vue+webpack4多页面打包配置
vue+webpack4多页面打包配置
多页面配置通常有两种形式,一种是多页面多配置,一种是多页面单配置。因为webpack(3.1以上)可以直接处理一个配置对象的数组,所以可以为每个页面单独写一份配置。
通常来讲,多配置的优点是配置灵活、独立,可以并行打包,从而提高打包速度,缺点是不能在多页面之间共享代码(一个页面加载了之后,下一个页面还得再加载一遍);单配置的特点基本上是和多配置相对。具体使用哪一种形式,看具体业务情况。本文主要介绍的是单配置的形式。
1. 整体目录结构
为了便于打包,我们创建一个pages的文件夹,在其下创建一个个的子文件夹代表一个个页面,每个子文件夹中建立各自的spa应用体系,如图所示:
这样做的好处是,我们在配置webpack的打包入口时,比较好操作,而且这样的结构也较为清晰。
2. webpack配置
2.1 文件结构
创建base、dev、prod三个文件。我们在base文件中配置entry、output、loader、公共的plugin等,其余的根据开发环境和线上环境各自所需在各自不同的文件中增删改。
2.2 entry
根据整体目录结构,每个页面文件夹都有各自的入口js文件,我们在配置entry选项时,就可以按如下编码方式书写:
/** * 通过约定,降低编码复杂度 * 每新增一个入口,即在src/pages目录下新增一个文件夹,以页面名称命名,内置一个index.js作为入口文件 * 通过node的文件api扫描pages目录 * 这样可以得到一个形如{page1: "入口文件地址", page2: "入口文件地址", ...}的对象 */ const getEntries = () => { let result = fs.readdirSync(pagesDirPath); let entry = {}; result.forEach(item => { entry[item] = path.resolve(__dirname, `../src/pages/${item}/index.js`); }); return entry; } module.exports = { entry: getEntries() ... }
2.3 output
output的配置选项如下,打完包后的目录结构如图所示:
//判断是否是开发环境 const devMode = process.env.NODE_ENV === "development"; module.exports = { ... output: { publicPath: devMode ? "" : "/", //这里的name即为我们entry对象中的每一个key值,也就是我们在pages目录下创建的一个个文件夹的名称 filename: devMode ? "[name].js" : "static/js/[name].[chunkhash].js", path: path.resolve(__dirname, "../dist") } ... }
2.4 html-webpack-plugin
配置完了entry和output,接下来需要为每个页面生成一个单独的html文件,也就是为每个页面创建一个html-webpack-plugin的实例:
/** * 扫描pages文件夹,为每个页面生成一个插件实例对象 */ const generatorHtmlWebpackPlugins = () => { let arr = []; let result = fs.readdirSync(pagesDirPath); result.forEach(item => { //判断页面目录下有无自己的index.html let templatePath; let selfTemplatePath = pagesDirPath + `/${item}/index.html`; let publicTemplatePath = path.resolve(__dirname, "../src/public/index.html"); try { fs.accessSync(selfTemplatePath); templatePath = selfTemplatePath; } catch(err) { templatePath = publicTemplatePath; } arr.push(new HtmlWebpackPlugin({ template: templatePath, filename: `${item}.html`, chunks: ["manifest", "vendor", item] })); }); return arr; } module.exports = { ... plugins: [ ...generatorHtmlWebpackPlugins() ] ... }
这里为了灵活性考虑,判断了各自的页面子文件夹中有无html模板文件;如果不需要,可以把templat路径直接定义成公共html文件的地址。
2.5 其他配置
基本上前面的几点配置就是一个多页面打包配置的雏形。此外还可以配置下诸如optimization、mini-css-extract-plugin等生产环境打包的优化配置。在文末的github地址中可以看到全部的配置信息。
3. 多页面+SPA
虽然我们这是一个多页面的应用,但每个页面也可以做成一个spa,如果你有这种需求的话;此外可以配置@babel/plugin-syntax-dynamic-import插件以支持import(),在router层面做代码分割和懒加载。