>[success] # 多页面打包 ~~~ 1.当我们想使用多页面打包去构建项目的时候,最笨的方法就是去配置每个多页面的'HtmlWebpackPlugin', 这里有个思维我总是绕不过去,在这里记录一下,首先webpack 啥都不配置只能解析,'js' 和'json',打包后 生成的也是'js',他不会给你构建'html',想让他构建html 就需要用到'HtmlWebpackPlugin',在'webpack'里面 配置的'entry'识别的入口也是识别的js文件 2.entry将这个入口文件的项目依赖的文件打成'js',想让'HtmlWebpackPlugin'生成的html 和这些入口打包生成 的js匹配上,就需要设置'HtmlWebpackPlugin'里面的chunk然他们一致 ~~~ >[info] ## 多页面打包 ~~~ 说明:如图项目结构目录'HtmlWebpackPlugin' 需要指定作为html的模板,我们将目录结构一个文件夹存储 多页的html模板,打包的入口文件 1.初级开发程序员爱写的方式就是堆积代码。多页面写出的效果如下,有多少多页面就手动写多少个HtmlWebpackPlugin : const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode: 'production', entry: { index: './src/index/index.js', sreach: './src/sreach/index.js' }, output: { path: path.join(__dirname, 'dist'), filename: '[name].js' }, module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }] }, plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname, 'src/index/index.html'), // 使用模板 filename: 'index.html', // 打包后的文件名 chunks: ['index'], // 对应html模板想要引入对应打包入口打包后的js包,这里就需要和entry key一一对应 inject: true, // 默认注入所有静态资源 minify: { html5: true, collapsableWhitespace: true, preserveLineBreaks: false, minifyCSS: true, minifyJS: true, removeComments: false } }), new HtmlWebpackPlugin({ template: path.join(__dirname, 'src/sreach/index.html'), // 使用模板 filename: 'sreach.html', // 对应html模板想要引入对应打包入口打包后的js包,这里就需要和entry key一一对应 chunks: ['sreach'], // 打包后需要使用的chunk(文件) inject: true, // 默认注入所有静态资源 minify: { html5: true, collapsableWhitespace: true, preserveLineBreaks: false, minifyCSS: true, minifyJS: true, removeComments: false } }), ] } ~~~ * 项目结构目录 ![](https://img.kancloud.cn/d3/eb/d3ebcaea0e79a439a4b0684940443d28_242x375.png) >[danger] ##### 通过脚本的思维去写 ~~~ 1.首先利用'glob.sync' 可以获取文件目录 -- 'npm i glob -D' ~~~ ~~~ const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') /* 1.因为要配置打包入口,和'HtmlWebpackPlugin'要使用的html模板 因此创建两个变量'entry' 和'htmlWebpackPlugins' 负责生成, 我们需要的打包配置入口和'HtmlWebpackPlugin' 使用的html模板 */ const glob = require('glob') const setMPA = () => { const entry = {}; const htmlWebpackPlugins = []; const entryFiles = glob.sync(path.join(__dirname, './src/*/index.js')); Object.keys(entryFiles) .map((index) => { const entryFile = entryFiles[index]; // 获取入口打包文件的路径 // '/Users/cpselvis/my-project/src/index/index.js' const match = entryFile.match(/src\/(.*)\/index\.js/); // 通过正则取出entry到时候要使用的key const pageName = match && match[1]; // 小的细节没有下角标1的话做一个兼容判断 entry[pageName] = entryFile; htmlWebpackPlugins.push( new HtmlWebpackPlugin({ inlineSource: '.css$', template: path.join(__dirname, `src/${pageName}/index.html`), filename: `${pageName}.html`, chunks: ['vendors', pageName], inject: true, minify: { html5: true, collapseWhitespace: true, preserveLineBreaks: false, minifyCSS: true, minifyJS: true, removeComments: false } }) ); }); return { entry, htmlWebpackPlugins } } const { entry, htmlWebpackPlugins } = setMPA(); module.exports = { mode: 'production', entry, output: { path: path.join(__dirname, 'dist'), filename: '[name].js' }, module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }] }, plugins: [].concat(htmlWebpackPlugins) } ~~~ >[danger] ##### 公共文件处理 ~~~ 1.当我们在进行多页面打包时候,可能两个项目都用了同样的工具类,或者框架,本质上我们可以将 这些同样的内容打包成一份,引入到这些打包后的文件,这样不会因为公共方法会因为你多少个多页面 而成为对应倍数打包 ~~~ ~~~ module.exports = { ... optimization: { splitChunks: { // 自动提取所有公共模块到单独 bundle chunks: 'all' } }, ... } ~~~ >[danger] ##### 要读文章系列 [原文链接](https://segmentfault.com/a/1190000017393930) >[danger] ##### 问答 * 感叹一句大神写代码考虑的真多 摩拜 ~~~ 1.这里entryFiles直接用map,取第一个参数实测效果一样,用Objec.keys是有什么特别原因? 答:里主要是如果 entry是 hard code的写法的话,那么entry是一个 object,例如: entry: { index: './src/index/index.js', search: './src/search/index.js' } 那么,我们获取动态设置 html-webpack-plugin 是不是需要通过 Object.keys 去获取key,主要是基于这点去考虑的哈。 由于我们这里直接演示了最通用的方案,一步到位,其实完全用 map 匹配没问题的,直接用 map 匹配即可。 ~~~