SourceMap
SourceMap(源代码映射)是一个用来生成源代码与构建后代码一一映射的文件的方案。使用后会生成xxx.map文件,里面包含源代码与构建后代码每一行、每一列的映射关系。当构建后代码出错了,会通过xxx.map文件,从构建后代码出错的位置找到映射后源代码的出错位置,这样浏览器就能提示源代码文件的出错位置,让我们能够在开发调试时快速的定位到错误的原因。
sourceMap的值有很多种,可以参考官网的文档
实际使用时,在开发时我们一般用cheap-module-source-map,他的优点是打包编译的速度快,但是映射是只包含行映射。
module.exports = {
// ...
mode: "development",
devtool: "cheap-module-source-map",
};
而在生产模式下则直接配置为source-map即可,它将会包含行列映射,相应的打包编译时速度也会慢一些
module.exports = {
// ...
mode: "production",
devtool: "source-map",
};
HotModuleReplacement
HotModuleReplacement(热模块替换)简称为HMR,是指在程序运行中,替换、添加或删除模块,而无需重新加载整个页面。
在开发时进行配置即可:
module.exports = {
// 其他省略
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
hot: true, // 开启HMR功能(只能用于开发环境,生产环境不需要了)
},
};
在实际的开发中我们还需要使用其他的比如react-hot-loader或vue-loader来实现HMR。
OneOf
打包时每个文件都会经过所有的loader处理,虽然有test作为匹配但还是需要过一遍,比较慢,在最外层加上一个oneOf就可以实现只要匹配上一个loader剩下就不匹配的效果:
module.exports = {
module: {
rules: [
{
oneOf: [
// 相关loader配置
],
},
],
},
};
Include/Exclude
Include即包含,只处理xxx文件
exclude即排除,除了xxx文件外都处理
可以在module和pulgins里配置
Cache
可以对之前的Eslint检查和Babel编译结果进行缓存,使得第二次及之后的打包速度变快:
module.exports = {
module: {
rules: [
{
oneOf: [
{
test: /\.js$/,
// exclude: /node_modules/, // 排除node_modules代码不编译
include: path.resolve(__dirname, "../src"), // 也可以用包含
loader: "babel-loader",
options: {
cacheDirectory: true, // 开启babel编译缓存
cacheCompression: false, // 缓存文件不要压缩
},
},
],
},
],
},
plugins: [
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src"),
exclude: "node_modules", // 默认值
cache: true, // 开启缓存
// 缓存目录
cacheLocation: path.resolve(
__dirname,
"../node_modules/.cache/.eslintcache"
),
}),
],
};
需要注意的是module和plugins中使用cache的方式不同
Thead
我们可以开启多进程同时处理js文件,这样打包的速度就会比之前的单进程打包要快许多。
const os = require("os");
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
// cpu核数
const threads = os.cpus().length;
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, "../dist"), // 生产模式需要输出
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true,
},
module: {
rules: [
{
oneOf: [
{
test: /\.js$/,
// exclude: /node_modules/, // 排除node_modules代码不编译
include: path.resolve(__dirname, "../src"), // 也可以用包含
use: [
{
loader: "thread-loader", // 开启多进程
options: {
workers: threads, // 数量
},
},
{
loader: "babel-loader",
options: {
cacheDirectory: true, // 开启babel编译缓存
},
},
],
},
],
},
],
},
plugins: [
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src"),
exclude: "node_modules", // 默认值
cache: true, // 开启缓存
// 缓存目录
cacheLocation: path.resolve(
__dirname,
"../node_modules/.cache/.eslintcache"
),
threads, // 开启多进程
}),
// ...
],
optimization: {
minimize: true,
minimizer: [
// css压缩也可以写到optimization.minimizer里面,效果一样的
new CssMinimizerPlugin(),
// 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
new TerserPlugin({
parallel: threads // 开启多进程
})
],
},
mode: "production",
devtool: "source-map",
};