本人萌新一枚,最近在做一个私人的多页面网站,本来用的是pug+sass+原生js的技术栈,忽然想试试能否沾一下webpack的优势,利用es6的语法。网上查了很多经验帖,最后总结出如下的方案。
首先备份一下pack.json
{
"name": "expressapp",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"build": "webpack"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1",
"mysql": "^2.17.1",
"node-sass": "^4.13.0",
"pug": "^2.0.0-beta11"
},
"devDependencies": {
"css-loader": "^3.2.1",
"ejs": "^3.0.1",
"glob": "^7.1.6",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"postcss-loader": "^3.0.0",
"pug-html-loader": "^1.1.5",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.1",
"url-loader": "^3.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
}
}
要注意以上依赖包中也有很多用于开发后端服务器的依赖,而前端用到的主要在 "devDependencies"中
之后是配置webpack.config.js
const path = require('path');
const glob = require('glob');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const HTMLReg = /\/([\w_]+)(?=.pug)/;
const JSReg = /\/([\w_]+)(?=.js)/;
const html = glob.sync('views/*.pug').map(path => {
let name = path.match(HTMLReg)[1];
return new HTMLWebpackPlugin({
template: path,
filename: name + '.html',
chunks: [name]
})
});
const entries = glob.sync('public/javascripts/*.js').reduce((prev, next) => {
let name = next.match(JSReg)[1];
prev[name] = './' + next;
return prev
}, {});
module.exports = {
entry: entries,
output: {
filename: 'js/[name].js',
path: path.resolve(__dirname, 'dist'),
},
module:{
rules: [
{
test: /\.pug$/,
use: ['html-loader','pug-html-loader']
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
...html
],
mode: "development"
};
path为常用的nodeJS内核模块,用于返回当前路径。
glob的作用是读取目标路径下的所有文件,并返回一个包含所有文件的路径的数组。HTMLWebpackPlugin是使webpack兼容多页面网站的关键, 这个插件可以用来单独打包HTML5文档,并各自引用对应的js文件。
const html = glob.sync('views/*.pug').map(path => {
let name = path.match(HTMLReg)[1];
return new HTMLWebpackPlugin({
template: path,
filename: name + '.html',
chunks: [name]
})
});
让各个js文档“各回各家”的关键在于设置chunks的name值为对应的js文件名。
至此,我们实现了利用webpack同时编译pug文件和js文件,并依然保持原有的文件格局,实现了多页面网站的打包。
但是该配置仍有不足之处,首先,css文件只能通过js文件引入才能被正常打包,这样最主要的问题在于:js文件往往要在页面加载完毕后再加载,此时引入css文件不仅要重新渲染界面,更重要的是,网页会在完整渲染之前先闪过一个未经过渲染的“丑陋无比”的界面。而且如果网速出问题,这个“丑八怪”甚至会持续的更久。就个人喜好而言,我宁愿多消耗几次请求也不能展示一个难看的界面。
其次,该方案尚不能打包图片,需要手动转移。