当我们遇到多入口项目时,如果不抽离代码块,一些公用的代码就会被加载两次,造成资源损耗。
本节介绍如何实现多入口打包配置,以及如何抽离公有代码块。
01 多入口打包
准备:
准备两个入口文件(或更多)
- aaa.js
- bbb.js
aaa.js
console.log("aaa.js")
bbb.js
console.log("bbb.js")
webpack配置:
原来单入口配置是这样的:
module.exports = {
mode: "production",//模式,两种模式,产线模式"production"、开发模式"development"。产线模式会把编译文件进行压缩优化,代码变成一行。
entry: "./src/aaa.js",//入口,相对路径
output: {
filename: "bundle.[hash:8].js",//打包后的文件名
path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
},
}
修改entry
和output
的filename
字段。
[name]
是指:获取entry
里面的key值,这里是作为文件名。
修改后如下:
module.exports = {
mode: "production",//模式,两种模式,产线模式"production"、开发模式"development"。产线模式会把编译文件进行压缩优化,代码变成一行。
entry: {
aaa:'./src/aaa.js',
bbb:'./src/bbb.js'
},
output: {
filename: "[name].js",//打包后的文件名
path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
},
}
打包:
npx webpack
发现输出目录(这里是./dist
)下生成了aaa.js
和bbb.js
两个输出文件。
这就实现多入口打包。
02 公用代码块抽离
准备:
我们在多入口打包的基础上,新增两个文件。
- common1.js
- common2.js
common1.js
console.log("common1 呀~~~~~")
common2.js
console.log("common1 呀~~~~~")
分别在aaa.js和bbb.js中引入:
aaa.js
import common1 from "./common1"
import common2 from "./common2"
console.log("aaa.js")
bbb.js
import common1 from "./common1"
import common2 from "./common2"
console.log("bbb.js")
此时运行打包npx webpack
会发现
{var n={906:function(){console.log("common1 呀~~~~~")},385:function(){console.log("common2 呀~~~~~")}}
这段代码再两个入口文件中都出现了。
这就证明了,common1.js
和common2.js
被打包了两次。
webpack 配置
在webpack中添加如下配置:
module.exports = {
optimization:{//优化配置项
splitChunks:{//分割代码块
cacheGroups:{//缓存组
common:{//缓存公用模块
chunks:'initial',//从入口文件抽离
minSize:0,//只要大于0字节就抽离
minChunks:2,//只要使用2次以上就抽离
}
}
}
},
}
运行npx webpack
打包。
你会发现, 除了两个入口文件以外,多了一个文件。
这个多出来的文件里,存储了common1.js
和common2.js
两个文件的代码内容。
./dist/383.js
(self.webpackChunkmm_webpack=self.webpackChunkmm_webpack||[]).push([[383],{906:function(){console.log("common1 呀~~~~~")},385:function(){console.log("common2 呀~~~~~")}}]);
然后aaa.js
和bbb.js
文件分别引用这个文件。
./dist/aaa.js
var n={246:function(n,r,t){t(906),t(385),console.log("aaa.js")}},
./dist/bbb.js
var n={709:function(n,r,t){t(906),t(385),console.log("bbb.js")}},
至此,公用代码抽离就实现了。
03 抽离第三方模块
有时候我们不仅仅需要抽离自己写的公用代码,还需要抽离node_modules
文件夹下的第三方模块代码。
一般第三方代码比较多,抽离重复使用的代码,能大大减少包体积。
准备:
这里用一个测试文件来代替存在node_modules
文件夹下的第三方模块代码。
- ./node_modules/test.js
console.log("test.js ~~~")
修改我们原有的入口文件。
- ./src/aaa.js
import common1 from "./common1"
import common2 from "./common2"
import test from "test"
console.log(test)
console.log("aaa.js")
- ./src/bbb.js
import common1 from "./common1"
import common2 from "./common2"
import test from "test"
console.log(test)
console.log("bbb.js")
aaa.js
和bbb.js
分别引入了test.js
,这就模拟了代码中多页面使用同一个第三方库的情况。
接下来编写webpack配置:
module.exports = {
optimization:{//优化配置项
splitChunks:{//分割代码块
cacheGroups:{//缓存组
common:{//缓存公用模块
chunks:'initial',//从入口文件抽离
minSize:0,//只要大于0字节就抽离
minChunks:2,//只要使用2次以上就抽离
},
vendor: {
test: /node_modules/,//把node_modules文件夹下的公用引用抽离出来
chunks: 'initial',//从入口文件抽离
minSize: 0,//只要大于0字节就抽离
minChunks: 2,//只要使用2次以上就抽离
}
}
}
},
}
运行npx webpack
打包
会发现抽离出来的test.js
的代码与之前的公用代码合并到一个文件里了。
(self.webpackChunkmm_webpack=self.webpackChunkmm_webpack||[]).push([[854],{507:function(){console.log("test.js ~~~")},906:function(){console.log("common1 呀~~~~~")},385:function(){console.log("common2 呀~~~~~")}}]);
其实这是一个错误,你会发现webpack里不添加vendor
配置也是生成这样的结果。
这说明vendor
配置并没有生效。
原因是:
webpack的optimization
执行顺序是从上到下,先执行到的common
配置,并且满足条件,就不会执行下面的vendor
配置了。
所以我们需要给vendor
配置添加一个priority
参数,告诉webpack它需要优先执行。
修改webpack配置:
module.exports = {
optimization:{//优化配置项
splitChunks:{//分割代码块
cacheGroups:{//缓存组
common:{//缓存公用模块
chunks:'initial',//从入口文件抽离
minSize:0,//只要大于0字节就抽离
minChunks:2,//只要使用2次以上就抽离
},
vendor: {
priority: 1,//优先级提高,先执行vendor,再执行其他
test: /node_modules/,//把node_modules文件夹下的公用引用抽离出来
chunks: 'initial',//从入口文件抽离
minSize: 0,//只要大于0字节就抽离
minChunks: 2,//只要使用2次以上就抽离
}
}
}
},
}
再运行npx webpack
你会发现多了一个输出文件。
这次,./node_modules/test.js
文件与其他公用代码的抽离分成了两个文件,内容分别是:
(self.webpackChunkmm_webpack=self.webpackChunkmm_webpack||[]).push([[507],{507:function(){console.log("test.js ~~~")}}]);
(self.webpackChunkmm_webpack=self.webpackChunkmm_webpack||[]).push([[383],{906:function(){console.log("common1 呀~~~~~")},385:function(){console.log("common2 呀~~~~~")}}]);
至此,第三方模块代码的抽离就完成了。
如有疑问,欢迎留言交流。
END
暂无评论