Webpack
①Webpack是一个静态资源打包工具,从一个或多个文件作为打包入口entry
,输出一个或多个打包文件bundle
。
②Webpack只会打包有引用的资源文件。
搭建新项目
①进入项目路径,初始化package.json
文件,并安装Webpack依赖包。
npm init -y
npm i webpack webpack-cli -D
②在根目录创建webpack.config.js
文件,使用CommonJS对外暴露配置对象。
module.exports = {
entry: "./src/main.js",
output: {},
module: {
rules: [],
},
plugins: [],
mode: "development",
};
③打包命令在package.json
的scripts
中设置。
{
"scripts": {
"dev": webpack serve,
"build": webpack
}
}
mode
①mode
可选择三种模式:development
开发,production
生产,none
不使用任何默认优化选项。
②在开发环境下,可以借助devServer
搭建开发服务器进行调试,不会输出打包文件,在内存中进行编译打包。
③实现HMR热模块替换,需要loader
对源文件进行一定的处理,能够利用缓存。
module.exports = {
devServer: {
host: "localhost",
port: "3000",
open: true, // 自动打开浏览器
hot: true, // (默认)开启HMR热模块替换
},
// devtool: 'cheap-module-source-map', // 开发模式
// devtool: 'source-map', // 生产模式
}
entry
①打包程序的入口文件路径,一般使用相对路径。
module.exports = {
entry: {
name1: "./src/1.js",
name2: "./src/2.js",
},
};
output
①output
设置Webpack如何打包输出最终文件。
②path
设置打包输出根目录的绝对路径。
③clean
设置每次打包清空上一次的打包结果。
④assetModuleFilename
设置资源模块的输出路径和文件名。
⑤filename
设置JS文件bundle
的输出路径和文件名。
⑥chunkFilename
设置chunk
的输出路径和文件名。
module.exports = {
output: {
path: path.resolve(__dirname, "dist"),
clean: true,
filename: "js/[name].js",
assetModuleFilename: 'assets/[hash:5][ext][query]',
chunkFilename: "js/[name].chunk.js",
},
};
loader
①Webpack默认只能处理JS文件,打包编译额外的图片、样式等其他类型文件需要使用loader
。
②安装对应的loader
,并在module.rules
数组中,引入loader
设置规则。
③use
指定多个loader
,多个loader
在use
中按书写反顺序依次执行,支持链式调用。上一个loader
执行后的结果将会传递给下一个loader
。
④generator.filename
能够设置某类型文件统一的输出路径和文件名,优先级高于output.assetModuleFilename
。
⑤Webpack内置静态资源处理模块。asset/resource
将静态资源原样发送到输出目录,并注入路径到bundle
。asset/inline
将静态资源自定义编码为字符串形式,并注入到bundle
中。asset/source
将静态资源原样注入bundle
。asset
将小于指定大小的文件视为inline
,否则为resource
,以此可设置小图base64转换。
⑥include
和exclude
设置指定目录是否进行loader
处理,两者不能共同设置。
⑦rules.oneOf
设置每个文件只能被一个loader
配置项所匹配。
module.exports = {
module: {
rules: [
{
oneOf: [
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"] },
{ test: /\.less$/, use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"] },
{ test: /\.(tff|woff2?|mp3|mp4|avi)$/, type: 'asset/resource' },
{
test: /\.js$/,
exclude: /node_modules/,
use: [{ loader: "babel-loader", options: {} }],
},
],
},
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
type: 'asset',
parser: { dataUrlCondition: { maxSize: 4 * 1024 } },
generator: { filename: 'images/[hash:5][ext][query]' },
},
],
},
};
plugin
①
module.exports = {
plugins: [
],
}
Eslint配置
①VSCode中的Eslint插件是帮助显示语法错误,不影响编写代码。而Webpack中的Eslint是在打包编译的时候进行语法检查,出现语法错误会终止打包。
②Eslint配置文件可以写在package.json
的eslintConfig
中,也可以单独写在项目根目录的.eslintrc
或.eslintrc.js
或.eslintrc.json
文件中。Eslint忽略文件写在项目根目录的.eslintignore
中。
③rules
规则中0
表示off
,1
表示warn
,2
表示error
。
④extends
可以继承某些已经写好的Eslint规则。
module.exports = {
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
env: {
node: true, // 启用node中的全局变量
browser: true, // 启用浏览器中的全局变量
},
rules: {
"no-var": 2,
},
extends: [], // 继承
plugins: [],
}
Babel配置
①Babel配置文件可以写在package.json
的babel
中,也可以单独写在项目根目录的.babelrc
或babel.config.js
等文件中。
②presets
预设一组Babel的扩展功能。
③plugins
设置可扩展插件,优化Babel的功能。
module.exports = {
presets: [
"@babel/preset-env",
"@babel/preset-typescript",
"@babel/preset-react",
],
plugins: [
"@babel/plugin-transform-runtime",
],
}
性能优化
①某些支持多线程的plugin
或loader
,开启多线程能提高打包性能。
②Eslint和Babel可以开启缓存,提高二次编译性能。
③rules.oneOf
减少loader
与文件的匹配次数,可提高性能。
④Webpack默认在生产模式开启的Tree Shaking,他只支持ES Module,不支持CommonJS。
⑤静态图片资源、CSS文件、JS文件都可以通过plugin
或loader
进行压缩。
⑥preload
和prefetch
用于资源预加载并缓存,不执行,preload
优先级比prefetch
高。preload
常用于立刻加载本页面资源,并且需要as
设置优先级,最高为style
,其次为script
。prefetch
常用于在浏览器空闲时加载其他页面资源。
CodeSplit
①在optimization.splitChunks
中配置代码分割,生成多个chunk
。
②chunks
有三种模式:async
模式将import()
方式异步加载的模块单独打包。initial
模式可以通过其他配置项进行配置,但不能分离异步模块。all
模式兼容两者,推荐使用all
模式。
③cacheGroups
设置缓存组,将匹配路径下的所有模块一起打包到一个chunk
中,可单独设置配置项覆盖之前的配置。
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
minSize: 20000, // 超过20KB的模块,会被拆分成chunk
minRemainingSize: 0,
minChunks: 1, // 被引用1次及以上的模块,会被拆分成chunk
maxAsyncRequests: 30, // 按需加载时,最大的并行请求数
maxInitialRequests: 30, // 入口点的最大并行请求数
enforceSizeThreshold: 50000, // 超过50KB的模块一定会被单独打包
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
}
④import()
动态引入时,配合output.chunkFilename
可以设置chunk
的路径和文件名。
import(
/* webpackChunkName: "chunk" */
/* webpackPreload: true */
/* webpackPrefetch: true */
"./1.js"
)
.then(() => {})
.catch(() => {});