开发环境

优化打包构建速度
优化代码调试

生产环境

打包速度更快
优化代码运行的性能

优化开发环境打包

模块热替换:HMR :hot module replacement

把更改的部分替换,而不是刷新整个页面
1、在devServer中加入hot:true即可,开启HMR功能
2、从起webpack服务
3、

css文件可以使用这个hot来解决,因为style-loader支持

html文件在hot过后会不能够实时更新代码

需要在entry中加入一个新的入口[./src/index.js,./src/index.html],但即便如此也不能实现局部打包,这里html放弃热启动,因为html是唯一文件,所以不需要模块化热启动

js文件不支持hmr,需要想办法

1、在主入口把可能更新的文件进行处理,比如处理my.js,代码如下
if(module.hot){
module.hot.accept(‘./my.js’,function(){
//一旦使用了hmr模式,在更改my.js时就会调用my.js中的主函数
my();
})
}
注:这种方法对于入口文件没有意义,入口文件不需要做这个处理。

source-map

源代码到映射代码的文件,能让我们报错中找到源文件的错误点
使用方法:在webpack.config.js中加入devtool:’source-map’即可
参数概念。
devtool参数合集
[inline-|hidden-|eval][nosources-][cheap-[module]]source-map

source-map:外部生成,能找到错误代码信息和源代码错误位置
inline-source-map:内联,也能找到源代码错误位置
hidden-source-map:外部,只能提示到构建后代码的错误
eval-source-map:内联,每一个文件都生成对应的map,可以找到源代码错误位置
nosources-source-map:外部,能找到错误代码,不能找到错误代码位置
cheap-source-map:外部,能精确到错误代码的行
cheap-module-source-map:外部,module会将loader的source-map加入

开发环境

速度eval>inline>cheap>…
eval-cheap-souce-map最快
调试友好
source-map>cheap-module-source-map>cheap-source-map

最终选择:eval-source-map/eval-cheap-module-souce-map

生产环境

安全nosources-source-map>hidden-source-map
但最终选择是source-map/cheap-module-source-map

oneOf:

在rules下嵌套oneOf:[],把不同名字的匹配放到其中,提升构建速度,同名规则,只把其中一个放在oneOf中

js缓存//二次构建会先读取缓存(加快打包速度)

在test:/.js$/的options中,增加cacheDirectory:true//缓存目录开(babel缓存)

文件资源缓存

在js出口与css的publicPath或name变成build.[hash].js/css这样就可以让缓存不是同一个文件名,客户端再次请求时,缓存中的文件都没有用了。当然也存在问题,更改js文件css也会收到影响,造成了不必要的请求
chunkhash
如果打包来源于同一个chunk那么hash值时一样的,但问题是,css是从js中导出的,所以他们的chunk是一样的,哈希值也是一样的。
contenthash:(上线代码性能优化)根据文件的内容生成哈希值,不同的文件是不一样的
所以我们把[hash]改成[contenthash:10]就可以了

树摇tree shaking:去除无用代码

去除css或js
前提是1、必须使用ES6模块话
2、mode:production
以上在老版本中容易出现丢失文件,可以在package.json中配置”sideEffects”:[“.css”,”.less”]

代码分割 code split

方法1

多入口entry中加入多个js路径
在output中的filename改成:js/[name].[contenthash:10].js

方法2

在webpack.config.js中加入optimization:{
splitChunks:{
chunks:”all”
//把node_modules中的文件单独打包成一个chunk
//分析多入口chunk中,如果有公共文件,会打包成单独的一个chunk,不会重复打包
}
}

方法3

动态引入
import(/webpackChunkName:’test’,webpackPrefetch:true/‘.test’)可以.then或.catch去用
这里注释中的name是固定名字的
可以把文件单独打包
注:3个方法是一起用的!

懒加载与预加载

webpackPrefetch:true预加载/提前加载js文件,等问价把其他文件加载完毕了,浏览器空闲了,再偷偷加载资源。(兼容性不太好)

PWA渐进式网络开发应用程序(离线可访问)

workbox技术
1、下载workbox-webpack-plugin
2、在插件plugin直接new
new WorkboxWebpackPlugin.GenerateSW({
//1、帮助serveiceworker快速启动
//2、删除旧的serviceworker
//生成一个serviceworker配置
clientsClaim:true,
skipWaiting:true
})
3、入口文件中注册serviceworker
//需要处理兼容性问题,下面代码写在主入口中
if(‘serviceWorker’ in navigator){
window.addEventListener(‘load’,()={
navigator.serviceworker.register(‘/service-worker.js’)
.then(()=console.log(‘sw注册成功’))
.catch(()=console.log(‘sw注册失败’))
}
}
4、在package.json中eslintConfig中加入”env”:{
“browser”:true//支持浏览器全局变量,因为eslint本身是不认识window、navigator全局变量的。
“nodejs”:true//支持node中的环境变量
}

多进程打包

目的是加快打包,
1、下载npm i thread-loader -D
2、在处理js文件的babel-loader之后去使用thread-loader,options中可以设定worker:2,规定只有两个线程
3、js文件越大,他才能够有效用,不要乱用

忽略网络(cdn)链接引入包被打包

1、在webpack.config.js中加入
externals:{
jquery:”jQuery”//拒绝他的打包
}
2、需要在html中导入cdn script
3、不能打包本地第三方库

dll可以有选择的把多个插件合成一个chunk文件

1、新建webpack.dll.js文件
const {resolve}=require(‘path’);
const webpack=require(‘webpack’);
2、module.exports={
//一般是打包第三方的库
entry:{
//最终打包的生成name
jquery:[‘jquery’]
},
output:{
filename:’[name].js’,
path:resolve(dirname,’dll’),
library:’[name][hash:10]’,//打包的库里面向外暴露出去的内容叫什么,
},
plugins:[
//打包生成一个manifest.json —>提供与上面的文件映射关系,我就能知道上面的文件不需要打包
new webpack.DllPlugin({
name:”[name]
[hash]”,//映射库暴露的内容名称
path:resolve(
dirname,’dll/manifest.json’)//输出文件路径
})
],
mode:’production’
};
3、默认的配置文件并不是webpack.dll.js
输入webpack —config webpack.dll.js
4、在webpack.config.js中导入插件
const webpack=require(‘webpack’)
在Plugins:[]中告诉webpack哪些不参与打包
new webpack.DllReferencePlugin({
manifest:resolve(dirname,”dll/manifest.json”)
})
5、下载npm i add-asset-html-webpack-plugin -D
在webpack.config.js引入该插件
const AddAssetHtmlWebpackPlugin=require(“add-asset-html-webpack-plugin”);
6、在plugins中new
//将某个文件打包输出出去,并在html中自动引入该资源
new AddAssetHtmlWebpackPlugin({
filepath:resolve(
dirname,’dll/jquery.js’
})