webpack 知识点整理
Posted 沿着路走到底
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack 知识点整理相关的知识,希望对你有一定的参考价值。
前端代码为何要进行构建和打包?
module、chunk、bundle 分别什么意思,有何区别?
module:各个源码文件,webpack中一切皆模块,只要是能引用的依赖,包括js、css、图片等都是模块。
chunk:多模块合并成的,如 entry、import()、splitChunk
bundle:最终的输出文件,一般是一个 chunk 对应 一个 bundle
loader 和 plugin 的区别?
webpack 如何实现懒加载?
webpack 常见性能优化
babel-runtime 和 babel-polyfill 的区别
基本配置
高级配置
优化打包效率
优化产出代码
构建流程概述
babel
webpack5
webpack5 主要是内部效率的优化
对比webpack4,没有太多使用上的改动
升级 webpack5 以及周边插件后,代码需要做出的调整:
- package.json 的 dev-server 命令改了 `"dev": "webpack serve --config build/webpack.dev.js",`
- 升级新版本 `const { merge } = require('webpack-merge')`
- 升级新版本 `const { CleanWebpackPlugin } = require('clean-webpack-plugin')`
- `module.rules` 中 `loader: ['xxx-loader']` 换成 `use: ['xxx-loader']`
- `filename: 'bundle.[contenthash:8].js'` 其中 `h` 小写,不能大写
webpack 基本配置
拆分配置 和 merge
启动本地服务
处理 ES6
处理样式
处理图片
模块化
webpack 高级配置
多入口
抽离 CSS 文件
抽离公共代码和第三方代码
懒加载
处理 JSX
处理 Vue
多入口
entry: {
index: path.join(srcPath, 'index.js'),
other: path.join(srcPath, 'other.js')
},
output: {
// filename: 'bundle.[contentHash:8].js', // 打包代码时,加上 hash 戳
filename: '[name].[contentHash:8].js', // name 即多入口时 entry 的 key
path: distPath,
// 修改所有静态文件 url 的前缀(如 cdn 域名),这里暂时用不到
// publicPath: 'http://cdn.abc.com'
},
plugins: [
// new htmlWebpackPlugin({
// template: path.join(srcPath, 'index.html'),
// filename: 'index.html'
// })
// 多入口 - 生成 index.html
new HtmlWebpackPlugin({
template: path.join(srcPath, 'index.html'),
filename: 'index.html',
// chunks 表示该页面要引用哪些 chunk (即上面的 index 和 other),
// 默认全部引用
chunks: ['index'] // 只引用 index.js
}),
// 多入口 - 生成 other.html
new HtmlWebpackPlugin({
template: path.join(srcPath, 'other.html'),
filename: 'other.html',
chunks: ['other'] // 只引用 other.js
})
]
抽离 CSS 文件
const path = require('path')
const webpack = require('webpack')
const { smart } = require('webpack-merge')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const webpackCommonConf = require('./webpack.common.js')
const { srcPath, distPath } = require('./paths')
module.exports = smart(webpackCommonConf, {
mode: 'production',
module: {
rules: [
// 抽离 css
{
test: /\\.css$/,
loader: [
MiniCssExtractPlugin.loader, // 注意,这里不再用 style-loader
'css-loader',
'postcss-loader'
]
},
// 抽离 less --> css
{
test: /\\.less$/,
loader: [
MiniCssExtractPlugin.loader, // 注意,这里不再用 style-loader
'css-loader',
'less-loader',
'postcss-loader'
]
}
]
},
plugins: [
new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹
new webpack.DefinePlugin({
// window.ENV = 'production'
ENV: JSON.stringify('production')
}),
// 抽离 css 文件
new MiniCssExtractPlugin({
filename: 'css/main.[contentHash:8].css'
})
],
optimization: {
// 压缩 css
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
}
})
抽离公共代码和第三方代码
optimization: {
// 分割代码块
splitChunks: {
chunks: 'all',
/**
* initial 入口 chunk,对于异步导入的文件不处理
async 异步 chunk,只对异步导入的文件处理
all 全部 chunk
*/
// 缓存分组
cacheGroups: {
// 第三方模块
vendor: {
name: 'vendor', // chunk 名称
priority: 1, // 权限更高,优先抽离,重要!!!
test: /node_modules/,
minSize: 0, // 大小限制
minChunks: 1 // 最少复用过几次
},
// 公共的模块
common: {
name: 'common', // chunk 名称
priority: 0, // 优先级
minSize: 0, // 公共模块的大小限制
minChunks: 2 // 公共模块最少复用过几次
}
}
}
}
懒加载
无需配置 webpack
// 引用动态数据 -- 懒加载
setTimeout(() => {
// 定义 chunk
import('./dynamic-data.js').then(res => {
console.log(res.default.message)
})
}, 1500)
处理 JSX
npm install --save-dev @babel/preset-react
.babelrc
{
"presets": ["@babel/preset-react"],
"plugins": []
}
处理 Vue
module: {
rules: [
{
test: /\\.vue$/,
loader: ['vue-loader'],
include: path.join(__dirname, '..', 'src')
},
]
},
webpack 性能优化
优化打包构建速度 - 开发体验和效率
优化产出代码 - 产品性能
webpack 性能优化 - 构建速度
优化 babel-loader
IgnorePlugin
noParse
happyPack
ParallelUglifyPlugin
自动刷新
热更新
DllPlugin
优化 babel-loader
{
test: /\\.js$/,
loader: ['babel-loader?cacheDirectory'], // 开启缓存
include: path.resolve(__dirname, 'src'), // 明确范围
// 排除范围,include 和 exclude 两者选一个即可
// exclude: path.resolve(__dirname, 'node_modules')
}
IgnorePlugin 避免引入无用模块
import moment from 'moment'
默认会引入所有语言 JS 代码,代码过大
如何只引入中文 ?
js
import moment from 'moment'
import 'moment/locale/zh-cn' // 手动引入中文语言包
moment.locale('zh-cn') // 设置语言为中文
console.log('locale', moment.locale())
console.log('date', moment().format('ll')) // 20xx年xx月xx日
webpack配置
plugins: [
// 忽略 moment 下的 /locale 目录
new webpack.IgnorePlugin(/\\.\\/locale/, /moment/),
],
noParse 避免重复打包
module: {
// react.min.js 文件就没有采用模块化
// 忽略对 react.min.js 文件的递归解析处理
noParse: [/react\\.min\\.js/],
}
IgnorePlugin vs noParse
IgnorePlugin 直接不引入,代码中没有
noParse 引入,但不打包
1
以上是关于webpack 知识点整理的主要内容,如果未能解决你的问题,请参考以下文章