Webpack的高级配置
1.Code Splitting(代码分割)
代码分割和webpack无关
1.webpack中实现代码分割的两种方式
- 同步代码:只需要在webpack.common.js中做optimizatio的配置访问
- 异步代码(import):异步代码,无需做任何操作,会自动进行代码分割,放置到新的文件中
打开src目录下创建的index.js
安装第三方包:npm install lodash --save
在index.js里引入
import _form "lodash"
console.log(_.join(['a', 'b', 'c'],*********))
第一个参数是字符串连接 第二个参数是连接符
打印结果为abc***********
假如改了我们的业务逻辑代码,用户需要重新加载main.js,才能获取到最新的代码,执行显示内容,意味代码一变更,用户就要重新加载2MB内容,
解决方案:
手动实现代码分割
-
在src目录下创建一个lodash.js文件
-
把index.js里的lodah的引入放到lodash文件里
-
import _form 'lodash'
-
window.=;
-
把lodash挂载到全局的window上,这样在控制台其他地方可以直接使用下划线变量了
-
index.js里直接写业务逻辑就可以
-
找到webpack.common.js文件进行配置
entry:{
lodash:'./src/lodash.js'
main:'./src/index.js'
}
-
打包会生成两个文件
-
一个是main.js 一个是lodash.js
-
index.html会同时引入main.js和lodash.js
-
当页面逻辑发生变化时,只要加载main.js即可,加快页面的加载速度
在webpack4里有一个插件:splitChunksPlugin,并且他直接与webpack做了捆绑,不需安装,直接配制使用
2.代码分割的两种解决方式
一、
配置同步代码,只需在webpack.common.js中做optimization的配置
entry:{
main:"./src/index.js"
}
webpack.common.js中
optimization:{
splitChunks:{
chunks:"all" //帮做代码分割
}
}
打包后生成了一个vendors~main.js文件和main.js文件在dist文件下, vendors ~main.js里面有lodash文件内容
二、
在index.js中异步加载lodash文件
function getComponent(){
//打包并不支持下面的这种语法
return import ('lodash').then(({default:_})=>{
var element = document.createElement('div')
element.innerHTML = _.join(['Dell','Lee'],'-')
return element
})
}
getComponent().then((element)=>{
docunment.body.appendChild(element)
})
这样会报错
安装:npm install babel-plugin-dunamic-import-webpack --save-dev
3.SplitChunksPlugin配置参数详解
optimization:{
splitChunks:{
chunks:"async", //在我们做代码分割时,只对异步代码有效,配置"all"会对同步异步一起做分割,"inital":对同步代码做分割
minSize:30000,///大于30000才进行代码分割,小于就不进行代码分割
maxSize:0,//可以配也可以不配
minChunks:1, //当一个模块被用了多少次,才进行代码分割
maxAsyncRequest:5,//同时加载的模块最多5个
maxInitialRequest:3, //入口文件引入的库,如果做代码分割,只能3个
automaticNameDelimiter:'~' //文件生成的时候,文件中间有~连接
name:true //打包生成的文件起什么名,cacheGroups里的名字让它有效
cacheGroups:{//当打包同步代码时,上面的参数有效
vendors:{//如果引入的文件大于30KB,
test:/[\/]node_modules[\/]/,//如果从node_modules引入的模块把它打包到vendors.js里
priority:-10, //-10优先级大,文件会被打包到wendors.js里
filename:"vendors.js"
},
default:{
priority:-20,
reuseExistingChunk:true,//如果一个模块已经被打包过了,那再打包会忽略这个模块,直接使用之前被打包的
filename:'common.js'//打包之后生成的文件名
}
}
}
}