生产模式是开发完成代码后,我们需要得到代码将来部署上线。这个模式下我们主要对代码进行优化,让其运行性能更好。优化主要从两个角度出发:
- 优化代码运行性能
- 优化代码打包速度
一、生产模式准备
我们分别准备两个配置文件来放不同的配置
1. 文件目录
├── webpack-test (项目根目录)
├── config (Webpack配置文件目录)
│ ├── webpack.dev.js(开发模式配置文件)
│ └── webpack.prod.js(生产模式配置文件)
├── node_modules (下载包存放目录)
├── src (项目源码目录,除了html其他都在src里面)
│ └── 略
├── public (项目html文件)
│ └── index.html
├── .eslintrc.js(Eslint配置文件)
├── babel.config.js(Babel配置文件)
└── package.json (包的依赖管理配置文件)
2. 修改开发模式的配置文件:
开发模式启动指令:npx webpack serve --config ./config/webpack.dev.js
const path = require('path'); //node.js核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口
entry: './src/main.js', //相对路径
// 输出
output: {
// __dirname nodejs的变量,代表当前文件的文件夹目录
// path: path.resolve(__dirname, "../dist"), //所以文件的输出绝对路径
// filename: 'static/js/main.js', //入口文件的打包输出名称
// 自动清空上次打包内容, 原理:在打包前,将path整个目录内容清空,在进行打包
// clean: true,
//因为开发模式没有输出,不需要指定输出路径
path: undefined,
filename: "static/js/main.js"
},
// 加载器
module: {
rules: [
// css-loder的配置
{
test: /\.css$/, //只检测.css文件
//执行顺序:从右到左(从下到上)
use: [
"style-loader", //将js中css通过创建style标签添加到html文件中
"css-loader"], //将css资源编译成commonjs的模块到js中
},
// less-loder的配置
{
test: /\.less$/,
// use:可以使用多个loader, loader:只能使用一个loader
use: [
// compiles Less to CSS
'style-loader',
'css-loader',
'less-loader', //将js中less通过创建style标签添加到html文件中
],
},
// scss-loder的配置
{
test: /\.s[ac]ss$/,
use: [
'style-loader', // 将 JS 字符串生成为 style 节点
'css-loader', // 将 CSS 转化成 CommonJS 模块
'sass-loader', // 将 Sass 编译成 CSS
],
},
// stylus-loader的配置
{
test: /\.styl$/,
use: [
'style-loader', // 将 JS 字符串生成为 style 节点
'css-loader', // 将 CSS 转化成 CommonJS 模块
'stylus-loader', // 将 Sass 编译成 CSS
],
},
// 图片
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于10KB图片会转base64, 优点:减少请求数量 缺点:体积变大
maxSize: 15 * 1024 // 4kb
}
},
generator: {
// 输出图片名字
filename: 'static/images/[hash:10][ext][query]' //[hash:10] 表示hash值只取10位
}
},
// 图标
{
test: /\.(ttf|woff2?)$/,
type: 'asset/resource',
generator: {
// 输出名字
filename: 'static/media/[hash:10][ext][query]'
}
},
// 其他资源
{
test: /\.(map3|map4|avi)$/, //在这里加上就可以统一处理
type: 'asset/resource',
generator: {
// 输出名字
filename: 'static/media/[hash:10][ext][query]'
}
},
// babel
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/, //排除 node_modules 中的js文件 (这些文件不处理)
loader: 'babel-loader',
// options: {
// presets: ['@babel/preset-env'] //一般在 babel.config.js 文件写,方便修改
// }
}
]
},
// 插件
plugins: [
// plugins的配置
new ESLintPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src") //__dirname表示绝对路径
}),
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html")
})
],
// 开发服务器:不会输出资源,在内存中编译打包的
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
},
// 模式
mode: 'development'
}
3. 修改生产模式的配置文件:
生产模式启动指令:npx webpack --config ./config/webpack.prod.js
const path = require('path'); //node.js核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口
entry: './src/main.js', //相对路径
// 输出
output: {
// __dirname nodejs的变量,代表当前文件的文件夹目录
path: path.resolve(__dirname, "../dist"), //所以文件的输出绝对路径
filename: 'static/js/main.js', //入口文件的打包输出名称
// 自动清空上次打包内容, 原理:在打包前,将path整个目录内容清空,在进行打包
clean: true,
},
// 加载器
module: {
rules: [
// css-loder的配置
{
test: /\.css$/, //只检测.css文件
//执行顺序:从右到左(从下到上)
use: [
"style-loader", //将js中css通过创建style标签添加到html文件中
"css-loader"], //将css资源编译成commonjs的模块到js中
},
// less-loder的配置
{
test: /\.less$/,
// use:可以使用多个loader, loader:只能使用一个loader
use: [
// compiles Less to CSS
'style-loader',
'css-loader',
'less-loader', //将js中less通过创建style标签添加到html文件中
],
},
// scss-loder的配置
{
test: /\.s[ac]ss$/,
use: [
'style-loader', // 将 JS 字符串生成为 style 节点
'css-loader', // 将 CSS 转化成 CommonJS 模块
'sass-loader', // 将 Sass 编译成 CSS
],
},
// stylus-loader的配置
{
test: /\.styl$/,
use: [
'style-loader', // 将 JS 字符串生成为 style 节点
'css-loader', // 将 CSS 转化成 CommonJS 模块
'stylus-loader', // 将 Sass 编译成 CSS
],
},
// 图片
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于15KB图片会转base64, 优点:减少请求数量 缺点:体积变大
maxSize: 15 * 1024 // 4kb
}
},
generator: {
// 输出图片名字
filename: 'static/images/[hash:10][ext][query]' //[hash:10] 表示hash值只取10位
}
},
// 图标
{
test: /\.(ttf|woff2?)$/,
type: 'asset/resource',
generator: {
// 输出名字
filename: 'static/media/[hash:10][ext][query]'
}
},
// 其他资源
{
test: /\.(map3|map4|avi)$/, //在这里加上就可以统一处理
type: 'asset/resource',
generator: {
// 输出名字
filename: 'static/media/[hash:10][ext][query]'
}
},
// babel
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/, //排除 node_modules 中的js文件 (这些文件不处理)
loader: 'babel-loader',
// options: {
// presets: ['@babel/preset-env'] //一般在 babel.config.js 文件写,方便修改
// }
}
]
},
// 插件
plugins: [
// plugins的配置
new ESLintPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src") //__dirname表示绝对路径
}),
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html")
})
],
// 生产模式不需要devServer
// 模式
mode: 'production',
}
由于运行指令比较长,为了方便运行不同模式的指令,我们将指令定义在 package.json 中 scripts 里面:
"scripts": {
"start":"npm run dev",
"dev": "webpack serve --config ./config/webpack.dev.js",
"build":"webpack --config ./config/webpack.prod.js"
},
- 生产模式运行指令: npm run build
- 开发模式运行指令:npm start
二、生产模式配置
1. Css处理
Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式,这样对于网站来说,会出现闪屏现象,用户体验不好,我们应该是单独的 Css 文件,通过 link 标签加载性能才好
1.下载包:npm install --save-dev mini-css-extract-plugin
2. 生产模式下配置文件 webpack.pros.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin({
filename:'static/css/main.css'
})],
module: {
rules: [
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader, //提取css成单独的文件
"css-loader"
],
},
],
},
};
2. Css 兼容性处理
1. 下载:npm i postcss-loader postcss postcss-preset-env -D
2. 生产模式配置文件 webpack.prod.js
在css-loader后面,less-loader、sass-loader、stylus-loader前面加上 postcss-loader
module.exports = {
module: {
rules: [
// css-loder的配置
{
test: /\.css$/, //只检测.css文件
//执行顺序:从右到左(从下到上)
use: [
MiniCssExtractPlugin.loader, //提取css成单独的文件
"css-loader", //将css资源编译成commonjs的模块到js中
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
],
},
// less-loder的配置
{
test: /\.less$/,
// use:可以使用多个loader, loader:只能使用一个loader
use: [
// compiles Less to CSS
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
'less-loader', //将js中less通过创建style标签添加到html文件中
],
},
// scss-loder的配置
{
test: /\.s[ac]ss$/,
use: [
MiniCssExtractPlugin.loader, // 将 JS 字符串生成为 style 节点
'css-loader', // 将 CSS 转化成 CommonJS 模块
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
'sass-loader', // 将 Sass 编译成 CSS
],
},
// stylus-loader的配置
{
test: /\.styl$/,
use: [
MiniCssExtractPlugin.loader, // 将 JS 字符串生成为 style 节点
'css-loader', // 将 CSS 转化成 CommonJS 模块
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
'stylus-loader', // 将 Sass 编译成 CSS
],
},
]
}
}
3. 控制兼容性
我们可以在 package.json 文件中添加 browserslist 来控制样式的兼容性做到什么程度。
//例如:兼容浏览器 ie8 以上
"browserslist" : [
"ie >= 8"
]
browserslist 文档:https://github.com/browserslist/browserslist
实际开发中可以这样设置:
"browserslist" : [
"last 2 version", // 所有浏览器适配最近两个版本
"> 1%", // 覆盖99%的浏览器
"not dead" //不要已经死了的浏览器
]
3. 合并配置
// 用来获取处理样式的loader
function getStyleLoader(pre) { //不同的loader通过传参
return [
MiniCssExtractPlugin.loader, //提取css成单独的文件
"css-loader", //将css资源编译成commonjs的模块到js中
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 智能预设,能解决大多数样式兼容性问题
],
},
},
},
pre,
].filter(Boolean) //过滤器
}
module.exports = {
// 入口
entry: './src/main.js', //相对路径
// 输出
output: {
// __dirname nodejs的变量,代表当前文件的文件夹目录
path: path.resolve(__dirname, "../dist"), //所以文件的输出绝对路径
filename: 'static/js/main.js', //入口文件的打包输出名称
// 自动清空上次打包内容, 原理:在打包前,将path整个目录内容清空,在进行打包
clean: true,
},
// 加载器
module: {
rules: [
// css-loder的配置
{
test: /\.css$/, //只检测.css文件
//执行顺序:从右到左(从下到上)
use: getStyleLoader()
},
// less-loder的配置
{
test: /\.less$/,
// use:可以使用多个loader, loader:只能使用一个loader
use: getStyleLoader('less-loader')
},
// scss-loder的配置
{
test: /\.s[ac]ss$/,
use: getStyleLoader('sass-loader')
},
// stylus-loader的配置
{
test: /\.styl$/,
use: getStyleLoader('stylus-loader')
},
]
}
4. css压缩
1. 安装插件: npm install css-minimizer-webpack-plugin --save-dev
2. 配置文件 webpack.prod.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
// `...`,
new CssMinimizerPlugin(),
],
},
plugins: [new MiniCssExtractPlugin()],
};