需要安装的模块
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"scripts": {
"serve": ""
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.23.9",
"@babel/preset-env": "^7.23.9",
"add-asset-html-webpack-plugin": "^6.0.0",
"autoprefixer": "^10.4.17",
"babel-loader": "^9.1.3",
"css-loader": "^6.10.0",
"css-minimizer-webpack-plugin": "^6.0.0",
"csv-loader": "^3.0.5",
"dart-sass": "^1.25.0",
"html-webpack-plugin": "^5.6.0",
"imports-loader": "^5.0.0",
"json5": "^2.2.3",
"mini-css-extract-plugin": "^2.8.0",
"postcss-loader": "^8.1.0",
"sass-loader": "^14.1.0",
"style-loader": "^3.3.4",
"terser-webpack-plugin": "^5.3.10",
"toml": "^3.0.0",
"ts-loader": "^9.5.1",
"typescript": "^5.3.3",
"webpack": "^5.90.0",
"webpack-bundle-analyzer": "^4.10.1",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1",
"webpack-merge": "^5.10.0",
"xml-loader": "^1.2.1",
"yaml": "^2.3.4"
},
"dependencies": {
"lodash": "^4.17.21",
"rgb-random-lazychild": "^1.0.2"
},
"browserslist": ["> 1%", "last 2 versions"]
}
基本命令
"scripts": {
"serve": "webpack serve --config webpack.config.js",
"build": "webpack --config webpack.config.js"
}
基本配置
webpack 的配置文件为:webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js", //以哪个文件为主
output: {
// filename: '[name].[contenthash].js',
filename: "index.js",
path: path.resolve(__dirname, "./dist"), //绝对路径
clean: true, //清理上次打包的文件
},
mode: "development", // 指定运行模式为开发模式
devtool: "eval-cheap-module-source-map",
plugins: [
new HtmlWebpackPlugin({
template: "./index.html",
filename: "app.html",
inject: "body", //在body里面生成script标签
}),
],
// 配置热更新服务器
devServer: {
static: "./dist",
},
};
静态资源处理
1.处理图片文件
asset/resource:
module: {
rules: [
{
//处理图片文件
test: /\.png$/,
type: "asset/resource", //类型
// 路径
generator: {
filename: "images/[contenthash][ext]",
},
},
];
}
asset/inline:
module: {
rules: [
{
//处理图片文件
test: /\.svg$/,
type: "asset/inline", //inline类型,将图片变为base64
},
];
}
asset:
module: {
rules: [
{
//处理图片文件
test: /\.png$/,
type: "asset", //类型:自动选择:默认如果大于8k-->本地资源,否则就是inline类型
// 自定义
parser: {
dataUrlCondition: {
maxSize: 4 * 1024 * 1024, //如果图片大于4M,那么就作为本地资源,否则就是inline类型
},
},
},
];
}
2.处理纯文本
module: {
rules: [
{
//处文本文件
test: /\.txt$/,
type: "asset/source", //类型
},
];
}
3.处理字体文件
module: {
rules: [
{
// 加载字体
test: /\.(woff|woff2|eot|ttf|otf)$/,
type: "asset/resource",
// 路径
generator: {
filename: "iconFont/[contenthash][ext]",
},
},
];
}
4.其它文件的处理
module: {
rules: [
{
test: /\.toml$/,
type: 'json',
// 指定解析器
parser: {
parse: toml.parse,
}
},
{
test: /\.yaml$/,
type: 'json',
parser: {
parse: yaml.parse,
}
},
{
test: /\.json5$/,
type: 'json',
parser: {
parse: json5.parse,
}
},
{
test: /\.csv$/,
use: 'csv-loader'
},
{
test: /\.xml$/,
use: 'xml-loader'
}
],
},
babel-loader
这个可以将 ES6 转 ES5
// 需要安装的库
/**
* 1. babel-loader: 用于处理es6语法
* 2. @babel/core: babel核心库
* 3. @babel/preset-env: babel预设库, 一组babel插件集合
*/
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
];
}
代码分离
防止引入的第三方库重复导出
内置模块处理:
optimization: {
splitChunks: {
chunks: "all"; //对所有模块进行分割
}
}
使用 dependOn:
module.exports = {
// 多个入口文件
entry: {
index: {
import: "./src/index.js",
dependOn: "comment",
},
another: {
import: "./src/another.js",
dependOn: "comment",
},
comment: "lodash",
},
};
预获取和预加载
预获取 prefetch: 在浏览器加载完必要的资源后,空闲时就会去获取可能需要的资源。 预加载 preload: 预先加载当前页面可能需要的资源, 它会与必要资源并行请求。
/* webpackPrefetch: true */
/* webpackPreload: true */
btn.addEventListener("click", () => {
import(/* webpackPrefetch: true */ "./math").then(({ add }) => {
console.log(add(4, 8));
});
});
缓存第三方库
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
公共路径
output: {
filename: 'index.js',
path: path.resolve(__dirname, './dist'), //绝对路径
clean: true, //清理上次打包的文件
publicPath: 'http://127.0.0.1:5500/公共路径/dist/' //设置打包后的文件访问路径
},
动态改变 mode
module.exports = (env) => {
mode: env.production ? 'production' : 'development', // 如果要压缩, 则需要生产环境
}
配置文件的拆分与合并
const { merge } = require("webpack-merge");
const configDev = require("./webpack.config.dev");
const configPro = require("./webpack.config.pro");
const configCommon = require("./webpack.config.common");
module.exports = (env) => {
switch (true) {
case env.development:
return merge(configDev, configCommon);
case env.production:
return merge(configPro, configCommon);
default:
return new Error("No valid environment");
}
};
路径别名
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
外部扩展
externalsType: "script",
externals: {
jquery: [
"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js",
"$"
]
}
这样就可以直接使用了:
import $ from "jquery";
console.log($);
依赖分析图
使用插件:webpack-bundle-analyzer
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); //依赖图插件
module.exports = {
plugins: [new BundleAnalyzerPlugin()],
};
css 的自动兼容
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"],
},
];
}
css 模块化
module: {
rules: [
{
test: /\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true,
},
},
],
},
];
}
解析 sass
module: {
rules: [
{
// 加载css或者scss文件
test: /\.(css|scss)$/,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
implementation: require("dart-sass"),
},
},
], //顺序不能改,,从数组后往前进行加载
},
];
}
抽离与压缩 css
需要生产环境
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //提取css
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); //压缩css
module.exports = {
plugins: [
// 提取css
new MiniCssExtractPlugin({
filename: "styles/[contenthash].css", //生成的css位置与css文件名字
}),
],
module: {
rules: [
{
// 加载css或者scss文件
test: /\.(css|scss)$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "sass-loader",
options: {
implementation: require("dart-sass"),
},
},
], //顺序不能改,,从数组后往前进行加载
},
],
},
optimization: {
minimizer: [new CssMinimizerPlugin()], //压缩css
},
};
压缩 js
需要生产环境
const terserPlugin = require("terser-webpack-plugin"); //压缩js
module.exports = {
// 我们发现在使用了css压缩后,js不能进行自动压缩了,所以需要自己配置
optimization: {
minimizer: [
new terserPlugin(), //压缩js
],
},
};
解析 ts
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader",
},
];
}
shimming 预置全局变量
const webpack = require("webpack");
module.exports = {
plugins: [
new webpack.ProvidePlugin({
_: "lodash",
}),
],
};
使用:
console.log(_.join([1, 2, 3], "~"));
将 this 指向为 window
module: {
rules: [
{
test: /\.js$/,
use: "imports-loader?wrapper=window",
},
];
}
自建小轮子之 library
因为 webpack 打包后的文件都是一个自执行函数,在库外部的任何位置都访问不到它,所以需要配置 library
module.exports = {
// 如果library的type为module时,必须配置
experiments: {
outputModule: true,
},
output: {
library: {
// type: "umd"
type: "module",
},
globalObject: "globalThis", //解决在type: "umd"时,self未定义的问题
},
};