文章目录
背景
前面介绍过,Webpack不单单只支持单页面项目(SPA),也支持多页面项目(MPA)的打包。那么在多页面项目开发过程中,每新增一个页面模块,都需要修改webpack.config.js配置文件(增加一个入口),这个时候我们就需要webpack帮我们自动扫描入口文件,完成多页面项目的打包,不用每次都需要修改webpack.config.js文件配置。
官方多入口配置
webpack默认是支持多入口配置的,如下:
module.exports = {
entry: {
app: './src/index.js',
search: './src/search.js'
}, //打包入口文件(如果是单个入口就是字符串,如果是多个入口就需要配置成对象)
output: { //打包输出文件
path: path.join(__dirname, 'dist'),
filename: '[name]_[chunkhash:8].js'
},
}
但是这种情况下就存在上面所说的问题,每次新增一个入口模块,都需要在entry中新增对应的入口配置。页面多的情况下维护困难。一般配置文件尽可能不要去随意改动。那么实际项目中,多页面打包应该如何做呢?
多项目打包步骤
entry实际上是一个map对象,结构如下{filename:filepath},那么我们可以根据文件名匹配,很容易构造自动扫描器:
npm 中有一个用于文件名匹配的 glob模块,通过glob很容易遍历出src目录下的所有js文件,我们可以通过指定规则,找到指定相匹配的入口文件,我们这里匹配src目录下所有的index.js作为入口(文件夹区分不同的模块,比如首页,src/index/index.js,搜索模块src/search/index.js,所有的入口以index.js命名):
-
安装glob模块
npm i -D glob
-
修改webpack.config.js 配置,新增entries函数,修改entry:entries(),修改output的filename为"[name].js"
'use strict'; const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); // const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); // const TerserPlugin = require("terser-webpack-plugin"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const autoprefixer = require('autoprefixer'); const HTMLInlineCSSWebpackPlugin = require("html-inline-css-webpack-plugin").default; const glob = require('glob'); //entries const entries = function () { const entry = {}; const htmlWebpackPlugin = []; let srcDir = path.resolve(__dirname, './src'); let entryFiles = glob.sync(srcDir + '/*/index.{js,jsx}') Object.keys(entryFiles).map((index) => { let filePath = entryFiles[index]; let match = filePath.match(/src\/(.*)\/index\.js/); const pageName = match && match[1]; entry[pageName] = filePath; htmlWebpackPlugin.push( new HtmlWebpackPlugin( { template: path.join(__dirname, `src/${pageName}/index.html`), filename: `${pageName}/index.html`, chunks: [pageName], inject: true } ) ) }) return {entry, htmlWebpackPlugin}; }; const {entry, htmlWebpackPlugin} = entries(); module.exports = { entry: entry, output: { path: path.join(__dirname, 'dist'), filename: '[name]_[chunkhash:8].js', }, ...... plugins: [ new MiniCssExtractPlugin({ filename: "[name].css", ignoreOrder: false, }), new HTMLInlineCSSWebpackPlugin(), ].concat(htmlWebpackPlugin), }
测试
新建如下目录结构(index和search是两个不同模块):