1.常见概念
entry:指定 webpack 应用程序或类库打包的入口。
output:指定 webpack 将所创建的 bundle输出到哪儿,以及如何命名这些文件。
- filename: 指定输出bundle的名称,支持使用变量([name])解决多入口、代码拆分以及插件等创建多个bundle的问题
- path: 指定输出磁盘目录,必须是绝对目录,可以通过__dirname或者node中path模块创建
loaders:指定 webpack 如何将不支持的文件类型转变成可支持的模块,用于对模块的源代码进行转换(默认支持 js以及json两种文件类型)
在module中的rules里定义规则:
- test 属性:用于标识那些文件需要被对应的 loader 进行转换。
- use 属性:表示进行转换时,应该使用哪个 loader
plugins:指定 webpack 如何对 bundle以及chunk的处理(优化、处理)
mode:启用webpack在相应环境下的内置优化。 development | production | none
resolve :配置模块如何解析。
- alias: 创建 import 或 require 的别名.可以用来改变解析(引用)文件。
2.配置一个支持react+scss+ts的项目
webpack.config.js如下:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: "./src/index.ts",
mode: "development",
module: {
rules: [
{
test: /\.(ts|tsx)$/,
exclude: [/node_modules/],
loader: "babel-loader",
options: {
presets: [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript",
],
},
},
/*
{
test: /\.(ts|tsx)$/,
use: 'ts-loader',
exclude: /node_modules/,
},*/
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.html$/,
loader: "html-loader",
},
],
},
resolve: { extensions: [".ts", ".tsx",'.js'] },
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "/dist/",
filename: "bundle.js",
},
devServer: {
contentBase: "./dist",
compress: true,
port: 8080,
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./src/index.html"),
filename: "index.html",
}),
new CleanWebpackPlugin()
],
};
3.常见webpack打包优化方案
项目打包过程,可以分为几个部分:
- 搜索所有的依赖项
- 解析所有的依赖模块。
- 将所有的依赖模块压缩打包到一个文件。
可以从这三个方面分别考虑打包优化。
1.搜索时间优化。
缩小文件搜索范围 ,减小不必要的编译工作
通过优化loader,以及reslove(module、alias、extensions、mainfileds、noparse)配置。
2.解析时间优化。
通过多进程打包优化解析时间。
tthread-loader。(只要把 thread-loader 放置在其他 loader 之前, 那 thread-loader 之后的 loader 就会在一个单独的 worker 池(worker pool)中运行。)
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
// 创建一个 js worker 池
use: [
'thread-loader',
'babel-loader'
]
},
]
}
3.优化压缩时间
webpack4 默认内置使用 terser-webpack-plugin 插件压缩优化代码,该插件使用 terser 来缩小 JavaScript 。
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
}
4.代码分割
Webpack默认会将所有依赖的文件打包输出到一个bundle.js中(单入口时),可以使用代码分割来将不同代码单独打包成不同chunk输出
- 通过optimization将公共代码单独打包成chunk。
- import动态导入(当想要根据业务拆分bundle时可以用这种方式)
- css资源单独打包。(使用MiniCssExtractPlugin提供的loader)
5. 合理利用缓存。
可以缩短连续构建时间,但会增加初始构建时间.
-
有些解析文件的loader自身带有缓存功能(如babel-loader,vue-loader)
-
可以通过cache-loader/HardSourceWebpackPlugin.
-
webpack5提供了cache配置项
4. 实现自定义loader\自定义plugin
自定义loader:
module.exports = function (source) {
// 默认单行和多行注释都删除
const defaultOption = {
oneLine: true,
multiline: true,
}
// 获取到webpack.config.js中配置的options
const configOptions = this.getOptions();
let result = source;
const options = Object.assign({}, defaultOption, configOptions);
// 去除单行注释
if (options.oneLine) {
result = result.replace(/\/\/.*/g, "")
}
// 去除多行注释
if (options.multiline) {
result = result.replace(/\/\*.*?\*\//g, "")
}
return result
}
自定义plugin:
const { sources } = require('webpack');
class DelCommentPlugin {
constructor(options) {
this.options = options
}
apply(compiler) {
// compilation 创建之后执行注册事件
compiler.hooks.compilation.tap("DelCommentPlugin", (compilation) => {
// 处理asset
compilation.hooks.processAssets.tap(
{
name: 'DelCommentPlugin', //自定义插件名称
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_PRE_PROCESS,
},
(assets) => {
for (const name in assets) {
// 只对js资产做处理
if (name.endsWith(".js")) {
if (Object.prototype.hasOwnProperty.call(assets, name)) {
const asset = compilation.getAsset(name);
const contents = asset.source.source();
const result = contents.replace(/\/\/.*/g, "").replace(/\/\*.*?\*\//g, "");
// 更新asset的内容
compilation.updateAsset(
name,
new sources.RawSource(result)
);
}
}
}
}
);
})
}
}
module.exports = DelCommentPlugin
参考:
juejin.cn/post/697174…
juejin.cn/post/684490…
juejin.cn/post/684490…
juejin.cn/post/697532…