前言
最近闲着没事干,于是把webpack官网文档又又又刷了一遍,结合公司的项目,做一次多页面项目的优化。
多入口只是在entry配置多个入口,webpack是基于入口打包文件的,所以会去分别打包entry配置的每一个入口
多入口通常的配置如下:
const config = {
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}};常见多入口问题和优化
1.开发环境,打包了不需要的入口。
上图
这里还只是三个页面,如果是100个页面呢?后果很严重啊。那么,如何只打包我当前需要的入口呢?
最直接的方法是入口文件只写你需要的页面入口。比如我只需要pageOne的页面,那可以
entry: {
pageOne: './src/pageOne/index.js',
// pageTwo: './src/pageTwo/index.js',
// pageThree: './src/pageThree/index.js'
}但是这样的话,显得太麻烦了,如果可以通过命令解决这种问题就方便多了,比如
npm run dev --file=xxx通过带上 file=xxx 告诉webpack我想要打包哪个入口文件,如果不带上额外参数就全部打包,这样真是一举两得。
process.argv
process 对象是一个全局变量,它提供当前 Node.js 进程的有关信息,以及控制当前 Node.js 进程。 因为是全局变量,所以无需使用 require()。
process.argv 属性返回一个数组,这个数组包含了启动Node.js进程时的命令行参数,
其中: 数组的第一个元素process.argv[0]——返回启动Node.js进程的可执行文件所在的绝对路径 第二个元素process.argv[1]——为当前执行的JavaScript文件路径 剩余的元素为其他命令行参数
例如: 输入命令:node scripts/build.js "web-runtime-cjs,web-server-renderer"
结果:
console.log(process.argv[0]) // 打印 D:\nodeJs\node.exe
console.log(process.argv[1]) // 打印 E:\Study_document\vue-resource\vue-dev\scripts\build.js
console.log(process.argv[2]) // 打印 web-runtime-cjs,web-server-renderer
这样的话,我们就能通过process.argv来获取到我们命令行添加的额外参数
function getCmdParas (name) {
//process.argv 返回一个运行环境数组
for (let key in process.argv) {
if (process.argv[key].indexOf(`--${name}`) > -1) {
return process.argv[key].split('=')[1]
} }
return ''
}
const page = getCmdParas('page') || "**"const file = getCmdParas('file') || "**"
const pageUrl = `./src/${file}/main.js`glob
用上面的方法我们获取到了 pageUrl ,它可能是具体的某个文件的路径,比如
./src/pageOne/main.js也可能是一个匹配路径
./src/**/main.js
//表示匹配src下所有文件夹/main.js而glob方法可以对输入的路径做匹配,返回匹配到的文件路径数组。
glob.sync为异步获取
用法:
glob.sync(pageUrl) //['src/pageOne/main.js','src/pageTwo/main.js',.....]那么我们利用这个可以动态的设置入口
const chunks = []
const entries = {}
const htmlWebpackPluginArray = []
glob.sync(pageUrl).forEach(path => {
//path => ./src/pageOne/main.js
const chunk = path.split('./src/')[1].split('/main.js')[0]
// 得到每个文件的名字。 比如pageOne
entries[chunk] = path
chunks.push(chunk)
const filename = chunk + '.html' // pageOne.html
const htmlConf = {
filename: filename,
// template: path.replace(/.js/g, '.html'),
inject: 'body',
hash: true,
chunks: ['commons', chunk] }
//此处利用 HtmlWebpackPlugin插件,生成每个入口对应的html
htmlWebpackPluginArray.push(new HtmlWebpackPlugin(htmlConf))})//这个方法的作用其实就是 获取shell 命令中的参数
如输入 --page=xxxxxx,那么就可以获取到
page=xxxxxx参数,
function getCmdParas (name) {
//process.argv 返回一个运行环境数组
for (let key in process.argv) {
if (process.argv[key].indexOf(`--${name}`) > -1) {
return process.argv[key].split('=')[1]
} } return ''}
const page = getCmdParas('page') || "**"
const file = getCmdParas('file') || "**"
const pageUrl = `./src/${file}/main.js`
const entries = {}
const htmlWebpackPluginArray = []
glob.sync(pageUrl).forEach(path => {
//path => ./src/pageOne/main.js
const chunk = path.split('./src/')[1].split('/main.js')[0]
// 得到每个文件的名字。 比如pageOne entries[chunk] = path
})
module.export={
entry:entries
}
配置命令
最后一步就是配置你的命令
在package.json 的script中加入
"build": "npx webpack --config webpack.config.js --file=pageOne"pageOne你可以修改为你想要打包的文件夹名称
自此大功告成。