完成多入口打包配置
上一节我说完了三个关键的plugin,通过三个plugin我们可以做到将代码进行分割,并且将分割的代码打包到我们指定的路径下,完成打包的模块可以被index.html文件正确引用。这里我们需要贯穿整个流程。
1、yargs
yargs 是一个非常强大的命令行参数处理工具,这里我们用到的功能比较简单,只需要获取从命令行传入的modules数组,这个数组表示所需打包的入口chunk。在vue-cli的默认安装包中并没有安装yargs这个模块,所以我们需要首先安装yargs模块。
// 通过npm安装yargs
npm install yargs -D
完成安装后,我们就能使用yargs进行命令行参数的获取,然后通过获取到的数组,按需打包我们需要的入口模块。例如:我们src下面有三个入口,分别为
moduleA
、moduleB
、moduleC
,但是本次我们发现moduleC
的代码没有发生变动,我们只需要在打包时传入moduleA
、moduleB
这两个参数就能做到。首先我们需要将参数从命令行传入到我们的运行脚本中。
2、命令行传入参数
2.1 scripts 的命令行参数
我们打包时运行的命令是
npm run build
,实际上我们执行的是package.json中的scripts中的脚本配置,vue-cli中默认的build配置是"build": "node build/build.js"
,也就是说通过npm run build
执行的是 build目录下的build.js文件。我们想要将参数传入到运行脚本中,就需要通过script脚本进行参数传递。
关于script脚本参数传递,这里贴一篇阮一峰老师的一篇博文供参考 npm scripts 使用指南,贴上我们需要的一段:
四、传参
向 npm 脚本传入参数,要使用--标明。
"lint": "jshint **.js"
向上面的npm run lint命令传入参数,必须写成下面这样。
$ npm run lint -- --reporter checkstyle > checkstyle.xml
也可以在package.json里面再封装一个命令。
"lint": "jshint **.js",
"lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"
也就是说在npm脚本中传入参数我们需要使用 -- --parameters
进行参数传递,我们在此使用的方式:npm run build -- --modules=moduleA moduleB
2.2 使用yargs的命令行参数传入
通过npm脚本我们已经可以将我们需要的modules参数传入到我们开始运行的build.js代码中了,接下来我们就要通过yargs来获取到modules参数所传入的值,这里的值是
moduleA、moduleB
,直接贴上我们获取参数的代码:
// utils.js文件
// 引入yargs模块
const yargs = require(\'yargs\')
/**
* 获取 命令行传入的参数
*/
const args = yargs.array(\'modules\').argv
// 这里如果没有传入modules参数则默认打包全部的模块
const modules = args.modules || [\'moduleA\', \'moduleB\', \'moduleC\']
// 我们将的到modules导出,以备其他模块使用
exports.bundleModules = modules
通过以上步骤我们就完成了参数的传递,可以通过命令行参数完成我们想要打包的模块。
3、入口处理
在vue-cli的默认入口中,是单入口应用的配置,所以我们需要修改为多入口的entry,根据webpack的文档,多入口配置采用的是对象的写法。我们在utils.js文件中通过方法生成entry,代码如下:
// utils.js
exports.entires = function () {
// 模块主目录
const BASE_PATH = path.resolve(__dirname, \'..\\\\src\\\\modules\')
// 最终的返回结果
let entriesMap = {}
// 得到所有模块的主入口
modules.forEach(item => {
entriesMap[item] = BASE_PATH + \'\\\\\' + item + \'\\\\main.js\'
})
// 最终横撑的entriesMap是一个对象,key为模块的名称,这个名称可以作为output中[name]占位符的值,也是很重要的
return entriesMap
}
这样我们就能通过modules得到我们需要打包的入口函数,接着我们将webpack.base.conf.js文件中的entry替换成我们生成的多入口形式,代码如下
// webpack.base.conf.js
module.exports = {
context: path.resolve(__dirname, \'../\'),
// 此处替换成我们自己的entry
entry: utils.entires(),
output: {
path: config.build.assetsRoot,
filename: \'[name].js\',
publicPath: process.env.NODE_ENV === \'production\'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
}
// ...
}
这样我们就处理好了入口处的webpack配置
4、出口处理
vue-cli生成的webpack配置中,通过npm run build命令进行的打包配置文件,出口配置在webpack.prod.conf.js文件中,在这里的output配置我们只需要修改打包生成的文件路径,代码如下:
// webpack.prod.conf.js
output: {
path: config.build.assetsRoot,
// 默认的配置,这里是将打包好的文件统一放在assets/js文件夹下面
// filename: utils.assetsPath(\'js/[name].[chunkhash].js\'),
// 修改后的配置,这里的[name]就是入口处的占位符,放到我们这里来说就分别是 moduleA|moduleB|moduleC,所以这里我们这么配置就是将不同的模块文件打包到各自的模块名称的js文件夹下
filename: path.posix.join(\'[name]/js\', \'[name].[chunkhash].js\'),
// 这里是异步模块,就是上一篇中说的async打包模块,这里的[name]占位符是vue-router中配置的异步路由名称
chunkFilename: utils.assetsPath(\'[name]/[id].[chunkhash].js\')
}
5、最终
完成了本篇中的所有配置之后,再将上一篇中三个插件的配置全部添加到webpack.prod.conf.js文件中,我们就能完成多入口模块的打包。我们需要清楚一点,执行
npm run build
和npm run dev
的区别。这两篇文章只是将build的代码实现了多入口的打包,我们并没有修改本地开发时的打包配置。下一篇文章我们会介绍一下前端多模块分布式发布时的打包配置,这个配置包含了本地开发环境的配置和build的配置。
完整版的代码仓库地址 multipleModules
最后贴一张最终打包完成的目录图