前言
生产模式是开发完成代码后,我们需要得到代码将来部署上线。这个模式下我们主要对代码进行优化,让其运行性能更好。
优化主要从两个角度出发:
- 优化代码运行性能
- 优化代码打包速度
一、开发模式与生成模式准备
在项目根目录下新建config文件夹,分别配置开发及生产模式配置信息
开发模式
- webpack.dev.js
const path = require("path")
const ESLintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
// 入口,指示 Webpack 从哪个文件开始打包
//相对路径
entry: "./src/main.js",
//输出,指示 Webpack 打包完的文件输出到哪里去
output: {
//绝对路径
//path: path.resolve(__dirname, "../dist"),
//开发没有输出
path: undefined,
//入口文件文件名
filename: "static/js/main.js",
//自动清空上次打包结果,在打包前将path对应目录清空
//clean: true,
},
//加载器
module: {
//webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析
//loader的配置
rules: [
//css
{
//只检测以.css结尾的文件,$以...结尾,\转义,i不区分大小写
test: /\.css$/i,
//执行顺序,从右往左
//style-loader:将js中css通过创建style标签添加到html文件中生效
//css-loader:将css资源编译成commonjs的模块到j中
//ERROR in ./src/main.js 5:0-24 :Module not found: Error: Can't resolve 'style-loader'
use: ["style-loader", "css-loader"],
},
//less
{
test: /\.less$/i,
// loader:[]只能使用一个loader,use使用多个
use: [
// compiles Less to CSS
"style-loader",
"css-loader",
//将less编译成css文件
"less-loader",
],
},
//sass 、scss
{
//[ac]:a,c都可以
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
// 将 Sass 编译成 CSS
"sass-loader",
],
},
//stylus
{
test: /\.styl$/,
// 将 Stylus 文件编译为 CSS
use: [
"style-loader",
"css-loader",
// 将 stylus 编译成 CSS
"stylus-loader",
],
},
//图片资源处理,图片性能优化,小图转base64,大图不变
{
test: /\.(png|jpe?g|gif|webp|svg)/,
type: "asset",
parser: {
dataUrlCondition: {
//小于多少的图片做处理,小于10kb转base64,减少请求数量,资源可能会变大
maxSize: 10 * 1024, // 4kb
},
},
generator: {
//hash :根据文件内容生成id,hash只取10位
//etx:扩展名
//query:携带的其他参数
filename: "static/imgs/[hash:10][ext][query]",
},
},
{
test: /\.(ttf|woff2?|mp3|mp4|avi)/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:10][ext][query]",
},
},
//babel
{
test: /\.m?js$/,
//排除node_modules的js文件
exclude: /node_modules/,
use: {
loader: "babel-loader",
// options: {
// presets: ['@babel/preset-env']
// }
},
},
],
},
// 插件,扩展 Webpack 的功能
plugins: [
new ESLintWebpackPlugin({
// 指定哪些检查文件
//ERROR in [eslint] No ESLint configuration found
context: path.resolve(__dirname, "../src"),
}),
new HtmlWebpackPlugin({
//template模版:以public/index.html文件创建新的html
//结构和原来一致,并自动引入打包的资源
template: path.resolve(__dirname, "../public/index.html"),
}),
],
// 开发服务器:不会有输出
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
},
//开发模式:development
//生产模式:production
//两种模式
mode: "development",
}
- 打包编译
npx webpack serve --config .\config\webpack.dev.js
注意:
- 开发模式无输出,path可省略
- 绝对路径重写
生产模式
- webpack.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")
//用来获取处理样式的loader
const getPostcss = (prePro) => {
return [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
prePro,
].filter(Boolean)
}
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, "../dist"),
filename: "static/js/main.js",
clean: true,
},
module: {
rules: [
{
test: /\.css$/i,
//提取css成单独的css文件
use: getPostcss(),
},
//less
{
test: /\.less$/i,
use: getPostcss("less-loader"),
},
{
test: /\.s[ac]ss$/i,
use: getPostcss("sass-loader"),
},
{
test: /\.styl$/,
use: getPostcss("stylus-loader"),
},
{
test: /\.(png|jpe?g|gif|webp|svg)/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024, // 4kb
},
},
generator: {
filename: "static/imgs/[hash:10][ext][query]",
},
},
{
test: /\.(ttf|woff2?|mp3|mp4|avi)/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:10][ext][query]",
},
},
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
],
},
plugins: [
new ESLintWebpackPlugin({
context: path.resolve(__dirname, "../src"),
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"),
}),
new MiniCssExtractPlugin({
filename: "staric/scc/min.css",
}),
],
mode: "production",
}
- 打包编译
npx webpack --config .\config\webpack.prod.js
注意:生产模式有输出
- path不可省略
- 无devserver
- 打包生成的文件皆被压缩,index.html和js等文件
package.json配置启动项
"scripts": {
"start":"npm run dev",
"dev": "webpack serve --config ./config/webpack.dev.js",
"build":"webpack --config ./config/webpack.prod.js"
},
- 项目启动(启动开发模式指令)
npm start/npm run dev
- 项目打包(生产环境打包)
npm run build
二、css处理
2.1 提取css文件为单独的文件
1. 下载包
npm i mini-css-extract-plugin -D
2. 在webpack.prod.js导入包
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
3. 将loader中use中的 "style-loader" 改为 MiniCssExtractPlugin.loader ,提取css成单独的css文件
4. plugins插件中调用
new MiniCssExtractPlugin({
filename:"staric/scc/min.css"
})
5. 重新打包 npm run build
HtmlWebpackPlugin自动引入打包的js,css资源
2.2 css兼容性问题
1. 下载包
npm i postcss postcss-loader postcss-preset-env -D
2. webpack.prod.js中loader 配置,在 use "css-loader"后 和 "less-loader" / "sass-loader" / "stylus-loader" 之间插入
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
为了使代码可读性可高,可对loader的处理样式部分进行封装
const getPostcss = (prePro) => { return [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: [ "postcss-preset-env", // 能解决大多数样式兼容性问题 ], }, }, }, prePro, ].filter(Boolean); };
- loader调用
use: getStyleLoaders("less-loader")
3. package.json 指示兼容性程度
"browserslist": [
"last 2 version",//所有浏览器只要最近的版本
"> 1%",//覆盖99%的浏览器
"no dead" //排除已经没了的
]
2.3 css压缩(压缩成一行)
- 安装插件
npm i css-minimizer-webpack-plugin -D
- webpack.prod.js引用
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
- plugins插件中调用
new CssMinimizerPlugin()
- 重新打包 npm run build
注意:
默认生产模式已经开启了:html 压缩和 js 压缩