webpack入门到精通
教学视频地址: 尚硅谷2020最新版Webpack5实战教程
项目github地址: webpack入门到精通
环境参数(本机)
Nodejs v13.8.0
webpack 4.43.0
webpack简介
weback是什么
- 前端资源构建工具
- 静态模块打包器(module bundler)
webpack五个核心概念
名称 | 描述 |
---|---|
Entry | 入口 |
Output | 出口 |
Loader | 转换 |
Plugins | 插件 |
Mode | 模式 |
webpack初体验
安装
1 | npm i webpack webpack-cli -D |
使用
1 | 开发模式 |
未配置前,只能处理js/json文件,不能处理css/img等其他资源
配置模板
1 | // file:webpack.config.js webpack的配置文件 |
打包样式资源
安装
1 | npm i style-loader css-loader -D |
配置
1 | // file:webpack.config.js |
运行
1 | webpack |
打包html资源
安装
1 | npm i html-webpack-plugin -D |
引入
1 | // file:webpack.config.js |
使用
1 | // file:webpack.config.js |
打包图片资源
安装
1 | npm i url-loader file-loader html-loader -D |
配置
1 | // file:webpack.config.js |
打包其他资源
file-loader 前面已经安装
配置
1 | // file:webpack.config.js |
devServer
作用
开发服务器,自动编译,自动刷新,自动打开浏览器
只会在内存中编译打包,不会有任何输出
安装
1 | npm i webpack-dev-server -D |
配置
1 | devServer: { |
使用
1 | npx webpack-dev-server |
提取css成单独文件
安装
1 | npm i mini-css-extract-plugin -D |
引入
1 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') |
配置
1 | // 1.修改plugins |
css的兼容性处理
安装
1 | npm i postcss-loader postcss-preset-env |
配置
1 | // 修改loader,即module中的rules |
压缩css
安装
1 | npm i optimize-css-assets-webpack-plugin -D |
引入
1 | const OptimizeCssAssetsWebpackPlugin= require('optimize-css-assets-webpack-plugin') |
配置
1 | // 修改plugins |
js语法检查
注:老师采用的是aribnb,不过我采用的代码风格是js- standard-style
安装
1 | npm i eslint-loader eslint -D |
1 | npm install eslint-config-standard eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node -D |
配置
1 | // file: package.json |
1 | // 增加loader,即module中的rules |
js兼容性处理
兼容处理有三种
@babel/preset-env 基本js兼容处理
问题:只能转换基本语法,如promise不能转换@babel/polyfill 全部兼容处理
问题:将所有兼容处理,体积太大
core-js 按需加载
安装
1 | npm i babel-loader @babel/core @babel/preset-env -D |
1 | npm i @babel/polyfill -D |
1 | npm i core-js -D |
配置
1 | // 第一种 增加loader,即module中的rules |
1 | // 第二 直接在js文件中增加 |
1 | // 第三种 增加loader,即module中的rules |
js压缩
1 | // file: webpack.config.js 切换成生产模式 |
html压缩
1 | // file: webpack.config.js 添加之前插件的minify属性 |
HMR
HMR: hot module replacement 热模块替换,一个文件修改后,只重新构建该文件,而不是全部构建
开启热功能
1 | // file: webpack.config.js |
样式文件:默认有HMR功能
js文件:默认无HMR功能
1
2
3
4
5// file:./src/jsindex.js 入口js文件下方添加
if (module.hot) {
module.hot.accept('./print.js', function () {
})
}html文件:默认无HMR功能,而且会导致无法热更新
1
2// file: webpack.config.js
entry: ['./src/js/index.js', './src/index.html']
source-map
找到源代码的错误信息和错误位置
使用
1 | // file: webpack.config.js |
参数
[inline-|hidden-eval-][nosourses-][cheap-[module-]]source-map
属性 | 存放位置 | 错误原因 | 错误位置 |
---|---|---|---|
source-map | 外部 | 源文件 | 源文件 |
inline-source-map | 内联 | 源文件 | 源文件 |
eval-source-map | 内联 | 源文件(+hash) | 源文件 |
hidden-source-map | 外部 | 构建文件 | 构建文件 |
nosources-source-map | 外部 | 源文件 | 无 |
cheap-source-map | 外部 | 源文件 | 源文件(1行) |
cheap-module-source-map | 外部 | 源文件 | 源文件(1行) |
开发环境推荐:eval-source-map
生产环境推荐:source-map / cheap-source-map / hidden-source-map
oneOf
只匹配一个loader,不用全部都匹配,优化打包构建速度
1 | rules: [ |
缓存
babel缓存(第二次打包构建速度更快)
1
2
3
4
5
6
7
8
9
10// 修改js-loader中的options
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 开启babel缓存,第二次构建时读取缓存
cacheDirectory: true
}
}
1 |
|
tree-shaking
去除无用代码,前提:使用es6模块化,开启production环境
默认已经开启了,不过可能会去除css等其他文件
1 | "sideEffects": ["*.css", "*.less"] |
代码分割
多入口
1
2
3
4
5entry: {
// 多入口
index: './src/js/index.js',
test: './src/js/test.js'
}optimization
1
2
3
4
5
6
7
8// file: webpack.config.js
// 1.将node_modules中的代码单独打包一个chunk输出
// 2.自动提取多入口chunk 的公共文件
optimization: {
splitChunks: {
chunks: 'all'
}
}import动态导入,能将某文件单独打包
1
2
3
4
5
6
7
8// file: ./src/index.js
import(/* webpackChunkName: 'test' */'./test')
.then(({ mul, sub }) => {
console.log(mul(2, 3))
})
.catch(() => {
console.log('加载失败')
})
lazy loading
懒加载:文件需要使用时才加载
预加载: 会在使用之前空闲时提前加载js
1 | // file: ./src/js/index.js |
PWA
渐进式网络开发应用程序(离线可访问)
安装
1 | npm i workbox-webpack-plugin -D |
引入
1 | const WorkboxWebpackPlugin = require('workbox-webpack-plugin') |
配置
1 | // file: webpack.config.js |
使用
1 | // file: ./src/js/index.js |
服务器搭建(serviceWorker只能在服务器中使用)
1 | 安装全局serve |
多进程打包
只有工作消耗时间比较长,才需要多进程打包
安装
1 | npm i thread-loader -D |
配置
1 | // file: webpack.config.js ->添加loader |
externals
忽略文件的打包
配置
1 | // file: webpack.config.js |
重新引入
1 | <!-- file: index.html --> |
DLL
动态连接库,将库打包单独打包
安装
1 | npm i add-asset-html-webpack-plugin -D |
新建dll配置文件
1 | // file: webpack.dll.js |
引入
1 | // file: webpack.config.js |
配置
1 | // file: webpack.config.js |
运行
1 | 先生成单独打包的文件 |
优化性能总结
开发环境性能优化
- 优化打包构建速度
- HMR
- 优化代码调试
- source-map
生产环境性能优化
- 优化打包构建速度
- oneOf
- babel缓存
- 多进程打包
- externals 忽略打包
- dll 单独打包
- 优化代码运行的性能
- 缓存(hash-chunkhash-contenthash)
- tree shaking 树摇,去除无用
- code split 代码分割
- 懒加载/预加载
- pwa 离线访问
entry
入口起点
string
'./src/index.js'
- 打包形成一个chunk ,输出一个bundle文件
- 此时chunk的名称模式是main
array
['./src/index.js', './src/add.js']
- 多入口
- 所有入口文件最终形成一个chunk ,输出一个bundle文件
- 作用只有在HMR功能中让html热更新生效
object
{index: './src/index.js',add: './src/add.js'}
- 多入口
- 有几个入口就有几个chunk,输出几个bundle文件
- chunk的名称是key
特殊用法(复用性)
1
2
3
4{
index: ['./src/index.js', './src/add.js'],
count: './src/count.js'
}
output
1 | output: { |
module
1 | module: { |
resolve
1 | resolve: { |
optimization
1 | optimization: { |