文章目录
webpack 是一个用于现代 JavaScript 应用程序的
静态模块打包工具
。
【 静态模块打包工具:将多个模块(JavaScript、CSS、图片等)打包到一个或多个输出文件中的工具。通过对模块进行静态分析和转换,可以有效地管理模块之间的依赖关系、进行代码优化和资源处理。打包后的输出内容被认为成
静态资源
】
打包方式
wepack会以一个或多个文件
作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件
输出出去。
当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图
(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles
(包),它们均为静态资源,用于展示你的内容。
为什么打包
我们会用各种语言进行开发,但是浏览器智能只能html、js、css。通过打包可以将我们的开发语言转换成浏览器识别的语言。
打包的功能:
编译
:将开发语言转换成浏览器能够识别的语言压缩
:打包后的文件体积减小,可以提高网页的加载速度- 多个文件合并成一个文件:打包后合并成一个文件,页面只需请求一次,这样能在一定程度上提升页面渲染效率
- 缓存静态资源:可以指定打包文件中的静态资源路径为CDN的域名,将这些资源上传到CDN上,从而实现cdn缓存
配置文件
weback的一个重点内容就是通过各种配置将各种语言编译成浏览器能够解析的语言。
从 v4.0.0 开始,webpack 可以不用再引入一个配置文件
来打包项目。传统的方式是指定一个配置文件webpack.config.js
进行打包。
webpack的配置文件一般名为:webpack.config.js
,同时不同的开发模式下可以配置不同的打包文件,不同模式下调用不同的文件进行打包,开发模式的配置文件一般名为: webpack.config.dev.js
;生产模式的配置文件一般名为: webpack.config.prod.js
。
开发模式
webpack.config.dev.js
const path = require("path")//nodejs核心模块主要用于处理路径问题
//引入eslint插件
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
// 引入HtmlWebpack插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// loader:直接下载对应的包就可以使用
// plugins:下载对应的包后需要引入使用
module.exports = {
//入口
entry: "./src/main.js",//相对路径
//输出
output: {
//文件的输出路径(默认输出目录:dist)
// path.resolve()方法返回一个绝对路径
// __dirname 当前文件的文件夹绝对路径
path: path.resolve(__dirname, "dist"),//绝对路径
//文件名
filename: "static/js/main.js",
clean: true, // 自动将上次打包目录资源清空
/*打包输出目录:
├── dist
└── static
├── imgs
│ └── 7003350e.png
└── js
└── main.js
*/
}
// 加载器
module: {
rules: [
//loader的配置
//--------------样式start----------
//css文件处理
{
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: ["style-loader", "css-loader"],
},
//less文件处理
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"],
},
//sass文件处理
{
test: /\.s[ac]ss$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
//styl文件处理
{
test: /\.styl$/,
use: ["style-loader", "css-loader", "stylus-loader"],
},
//--------------样式end----------
//--------------图片start----------
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
// “asset” 相当于url-loader, 将文件转化成 Webpack 能识别的资源,同时小于某个大小的资源会处理成 data URI 形式
parser: {
dataUrlCondition: {
//转换成base64,优点:减少请求数量 缺点:体积会变大
maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
}
},
generator: {
// 将图片文件输出到 static/imgs 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: "static/imgs/[hash:8][ext][query]",
},
},
//--------------图片end----------
//--------------字体start----------
{
//处理字体图标资源
test: /\.(ttf|woff2?)$/,
type: "asset/resource",
//“asset/resource” 相当于file-loader, 将文件转化成 Webpack 能识别的资源,其他不做处理
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
//--------------字体end----------
//--------------其他文件start---------
{
test: /\.(map4|map3|avi)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:8][ext][query]",
},
//--------------其他文件end----------
//--------------js代码兼容性处理(babel,需要配置对应的babel文件)---------
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
//--------------js代码兼容性处理end---------
],
},
// 插件
plugins: [
// plugins的配置
//----------代码格式Eslint配置start(需要配置对应的eslint文件)-----------
new ESLintWebpackPlugin({
// 指定eslint检查文件的根目录
context: path.resolve(__dirname, "src"),
}),
//----------代码格式Eslint配置end-----------
//-------------html资源start----------------
// 我们可以将打包好的内容直接注入到某个html文件中,这样html文件就无需引入我们所写的js文件
new HtmlWebpackPlugin({
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "public/index.html"),
}),
//-------------html资源end----------------
],
// 模式
mode: "development",
hot: true, // 开启HMR功能(修改某个模块代码,就只有这个模块代码需要重新打包编译,其他模块不变,这样打包速度就能很快)
}
生产模式
相比于开发模式来讲,生产模式的一些打包规则更注重用户体验:
- 白屏现象:
使用"style-loader"
的时候,css 文件被打包到 js 文件中是以style 标签来生成样式的,这样对于网站来说,会出现闪屏现象
,用户体验不好。最好使用单独的 Css 文件,link标签加载,此时我们就需要使用mini-css-extract-plugin
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
- css样式不兼容问题
postcss-preset-env
能解决大多数样式兼容性问题
npm i postcss-loader postcss postcss-preset-env -D
- 压缩
样式文件压缩npm i css-minimizer-webpack-plugin -D
webpack 默认生产模式已经开启了:html 压缩和 js 压缩,不需要额外进行配置
webpack.config.prod.js
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");
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, "../dist"), // 生产模式需要输出
filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
clean: true,
},
module: {
rules: [
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: [MiniCssExtractPlugin.loader, "css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
],
},
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, "css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
"less-loader"],
},
{
test: /\.s[ac]ss$/,
use: [MiniCssExtractPlugin.loader, "css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
"sass-loader"],
},
{
test: /\.styl$/,
use: [MiniCssExtractPlugin.loader, "css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
"stylus-loader"],
},
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
},
},
generator: {
// 将图片文件输出到 static/imgs 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: "static/imgs/[hash:8][ext][query]",
},
},
{
test: /\.(ttf|woff2?)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
],
},
plugins: [
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src"),
}),
new HtmlWebpackPlugin({
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "../public/index.html"),
}),
// css压缩
new CssMinimizerPlugin(),
],
// devServer: {
// host: "localhost", // 启动服务器域名
// port: "3000", // 启动服务器端口号
// open: true, // 是否自动打开浏览器
// },
mode: "production",
};
webpack的优化配置
参照这里:https://blog.youkuaiyun.com/mantou_riji/article/details/125998059
打包命令
配置好webpack的文件之后就可以通过该配置文件进行项目的打包了。
格式: webpack --config 配置文件
eg:
webpack --config ./webpack.config.js
在package.json文件中配置打包命令
配置运行指令
为了方便运行不同模式的指令,我们将指令定义在 package.json
中 scripts 里面。
package.json
{
// 其他省略
"scripts": {
"start": "npm run dev",
"build:dev": "webpack serve --config ./config/webpack.dev.js",
"build:prod": "webpack --config ./config/webpack.prod.js"
}
}
以后打包指令:
开发模式:npm run dev
生产模式:npm run build
打包命令的参数
大部分可以参数直接在配置文件中配置。
--config <config>
:指定使用的配置文件
,默认为 webpack.config.js。--mode <mode>
:指定打包的模式,可选的值有development 和 production
。--entry <entry>
:指定入口文件。--output <output>
:指定输出文件的路径和文件名。--watch
:监视文件改动并实时重新编译。
示例:
npx webpack --watch
使用 --watch 参数时,webpack会监视配置文件和入口文件以及它们所依赖的文件
的变化,并在这些文件有修改时重新编译。
配置文件: webpack.config.js
入口文件:通过配置文件指定的入口文件
所依赖的文件:如果在配置文件中定义了其他文件的依赖,webpack也会监视这些依赖文件,如样式文件、模板文件、自定义模块等。
webpack会检测通过配置文件显式指定或间接引用的文件变化
6. --devtool <devtool>
:用于指定生成 source map
的方式(即打包后的代码和打包前的代码之间的映射方式),以方便在调试过程中定位源代码。
示例:npx webpack --devtool source-map
几种取值:
- source-map:生成独立的 Source Map 文件(.map文件)。
当使用 devtool 配置项设置为 source-map 时,Webpack 会生成独立的 Source Map 文件(.map 文件),其将打包前后的代码关联起来。这样,在浏览器的开发者工具中,当出现代码问题时,会显示真实的源码位置
,而不是打包后的代码位置。
但是source-map会增加构建时间和构建大小,所以在生产环境下,通常会将 devtool 设置为cheap-module-source-map 或 hidden-source-map
,以提高性能并降低生成的 Source Map 文件的大小。 - cheap-module-source-map:生成 Source Map 文件,但
不包含列信息
。 - eval-source-map:每个模块都使用 eval 执行,并生成 Source Map 数据,最快但不支持调试转换后的代码。
- cheap-module-eval-source-map:组合使用 cheap-module 和 eval 执行方式,生成 Source Map 数据。
- cheap-module-inline-source-map:以
行内
的方式生成 Source Map 数据,可以定位源文件内容(行和列)。相比于source-map
具有较好的性能,适用于开发环境
中进行调试。但这种方式的 Source Map 数据相对简单,可能对于复杂的转换和加载器链可能不够准确。因此,在生产环境中不建议使用这种方式生成 Source Map。
也可以在配置文件中配置:
module.exports = {
// 其他省略
mode: "development",
devtool: "cheap-module-source-map",
};
--module-bind <module>
:指定特定类型文件的加载器。
示例
npx webpack --module-bind css=style-loader!css-loader js=babel-loader
- npx webpack --help 命令查看所有的可用命令参数及其说明。
webpack的非文件配置
vue.config.js中配置webpack
如果您不想单独设置一个文件来配置webpack,Vue CLI提供了一个默认的配置文件,可以在项目根目录中的vue.config.js
文件中进行配置。
在vue.config.js文件中,可以使用module.exports导出一个包含配置选项的对象。在module.exports对象中添加不同的配置选项。
以下是一些常见的配置选项示例:
- publicPath:指定应用程序所在的基本 URL。在开发环境和生产环境中,将使用不同的值。
- outputDir:指定构建输出的目录,默认为dist。
- devServer:配置开发服务器的行为,比如设置监听的端口和代理等。
configureWebpack:用于修改webpack的配置对象
,可以通过此选项添加额外的webpack插件或自定义配置。
以下是一个示例配置:
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/my-app/' : '/',
outputDir: 'dist',
devServer: {
port: 8080,
proxy: {
//代理地址
'/api': {
target: 'http://localhost:3000',
changeOrigin: true
}
}
},
configureWebpack: {
plugins: [
// 添加自定义的插件
new MyCustomPlugin()
]
}
}