目錄結構javascript
├─build webpack配置目錄 │ ├─plugins.js │ ├─rules.js │ ├─transfromAssets.js //簡單的一個插件,處理路徑問題 │ └─webpack.config.js └─src ├─components ejs公用組件目錄 ├─css ├─js ├─index.ejs 模板文件 └─about.ejs
源碼地址:githubcss
index.ejs 須要向header.ejs傳入htmlWebpackPlugin,不然html-webpack-plugin配置的title可能會不起做用html
<%= require('./components/header.ejs')({path:'index',htmlWebpackPlugin}) %> <div id="root"> 內容 </div> <%= require('./components/footer.ejs')() %>
header.ejsjava
<head> <meta charset="utf-8"> <title><%= htmlWebpackPlugin.options.title %></title> </head>
webpack plugins,由於是多個頁面,因此經過for循環插入HtmlWebpackPluginnode
const HtmlWebpackPlugin = require('html-webpack-plugin'); const plugins = []; ... nav.forEach(value => { plugins.push( new HtmlWebpackPlugin({ filename: `${value.path}.html`, template: path.resolve(__dirname, '../src', `${value.path}.ejs`), inject: true, chunks: ['common', value.path], favicon: './src/assets/img/favicon.ico', title: 'title', minify: { collapseWhitespace: true } }) ) }) ...
安裝下babel-loader、@babel/core、@babel/preset-env,處理es6的語法。webpack
plugins.jsgit
const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const optimizeCss = require('optimize-css-assets-webpack-plugin'); const TransfromAssets = require('./transfromAssets'); const path = require('path'); const nav = require(`../src/data.js`).nav; const plugins = []; nav.forEach(value => { plugins.push( new HtmlWebpackPlugin({ filename: `${value.path}.html`, template: path.resolve(__dirname, '../src', `${value.path}.ejs`), inject: true, chunks: ['common', value.path], favicon: './src/assets/img/favicon.ico', title: 'title', minify: { collapseWhitespace: true } }) ) }) const otherPlugins = [ new MiniCssExtractPlugin({ filename: '[name].[hash:8].css', chunkFilename: '[id].css', }), new optimizeCss({ assetNameRegExp: /\.css$/g, cssProcessor: require('cssnano'), cssProcessorOptions: { discardComments: { removeAll: true } }, canPrint: true }), new TransfromAssets() ]; plugins.splice(nav.length, 0, ...otherPlugins); module.exports = plugins;
rules.jses6
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = [{ test: /\.(c|le)ss$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', { loader: "postcss-loader", options: { plugins: [ require("autoprefixer") ] } }, 'less-loader' ] }, { test: /\.js$/, //js文件加載器 exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } }, { test: /\.html$/, use: [{ loader: 'html-loader', options: { interpolate: true, minimize: false } }] }, { test: /\.ejs/, use: ['ejs-loader'], } ]
transfromAssets.js 一個插件,做用:github
function TransfromAssets(options) {};//也能夠是一個類 TransfromAssets.prototype.apply = function(compiler) { compiler.plugin('emit', function(compilation, callback) { for (var filename in compilation.assets) { if (/common.*js$/.test(filename)) { delete compilation.assets[filename]; continue; } if (/.*[js|css]$/.test(filename)) { let type = /.*js$/.test(filename) ? 'js' : 'css'; let source = compilation.assets[filename].source(); let size = compilation.assets[filename].size(); compilation.assets[`${type}/${filename}`] = { source: () => source, size: () => size } delete compilation.assets[filename]; } if (/html$/.test(filename)) { let source = compilation.assets[filename].source(); source = source.replace(/\<script.*?<\/script>/ig, value => ~value.indexOf('common') ? '' : value); source = source.replace(/href=\"\S+?.css\"/ig, value => value.slice(0, 6) + 'css/' + value.slice(6)); source = source.replace(/src=\".*?.js\"/ig, value => value.slice(0, 5) + 'js/' + value.slice(5)); compilation.assets[filename].source = () => source; } } callback(); }) }; module.exports = TransfromAssets;
webpack.config.jsweb
const path = require('path'); const plugins = require('./plugins'); const rules = require('./rules'); module.exports = { entry: { common: '@src/js/common.js', index: '@src/js/index.js', detail: '@src/js/list.js', }, output: { path: path.resolve(__dirname, '../dist/'), filename: "[name].[hash:8].js" }, devServer: { inline: true, historyApiFallback: true, }, resolve: { alias: { '@': path.join(__dirname, '..'), '@src': path.join(__dirname, '..', 'src') } }, module: { rules }, plugins }