
知识体系
初始化阶段
构建阶段
生成阶段

本质上,webpack是一个现代Javascript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,他会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要地每个模块,然后将所有这些模块打包成一个或多个bundle
class MyClass {
myProps = 42; // 类中直接定义实例属性和静态属性,而不需要在构造函数中使用 this 关键字
constructor() {
console.log(this.myProps);
}
}function mixin(behaviour) {
return function(target) {
Object.assign(target.prototype, behaviour);
};
}
// 使用装饰器应用mixin
@mixin({ foo: "bar" })
class MyClass {}
let obj = new MyClass();
console.log(obj.foo); // 输出 bar// 图片和字体处理
module.exports = {
// ...
module: {
rules: [
{
test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
type: "asset/resource",
generator: {
filename: "[name][hash:8][ext]"
},
parser: {
dataUrlCondition: {
maxSize: 50 * 1024 // 50kb
}
}
},
{
test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
type: "asset/inline",
generator: {
filename: "[name][hash:8][ext]"
},
parser: {
dataUrlCondition: {
maxSize: 50 * 1024 // 50kb
}
}
}
]
}
};例如 filename: "[name][hash:8][ext]"
loader 本质上就是一个函数,这个函数会在我们在我们加载一些文件时执行; 在 webpack 的定义中,loader 导出一个函数,loader 会在转换源模块(resource)的时候调用该函数。这个函数中,我们可以通过传入 this 上下文给 Loader API 来使用他们
设计原则
module.exports = function(source) {
console.log("source>>>>", source);
return source;
};Plugin它是一个插件,用于增强webpack功能,webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 webpack 提供的 API 改变输出结果 plugin 通常是在 webpack 打包的某个时间节点做一些操作,一般使用 new Plugin() 的形式使用
class DemoPlugin {
constructor() {
console.log("plugin init");
}
apply(compiler) {
// 一个新的编译(compilation)创建之后(同步)
// compilation代表每一次执行打包,独立的编译
compiler.hooks.compile.tap("DemoWebpackPlugin", compilation => {
console.log(compilation);
});
// 生成资源到 output 目录之前(异步)
compiler.hooks.emit.tapAsync("DemoWebpackPlugin", (compilation, fn) => {
console.log(compilation);
compilation.assets["index.md"] = {
// 文件内容
source: function() {
return "this is a demo for plugin";
},
// 文件尺寸
size: function() {
return 25;
}
};
fn();
});
// 第二种写法(promise)
compiler.hooks.emit.tapPromise("DemoWebpackPlugin", compilation => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 1000);
}).then(() => {
console.log(compilation.assets);
compilation.assets["index.md"] = {
// 文件内容
source: function() {
return "this is a demo for plugin";
},
// 文件尺寸
size: function() {
return 25;
}
};
});
});
// 第三种写法(async await)
compiler.hooks.emit.tapPromise("DemoWebpackPlugin", async compilation => {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 1000);
});
console.log(compilation.assets);
compilation.assets["index.md"] = {
// 文件内容
source: function() {
return "this is a demo for plugin";
},
// 文件尺寸
size: function() {
return 25;
}
};
});
}
}
module.exports = DemoPlugin();SourceMap 是一种映射关系,当项目运行后,如果出现错误,我们可以利用 SourceMap 反向定位到源码位置
module.exports = {
//...
devtool: "source-map" // 使用完整的 SourceMap
};推荐
module.exports = {
// noParse
module: {
noParse: /jquery|lodash/,
rules: []
},
// resolve
resolve: {
modules: [paths.src, "node_modules"], // webpack 优先 src 目录下查找需要解析的文件,会大大节省查找时间
extensions: [".js", ".jsx", ".json"],
// extensions: ['.ts', '...'],
symlinks: false,
alias: {
"@": paths.src,
assets: paths.public
},
resolveLoader: {
modules: ["node_modules", resolve("loader")], // 搜索目录
alias: {
"my-loader": path.resolve(__dirname, "loaders/my-loader.js") // 创建别名
},
extensions: [".js", ".json"] // 自动解析扩展名
}
},
optimization: {
runtimeChunk: true,
minimizer: [
new CssMinimizerPlugin({
parallel: 4,
}),
new TerserPlugin({
parallel: 4,
terserOptions: {
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
}
})
]
},
splitChunks: {
// include all types of chunks
chunks: 'all',
// 重复打包问题
cacheGroups:{
vendors:{ // node_modules里的代码
test: /[\\/]node_modules[\\/]/,
chunks: "all",
// name: 'vendors', 一定不要定义固定的name 切记不要为 cacheGroups 定义固定的 name,因为 cacheGroups.name 指定字符串或始终返回相同字符串的函数时,会将所有常见模块和 vendor 合并为一个 chunk。这会导致更大的初始下载量并减慢页面加载速度
priority: 10, // 优先级
enforce: true
}
}
}
};HRM的原理实际上是 webpack-dev-server(WDS)和浏览器之间维护了一个websocket服务。当本地资源发生变化后,webpack会先将打包生成新的模块代码放入内存中,然后WDS向浏览器推送更新,并附带上构建时的hash,让客户端和上一次资源进行对比