第一个问题:
上一篇中我,我们将整理好的webpack配置放进build文件夹中,进行npm run build
的时发现打包文件夹生成在build目录下,这当然不是我们想要的 ↓
我们的修改一下output输出配置中的path让其生成到根目录:
此时打包文件就生成在根目录下了,下次如果出现这个问题,只要知道打包文件默认是生成在同级的配置文件下的,如果需要生成到其他目录则重新配置一下路径,这个路径就是相对于webpack配置文件的路径
另一个问题:
此时如果我们在bundle打包的文件夹中新建一个文件,然后重新打包npm run build
,发现clean-webpack-plugin这个插件没有将我们新建的文件进行清理,这是我们得重新修正一下我们的CleanWebpackPlugin中的配置(这里可以去github上搜一下clean-webpack-plugin这个插件,里面有对这个的处理方法,这里直接写):
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new CleanWebpackPlugin(['bundle'],{
root: path.resolve(__dirname,'../')
})
],
大概配置的意思就是修改clean-webpack-plugin这个插件从哪个根路径去清理,默认clean-webpack-plugin是在webpack配置同级路劲中去查找指定的打包文件,此时我们在第一个问题中就已经修改了output输出位置,所以root就要调至根路径即可,此时运行npm run build
就发现新增的文件已经清理
++++++++++++++++++++++clean-webpack-plugin 3.0.0升级变动+++++++++++++++++++++++++++
升级之后,此时clean-webpack-plugin插件没有了root属性,并且导入的方式也变了,需要解构赋值的方式进行导入,我们这里要重新更换一下CleanWebpackPlugin的配置,否则会报错(最新的更改同样可以去github查):
const {CleanWebpackPlugin} = require('clean-webpack-plugin'); // +- 更新
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new CleanWebpackPlugin() // +- 更新
],
此时运行npm run build
同样可以清理新增的文件,over~(前面的我直接在涉及这部分的代码进行更新提醒即可)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
卖关子:
解决完前面两个问题,我们就开始进入Code Splitting代码分割,那么这个到底是什么呢?有什么用?不急依照惯例讲解概念前我们都是卖关子的,写代码看结果得结论~
开始:
我们继续下面的步骤前,配置一个新的script指令 → 主要实现打包后生产未压缩的main.js,方便之后的讲解
"scripts": {
"dev": "webpack-dev-server --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js",
"start": "webpack --config ./build/webpack.dev.js" // + 新增
}
其次我们在index.js的代码清空,并且删除math.js,并且结合lodash讲解,那我们的安装一下这个万能小工具包lodash npm install lodash --save
,安装完成之后我们写代码:
import _ from 'lodash'
console.log(_.join(['a','b','c'],'-'))
然后重新打包执行新指令 npm run start
,然后控制台输出的是一个以横杠连接的abc字母,此时我们看打包文件main.js会发现打包也会将lodash这种第三方插件打包进去
假设:
此时lodash大小为(1Mb),在index.js实现的逻辑代码大小也为(1Mb),那我们打包文件就是(2Mb),此时我们打开浏览器加载时,就要请求加载2Mb的文件;此时我们更改index.js
里的逻辑,重新打包时,浏览器依然得重新请求加载(2Mb)的文件,我们发现是不是有点不符合情理,我们只是修改了逻辑代码,而第三方库没有修改或者更新,但每次加载是都要去加载它,有点浪费加载资源
那我们想不如将他们分割开来,也就是第三方Loadsh插件库和我们的逻辑代码写成两个文件,如下在src目录新建lodash.js:
import _ from 'lodash'
window._ = _;
增加打包文件入口:
entry: {
"main": './src/index.js',
"lodash": './src/lodash.js'
},
此时我们再次运行打包命令npm run start
成功后,发现打包文件夹bundle里多出了一个lodash.js的打包文件,而main.js里没有lodash相关的打包代码了,说明我们成功分割了这两个代码,并且在index.html中可以看出 ↓
所以此时去页面加载时,此时按照浏览器的多并发请求,也就是其实加载一个2Mb的文件会比加载两个1Mb文件要慢一点的,此时如果修改了index.js的逻辑代码,会发现浏览器只加载main.js打包文件,而lodash.js的打包文件不再加载,因为浏览器发现lodash.js的代码并没有变,所以直接使用缓存,通过这个代码分割,是不是感觉在加载速度上比第一种要快,高效的利用了加载资源性能以及提高了用户体验~
前言:
在没有webpack之前我们也是可以使用这种方法使用优化加载性能,如今webpack的兴起,只要说起代码分割估计都会想到webpack吧,但其实Code Splitting和webpack并没有直接关系,只是后面webpack把他通过配置放入底层,现在我们只需要通过webpack特有的配置进行智能化的实现Code Splitting代码分割的功能,下面我们来实现一下 ↓
整理代码:
此时我们可以删除lodash.js
,并且相应的去掉入口配置,同时恢复index.js
中lodash的导入,然后回到webpack.common.js
中配置optimization:
optimization:{
splitChunks: {
chunks: 'all'
}
}
重新运行后,bundle文件夹中会对出一个vendors~main.js
,它里面就是lodash引入的库
上面就是webpack中通过配置只能的完成了代码分割功能,重新运行打包一样可以输出对应逻辑,此时我们回到index.js,它里面都是同步的逻辑,而Code Splitting代码分割处理同步代码和异步代码又有一定的区别 ↓
Code Splitting代码分割处理异步代码:
// 同步代码输出
// import _ from 'lodash';
// console.log(_.join(['a','b','c'],'-'));
// 异步代码输出(模仿webpack官网上的方法)
function getComponent(){
return import('lodash').then(({ default: _ }) => {
var dom = document.createElement('div');
dom.innerHTML = _.join(['Copy','Splitting'],' ');
return dom;
})
}
getComponent().then(dom => {
document.body.appendChild(dom);
})
简述逻辑:
创建一个方法getComponent → 当成功引入lodash后 → 其返回值为_ → 然后执行回调then中的逻辑 → 并且返回一个dom元素 → 之后执行调用该方法同样也等getComponent()方法执行完后拿到其返回值 → 作为then回调的参数 → 最后执行回调中的逻辑将dom节点添加到页面中
完成:
此时我们重新打包npm run start
,发现命令行中报错了 ↓
新版的webpack4一开始并不支持这种异步方式的回调导入,所以报了一个dynamicImport
的错误,解决的办法就是借助babel的一个插件npm install babel-plugin-dynamic-import-webpack -D
,安装好之后我们可以在 .babelrc
进行配配置:
{
"presets":[
["@babel/preset-env", {
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1",
},
"useBuiltIns": "usage"
}
],
"@babel/preset-react"
],
"plugins": ["dynamic-import-webpack"] // + 新增
}
+++++++++++++++++++++++webpack4.3x.0升级改动++++++++++++++++++++++++
webpack4.3x.0借助babelv7.5.0之后不会报这个错误了,他已经可以识别这种异步导入的方法,所以不会报dynamicImport
的错误了, 此时我们可以在.babelrc
中去掉
"plugins": ["dynamic-import-webpack"]
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
重新打包发现已经解决啦,然后bundle打包文件夹中,内容跟上次差不多,也是可以实现代码分割的:
此时我们去掉webpack.common.js
里的optimization这个配置,重新打包一样也可以,页面也会输出Copy Spitting
区别总结:
同步中Code Splitting代码分割 → 使用同步导入第三方插件的方式import xxx from './xxx'
,同时配置optimization
异步中Code Splitting代码分割 → 使用异步导入第三方插件的方式,处理一下异步导入的语法编译即可,不需要配置optimization
从上面关于Code Splitting代码分割其实很少,我们就是用了splitChunks这个配置项,但里面还有很多配置项还没有说,下一篇我们就来借助文档分析一下这里的配置参数的意思吧~
#下一篇【SplitChunksPlugin配置参数详解~】