初步体验webpack打包
webpack是一个静态资源打包工具。
它会以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。
输出的文件就是编译好的文件,就可以在浏览器段运行了。
1.初始化最简单的一个目录文件,手动创建
main.js
import count from "./js/count";
import sum from "./js/sum";
console.log(count(2,1));
console.log(sum(1,2,3,4));
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>webpack</h3>
<!-- 这里直接运行报错 浏览器不识别ES6模块化 -->
<!-- <script src="../src/main.js"></script> -->
<!-- 运行的时候改成这个路径,webpack打包好的js文件 -->
<script src="../dist/main.js"></script>
</body>
</html>
2.下载依赖
npm init -y
初始化package.json文件 修改一下 main 的路径 ./src/main.js
{
"name": "webpack_code",
"version": "1.0.0",
"description": "",
"main": "./src/main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
注意:package.json中name字段不能叫做webpack,否则下一步会报错
npm i webpack webpack-cli -D
3.启用webpack
开发模式
npx webpack ./src/main.js --mode=development
生产模式
npx webpack ./src/main.js --mode=production (生产环境会对代码压缩,文件非常小)
默认webpack会将文件打包输出到dist目录下,我们查看dist目录下文件情况就好了
npx webpack:是用来运行本地安装 webpack包的。
./src/main.js:指定webpack从main.js文件开始打包,不但会打包main.js,还会将其依赖也一起打包进来。
–mode=xxx:指定模式(环境)
webpack本身功能比较少,只能处理js资源,一旦遇到css等其他资源就会报错。
5大核心概念
1.entry(入口)
指示webpack从哪个文件开始打包
2.outpu(输出)
指示webpack打包完的文件输出到哪里去,如何命名等
3.loader(加载器)
webpack本身只能处理js、json等资源,其他资源需要借助loader,webpack才能解析
4.plugins(插件)
扩展webpack的功能
5.mode(模式)
主要由两种模式:
开发模式:development
生成模式:production
准备webpack配置文件
在项目 根目录 新建文件:webpack.config.js
const path=require('path');//nodejs核心模块,专门用来处理路径问题
module.exports={
//入口
entry:'./src/main.js', //相对路径
//输出
output:{
//文件的输出路径
//__dirname nodejs的变量,代表当前文件的文件夹目录
path:path.resolve(__dirname,'dist'),//绝对路径
//文件名
filename:'main.js'
},
//加载器
module:{
rules:[
//loader的配置
]
},
//插件
plugins:[
//plugin的配置
],
//模式
mode:'development',
}
运行打包:npx webpack
开发模式介绍
1.编译代码,使浏览器能识别运行
开发时我们有样式资源,字体图标,图片资源,html资源等,webpack默认都不能处理这些资源,所以我们要加载配置来编译这些资源
2.代码质量检查,树立代码规范
提前检查代码的一些隐患,让代码运行时能更加健壮。
提前检查代码规范和格式,统一团队编码风格,让代码更优雅美观。
官方文档
处理样式资源Css资源
(less,sass也是这样的处理步骤)
1,下载包
npm i css-loader style-loader -D
css-loader:负责将css文件编译成webpack能识别的模块
style-loader:会动态创建一个style标签,里面放置webpack中css模块内容
2. 创建一个css资源引入
main.js
import count from "./js/count";
import sum from "./js/sum";
//想要webpack打包资源,必须引入该资源
import './css/index.css'
console.log(count(2,1));
console.log(sum(1,2,3,4));
3.webpack.config.js 配置(如果有less,sass往rules里面添加即可)
处理图片资源 不需要下载和配置,如果想转换base64就需要配置一下
修改输出文件目录
处理字体图标资源
处理其他资源(比如视频,音频等等)
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
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:[
//loader的配置
{
test:/\.css$/i, //只检测.css结尾的文件
use:[ //执行顺序,从右到左(从下到上)
"style-loader", //将js中css通过创建style标签添加html文件中生效
"css-loader" //将css资源编译成commonjs的模块到js中
]
},
{
test: /\.less$/i,
use: [
// 使用多个loader
'style-loader',
'css-loader',
'less-loader', //将less编译成css文件
],
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
generator:{
//输出图片名称
//[hash:10] hash值取前10位
filename:"static/images/[hash:10][ext][query]"
}
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
generator:{
//输出名称
filename:"static/media/[hash:10][ext][query]"
}
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
// options:{
// presets:["@babel/preset-env"]
// }
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"src"),
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"public/index.html")
})
],
//开发服务器:不会输出资源,在内存中编译打包
devServer:{
host:'localhost',//启动服务器域名
port:'3000',//启动服务器端口
open:true,//是否自动打开浏览器
},
//模式
mode:'development',
}
eslint使用
它是用来检测js和jsx语法的工具,可以配置各项功能
使用eslint,关键是写eslint配置文件,里面写上各种rules规则,将来运行eslint时就会以写的规则对代码进行检查
配置文件由很多种写法:
.eslintrc.*:新建文件,位于项目根目录
配置说明
1.下载包
npm i eslint-webpack-plugin eslint -D
vscode可以安装一个插件 ESLint
安装了这个插件就需要在配置一个文件 .eslintignore
忽略dist文件,里面的不检查
dist
2.定义.eslintrc.js 配置文件
module.exports={
//继承Eslint规则
extends:['eslint:recommended'],
env:{
node:true,//启用node中全局变量
browser:true,//启用浏览器中全局变量
},
parserOptions:{
ecmaVersion:6, //语法环境ES6
sourceType:'module' //es module
},
rules:{
"no-var":2 ,//不能使用var定义变量
}
}
babel使用
主要用于将ES6语法编写的代码转换为向后兼容的JavaScript语法,以便能够运行在当前和旧版本的浏览器或其他环境中
1.下载
npm i babel-loader @babel/core @babel/preset-env -D
2.定义babel配置文件 babel.config.js
module.exports={
//智能预设,能够编译ES6语法
presets:["@babel/preset-env"]
}
处理html资源
1.下载
npm install --save-dev html-webpack-plugin
2.引入
const HtmlWebpackPlugin=require('html-webpack-plugin')
自动化
每次写完代码都需要手动输入指令才能编译代码,太麻烦,希望一切自动化
1.下载
npm i webpack-dev-server -D
2.配置 webpack.config.js
//开发服务器:不会输出资源,在内存中编译打包
devServer:{
host:'localhost',//启动服务器域名
port:'3000',//启动服务器端口
open:true,//是否自动打开浏览器
},
3.运行
npx webpack serve
生产模式
生产模式是开发完成代码后,需要得到代码将来部署上线
主要对代码进行优化,让其运行性能更好。
1,优化代码运行性能
2,优化代码打包速度
准备两个配置文件来放不同的配置
webpack.dev.js 文件
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports={
//入口
entry:'./src/main.js', //相对路径
//输出
output:{
//所有文件的输出路径
//开发模式没有输出
path:undefined,
//入口文件打包输出文件名
filename:'static/js/main.js',
},
//加载器
module:{
rules:[
//loader的配置
{
test:/\.css$/i, //只检测.css结尾的文件
use:[ //执行顺序,从右到左(从下到上)
"style-loader", //将js中css通过创建style标签添加html文件中生效
"css-loader" //将css资源编译成commonjs的模块到js中
]
},
{
test: /\.less$/i,
use: [
// 使用多个loader
'style-loader',
'css-loader',
'less-loader', //将less编译成css文件
],
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
generator:{
//输出图片名称
//[hash:10] hash值取前10位
filename:"static/images/[hash:10][ext][query]"
}
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
generator:{
//输出名称
filename:"static/media/[hash:10][ext][query]"
}
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
// options:{
// presets:["@babel/preset-env"]
// }
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
})
],
//开发服务器:不会输出资源,在内存中编译打包
devServer:{
host:'localhost',//启动服务器域名
port:'3000',//启动服务器端口
open:true,//是否自动打开浏览器
},
//模式
mode:'development',
}
运行
npx webpack serve --config ./config/webpack.dev.js
webpack.prod.js 文件
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
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:[
//loader的配置
{
test:/\.css$/i, //只检测.css结尾的文件
use:[ //执行顺序,从右到左(从下到上)
"style-loader", //将js中css通过创建style标签添加html文件中生效
"css-loader" //将css资源编译成commonjs的模块到js中
]
},
{
test: /\.less$/i,
use: [
// 使用多个loader
'style-loader',
'css-loader',
'less-loader', //将less编译成css文件
],
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
generator:{
//输出图片名称
//[hash:10] hash值取前10位
filename:"static/images/[hash:10][ext][query]"
}
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
generator:{
//输出名称
filename:"static/media/[hash:10][ext][query]"
}
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
// options:{
// presets:["@babel/preset-env"]
// }
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
})
],
//模式
mode:'production',
}
打包
npx webpack --config ./config/webpack.prod.js
简化运行代码的长度 配置 package.json
"scripts": {
"start":"npm run dev",
"dev": "webpack serve --config ./config/webpack.dev.js",
"build":"webpack --config ./config/webpack.prod.js"
},
提取css成单独文件
css文件目前被打包到js文件中,当js文件加载时,会创建一个style标签来生成样式
这样对于网站来说,会出现闪屏现象,用户体验不好
应该是单独的css文件,通过link标签加载性能才好
1.下载
npm i mini-css-extract-plugin -D
2.配置webpack.prod.js文件
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-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:[
//loader的配置
{
test:/\.css$/i, //只检测.css结尾的文件
use:[ //执行顺序,从右到左(从下到上)
MiniCssExtractPlugin.loader, //提取css成单独文件
"css-loader" //将css资源编译成commonjs的模块到js中
]
},
{
test: /\.less$/i,
use: [
// 使用多个loader
MiniCssExtractPlugin.loader, //提取css成单独文件
'css-loader',
'less-loader', //将less编译成css文件
],
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
generator:{
//输出图片名称
//[hash:10] hash值取前10位
filename:"static/images/[hash:10][ext][query]"
}
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
generator:{
//输出名称
filename:"static/media/[hash:10][ext][query]"
}
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
// options:{
// presets:["@babel/preset-env"]
// }
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
}),
new MiniCssExtractPlugin({
filename:'static/css/main.css'
})
],
//模式
mode:'production',
}
Css兼容性处理
1.下载包
npm i postcss-loader postcss postcss-preset-env -D
2.配置webpack.prod.js文件
在css-loader后面 在less-loader前面 加代码
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-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:[
//loader的配置
{
test:/\.css$/i, //只检测.css结尾的文件
use:[ //执行顺序,从右到左(从下到上)
MiniCssExtractPlugin.loader, //提取css成单独文件
"css-loader", //将css资源编译成commonjs的模块到js中
{
loader:"postcss-loader",
options:{ //配置项
postcssOptions:{
plugins:[
"postcss-preset-env",//能解决大多数兼容性问题
]
}
}
},
]
},
{
test: /\.less$/i,
use: [
// 使用多个loader
MiniCssExtractPlugin.loader, //提取css成单独文件
'css-loader',
{
loader:"postcss-loader",
options:{ //配置项
postcssOptions:{
plugins:[
"postcss-preset-env",//能解决大多数兼容性问题
]
}
}
},
'less-loader', //将less编译成css文件
],
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
generator:{
//输出图片名称
//[hash:10] hash值取前10位
filename:"static/images/[hash:10][ext][query]"
}
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
generator:{
//输出名称
filename:"static/media/[hash:10][ext][query]"
}
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
// options:{
// presets:["@babel/preset-env"]
// }
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
}),
new MiniCssExtractPlugin({
filename:'static/css/main.css'
})
],
//模式
mode:'production',
}
package.json 文件还需要做兼容那些处理
实际开发用的是这种
"browserslist":[
"last 2 version",
"> 1%",
"not dead"
]
Css压缩
1.下载包
npm i css-minimizer-webpack-plugin -D
2.配置webpack.prod.js文件
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
const CssMinimizerPlugin=require("css-minimizer-webpack-plugin")
//定义一个函数抽取重复的代码 用来获取处理样式的loader
function getStyleLoader(pre){
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:[
//loader的配置
{
test:/\.css$/i, //只检测.css结尾的文件
use:getStyleLoader(),
},
{
test: /\.less$/i,
use:getStyleLoader('less-loader'),
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
generator:{
//输出图片名称
//[hash:10] hash值取前10位
filename:"static/images/[hash:10][ext][query]"
}
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
generator:{
//输出名称
filename:"static/media/[hash:10][ext][query]"
}
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
// options:{
// presets:["@babel/preset-env"]
// }
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
}),
new MiniCssExtractPlugin({
filename:'static/css/main.css'
}),
new CssMinimizerPlugin(),
],
//模式
mode:'production',
}
html压缩
(默认生成模式已经开启了:html压缩和js压缩,不需要额外进行配置)
webpack高级配置
(其实就是进行webpack优化)
1.提升开发体验
2.提升打包构建速度
3.减少代码体积
4.优化代码运行性能
1.提升开发体验
SourceMap(源代码映射)是一个用来生成源代码与构建后代码一一映射的文件的方案。
它会生成一个xxx.map文件,里面包含源代码和构建后代码每一行,每一列的映射关系,当构建后代码出错了,会通过xxx.map文件,从构建后代码出错位置找到映射后源代码出错位置,从而让浏览器提示源代码文件出错位置,帮助我们更快的找到错误根源。
开发模式:cheap-module-source-map
优点:打包编辑速度快,只包含行映射
缺点:没有列映射
webpack.dev.js
//模式
mode:'development',
devtool:"cheap-module-source-map"
生产模式:source-map
优点:包含行/列映射
缺点:打包编辑速度更慢
webpack.prod.js
//模式
mode:'production',
devtool:"source-map"
2.提升打包构建速度
HotModuleReplacement(HMR/热模块替换):在程序运行中,替换,添加或删除模块,而无需重新加载整个页面。
基本配置 webpack.dev.js
//开发服务器:不会输出资源,在内存中编译打包
devServer:{
host:"localhost",//启动服务器域名
port:"3000", //启动服务器端口号
open:true,//是否自动打开浏览器
hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
},
此时css样式经过style-loader处理,已经具备HMR功能了,但是js还不行。
main.js
import count from "./js/count";
import sum from "./js/sum";
//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));
if(module.hot){
//判断是否支持热模块替换功能
module.hot.accept("./js/count")
module.hot.accept("./js/sum")
}
上面这样写很麻烦,所以实际开发我们会使用其他loader来解决(比如:vue-loader,react-hot-loader)
oneOf(就是只能匹配上一个loader,剩下的就不匹配了)
include/exclude(包含/排除)两者只能存在一个
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
//include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
// options:{
// presets:["@babel/preset-env"]
// }
}
cache(对Eslint检查和Babel编译结果进行缓存)
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
//include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
// presets:["@babel/preset-env"]
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
}
}
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache") //指定缓存文件
}),
thead(多进程打包,开启电脑的多个进程同时干一件事,速度更快)
需要注意:请仅在特别耗时的操作中使用,因为每个进程启动就有大约为600ms左右开销。
我们启动进程的数量就是我们CPU的核数。
1.如何获取CPU的核数,因为每个电脑都不一样
//nodejs核心模块,直接使用
const os=require('os');
//cpu核数
const threads=os.cpus().length;
2.下载包
npm i thread-loader -D
3.配置
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
//include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
use:[
{
loader:"thread-loader", //开启多进程
options:{
works:threads, //进程数量
}
},
{
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
// presets:["@babel/preset-env"]
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
}
}
]
}
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache"), //指定缓存文件
threads,//开启多进程和设置进程数量
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
}),
new MiniCssExtractPlugin({
filename:'static/css/main.css'
}),
// new CssMinimizerPlugin(),
// new TerserWebpackPlugin({
// parallel:threads,//开启多进程和设置进程数量
// })
],
optimization:{
//压缩的操作
minimizer:[
//压缩css
new CssMinimizerPlugin(),
//压缩js
new TerserWebpackPlugin({
parallel:threads,//开启多进程和设置进程数量
})
]
},
3.减少代码体积
tree Shaking(用于描述移除js中的没有使用上的代码)
webpack已经默认开启了这个功能,无需其他配置
注意:它依赖 ES模块化
babel
1.下载包
npm i @babel/plugin-transform-runtime -D
@babel/plugin-transform-runtime(禁用了Babel自动对每个文件的runtime注入,而是引入,并且使所有辅助代码从这里引用)
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
//include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
use:[
{
loader:"thread-loader", //开启多进程
options:{
works:threads, //进程数量
}
},
{
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
// presets:["@babel/preset-env"]
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
plugins:['@babel/plugin-transform-runtime'],//减少代码体积
}
}
]
}
image Minimizer(用来压缩图片的插件)
注意:如果项目中图片都是在线连接,那么就不需要了,本地项目静态图片才需要进行压缩
1.下载包
npm i image-minimizer-webpack-plugin imagemin -D
还有剩下包需要下载,有两种模式:
无损压缩
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
有损压缩
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo -D
注意:有时候网络问题,需要多下载几次,不然就使用翻墙软件下载
2.配置,以无损压缩配置为例 打包的时候报错 不知道啥问题导致的
optimization:{
//压缩的操作
minimizer:[
//压缩css
new CssMinimizerPlugin(),
//压缩js
new TerserWebpackPlugin({
parallel:threads,//开启多进程和设置进程数量
}),
//压缩图片
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[
"svgo",
{
plugins: [
"preset-default",
"prefixIds",
{
name: "sortAttrs",
params: {
xmlnsOrder: "alphabetical",
},
},
],
},
],
],
},
},
}),
]
},
4.优化代码运行性能
code split(代码分割)
1.分割文件:将打包生成的文件进行分割,生成多个js文件
单入口
optimization:{
//压缩的操作
minimizer:[
//压缩css
new CssMinimizerPlugin(),
//压缩js
new TerserWebpackPlugin({
parallel:threads,//开启多进程和设置进程数量
}),
],
//代码分割配置
splitChunks:{
chunks:"all",
//其他都用默认值
}
},
2.按需加载:需要哪个文件就加载哪个文件。
main.js 动态引入按需加载
import count from "./js/count";
import sum from "./js/sum";
//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));
document.getElementById('btn').onclick=function(){
//动态引入按需加载
//eslint不能识别动态导入需要,需要额外追加配置
import("./js/math").then(({mul})=>{
console.log(mul(3,1));
})
}
if(module.hot){
//判断是否支持热模块替换功能
module.hot.accept("./js/count")
module.hot.accept("./js/sum")
}
.eslintrc.js 解决动态语法导入报错
module.exports={
//继承Eslint规则
extends:['eslint:recommended'],
env:{
node:true,//启用node中全局变量
browser:true,//启用浏览器中全局变量
},
parserOptions:{
ecmaVersion:6, //语法环境ES6
sourceType:'module' //es module
},
rules:{
"no-var":2 ,//不能使用var定义变量
},
plugins:['import'] //解决动态语法导入报错
}
给模块命名
1.main.js
import count from "./js/count";
import sum from "./js/sum";
//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));
document.getElementById('btn').onclick=function(){
//动态引入按需加载
//eslint不能识别动态导入需要,需要额外追加配置
// /* webpackChunkName:"math" */ webpack魔法命名
import(/* webpackChunkName:"math" */ "./js/math").then(({mul})=>{
console.log(mul(3,1));
})
}
if(module.hot){
//判断是否支持热模块替换功能
module.hot.accept("./js/count")
module.hot.accept("./js/sum")
}
2.配置webpack.prod.js文件
//输出
output:{
//所有文件的输出路径
//__dirname nodejs的变量,代表当前文件的文件夹目录
path:path.resolve(__dirname,'../dist'),//绝对路径
//入口文件打包输出文件名
filename:'static/js/main.js',
//给打包输出的其他文件命名
chunkFilename:"static/js/[name].js",
//原理,在打包前,将path整个目录内容清空,再进行打包
clean:true, //自动清空上次打包内容
},
统一命名 webpack.prod.js
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=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 TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
//nodejs核心模块,直接使用
const os=require('os');
//cpu核数
const threads=os.cpus().length;
//定义一个函数抽取重复的代码 用来获取处理样式的loader
function getStyleLoader(pre){
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/[name].js',
//给打包输出的其他文件命名
chunkFilename:"static/js/[name].chunk.js",
//图片,字体等通过type:asset处理资源命名方式
assetModuleFilename:"static/media/[hash:10][ext][query]",
//原理,在打包前,将path整个目录内容清空,再进行打包
clean:true, //自动清空上次打包内容
},
//加载器
module:{
rules:[
//loader的配置
{
//每个文件只能被其中一个loader配置处理
oneOf:[
{
test:/\.css$/i, //只检测.css结尾的文件
use:getStyleLoader(),
},
{
test: /\.less$/i,
use:getStyleLoader('less-loader'),
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
// generator:{
// //输出图片名称
// //[hash:10] hash值取前10位
// filename:"static/images/[hash:10][ext][query]"
// }
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
// generator:{
// //输出名称
// filename:"static/media/[hash:10][ext][query]"
// }
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
//include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
use:[
{
loader:"thread-loader", //开启多进程
options:{
works:threads, //进程数量
}
},
{
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
// presets:["@babel/preset-env"]
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
plugins:['@babel/plugin-transform-runtime'],//减少代码体积
}
}
]
}
]
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache"), //指定缓存文件
threads,//开启多进程和设置进程数量
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
}),
new MiniCssExtractPlugin({
filename:'static/css/[name].css',
chunkFilename:'static/css/[name].chunk.css'
}),
// new CssMinimizerPlugin(),
// new TerserWebpackPlugin({
// parallel:threads,//开启多进程和设置进程数量
// })
],
optimization:{
//压缩的操作
minimizer:[
//压缩css
new CssMinimizerPlugin(),
//压缩js
new TerserWebpackPlugin({
parallel:threads,//开启多进程和设置进程数量
}),
//压缩图片 以下代码打包报错 不知道哪里问题
// new ImageMinimizerPlugin({
// minimizer: {
// implementation: ImageMinimizerPlugin.imageminGenerate,
// options: {
// plugins: [
// ["gifsicle", { interlaced: true }],
// ["jpegtran", { progressive: true }],
// ["optipng", { optimizationLevel: 5 }],
// [
// "svgo",
// {
// plugins: [
// "preset-default",
// "prefixIds",
// {
// name: "sortAttrs",
// params: {
// xmlnsOrder: "alphabetical",
// },
// },
// ],
// },
// ],
// ],
// },
// },
// }),
],
//代码分割配置
splitChunks:{
chunks:"all",
//其他都用默认值
}
},
//模式
mode:'production',
devtool:"source-map"
}
preload(告诉浏览器立即加载资源) / prefetch(告诉浏览器在空闲时才开始加载资源)
共同点: 都只会加载资源,并不执行。都有缓存
区别:preload加载优先级高,prefetch加载优先级低。
preload只能加载当前页面需要使用的资源,prefetch可以加载当前页面资源,也可以加载下一个页面需要使用的资源。
下载包
npm install --save-dev @vue/preload-webpack-plugin
const PreloadWebpackPlugin=require("@vue/preload-webpack-plugin")
//插件
plugins:[
new PreloadWebpackPlugin({
// rel:'preload',
// as:'script',
rel:'prefetch',
})
],
core-js(是专门用来做ES6以及以上的API的polyfill(垫片/补丁,就是用社区上提供的一段代码,让我们在不兼容某些新特性的浏览器上,使用该新特性))
下载包
npm i core-js
main.js
import count from "./js/count";
import sum from "./js/sum";
//完整引入
// import 'core-js'
//按需加载
// import 'core-js/es/promise'
//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));
document.getElementById('btn').onclick=function(){
//动态引入按需加载
//eslint不能识别动态导入需要,需要额外追加配置
// /* webpackChunkName:"math" */ webpack魔法命名
import(/* webpackChunkName:"math" */ "./js/math").then(({mul})=>{
console.log(mul(3,1));
})
}
if(module.hot){
//判断是否支持热模块替换功能
module.hot.accept("./js/count")
module.hot.accept("./js/sum")
}
new Promise((resolve)=>{
setTimeout(()=>{
resolve();
},1000)
})
自动引入
文档
babel.config.js
module.exports={
//智能预设,能够编译ES6语法
presets:[
[
"@babel/preset-env",
{
useBuiltIns:'usage',//按需加载自动引入
corejs:3
}
]
]
}
PWA(渐进式网络应用程序,在离线时应用程序能够继续运行功能) 兼容性比较差
下载包
npm i workbox-webpack-plugin -D
文档
配置main.js
import count from "./js/count";
import sum from "./js/sum";
//完整引入
// import 'core-js'
//按需加载
// import 'core-js/es/promise'
//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));
document.getElementById('btn').onclick=function(){
//动态引入按需加载
//eslint不能识别动态导入需要,需要额外追加配置
// /* webpackChunkName:"math" */ webpack魔法命名
import(/* webpackChunkName:"math" */ "./js/math").then(({mul})=>{
console.log(mul(3,1));
})
}
if(module.hot){
//判断是否支持热模块替换功能
module.hot.accept("./js/count")
module.hot.accept("./js/sum")
}
new Promise((resolve)=>{
setTimeout(()=>{
resolve();
},1000)
})
const arr=[1,2,3,4];
console.log(arr.includes(1));
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
//插件
plugins:[
new WorkboxPlugin.GenerateSW({
//这些选项帮助快速启用 ServiceWorkers
//不允许遗留任何‘旧的’ ServiceWorkers
clientsClaim:true,
skipWaiting:true
})
],
npm i serve -g 全局安装
serve dist 运行
Notwork——》开启 Offline 离线环境 看效果
webpack.prod.js完整代码
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=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 TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
const PreloadWebpackPlugin=require("@vue/preload-webpack-plugin")
const WorkboxPlugin=require('workbox-webpack-plugin')
//nodejs核心模块,直接使用
const os=require('os');
//cpu核数
const threads=os.cpus().length;
//定义一个函数抽取重复的代码 用来获取处理样式的loader
function getStyleLoader(pre){
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/[name].js',
//给打包输出的其他文件命名
chunkFilename:"static/js/[name].chunk.js",
//图片,字体等通过type:asset处理资源命名方式
assetModuleFilename:"static/media/[hash:10][ext][query]",
//原理,在打包前,将path整个目录内容清空,再进行打包
clean:true, //自动清空上次打包内容
},
//加载器
module:{
rules:[
//loader的配置
{
//每个文件只能被其中一个loader配置处理
oneOf:[
{
test:/\.css$/i, //只检测.css结尾的文件
use:getStyleLoader(),
},
{
test: /\.less$/i,
use:getStyleLoader('less-loader'),
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
// generator:{
// //输出图片名称
// //[hash:10] hash值取前10位
// filename:"static/images/[hash:10][ext][query]"
// }
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
// generator:{
// //输出名称
// filename:"static/media/[hash:10][ext][query]"
// }
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
//include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
use:[
{
loader:"thread-loader", //开启多进程
options:{
works:threads, //进程数量
}
},
{
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
// presets:["@babel/preset-env"]
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
plugins:['@babel/plugin-transform-runtime'],//减少代码体积
}
}
]
}
]
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache"), //指定缓存文件
threads,//开启多进程和设置进程数量
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
}),
new MiniCssExtractPlugin({
filename:'static/css/[name].css',
chunkFilename:'static/css/[name].chunk.css'
}),
// new CssMinimizerPlugin(),
// new TerserWebpackPlugin({
// parallel:threads,//开启多进程和设置进程数量
// })
new PreloadWebpackPlugin({
// rel:'preload',
// as:'script',
rel:'prefetch',
}),
new WorkboxPlugin.GenerateSW({
//这些选项帮助快速启用 ServiceWorkers
//不允许遗留任何‘旧的’ ServiceWorkers
clientsClaim:true,
skipWaiting:true
})
],
optimization:{
//压缩的操作
minimizer:[
//压缩css
new CssMinimizerPlugin(),
//压缩js
new TerserWebpackPlugin({
parallel:threads,//开启多进程和设置进程数量
}),
//压缩图片 以下代码打包报错 不知道哪里问题
// new ImageMinimizerPlugin({
// minimizer: {
// implementation: ImageMinimizerPlugin.imageminGenerate,
// options: {
// plugins: [
// ["gifsicle", { interlaced: true }],
// ["jpegtran", { progressive: true }],
// ["optipng", { optimizationLevel: 5 }],
// [
// "svgo",
// {
// plugins: [
// "preset-default",
// "prefixIds",
// {
// name: "sortAttrs",
// params: {
// xmlnsOrder: "alphabetical",
// },
// },
// ],
// },
// ],
// ],
// },
// },
// }),
],
//代码分割配置
splitChunks:{
chunks:"all",
//其他都用默认值
},
runtimeChunk:{
name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
}
},
//模式
mode:'production',
devtool:"source-map"
}
webpack.dev.js完整代码
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
//nodejs核心模块,直接使用
const os=require('os');
//cpu核数
const threads=os.cpus().length;
module.exports={
//入口
entry:'./src/main.js', //相对路径
//输出
output:{
//所有文件的输出路径
//__dirname nodejs的变量,代表当前文件的文件夹目录
path:path.resolve(__dirname,'../dist'),//绝对路径
//入口文件打包输出文件名
filename:'static/js/[name].js',
//给打包输出的其他文件命名
chunkFilename:"static/js/[name].chunk.js",
//图片,字体等通过type:asset处理资源命名方式
assetModuleFilename:"static/media/[hash:10][ext][query]",
//原理,在打包前,将path整个目录内容清空,再进行打包
clean:true, //自动清空上次打包内容
},
//加载器
module:{
rules:[
//loader的配置
{
//每个文件只能被其中一个loader配置处理
oneOf:[
{
test:/\.css$/i, //只检测.css结尾的文件
use:[ //执行顺序,从右到左(从下到上)
"style-loader", //将js中css通过创建style标签添加html文件中生效
"css-loader" //将css资源编译成commonjs的模块到js中
]
},
{
test: /\.less$/i,
use: [
// 使用多个loader
'style-loader',
'css-loader',
'less-loader', //将less编译成css文件
],
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
// generator:{
// //输出图片名称
// //[hash:10] hash值取前10位
// filename:"static/images/[hash:10][ext][query]"
// }
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
// generator:{
// //输出名称
// filename:"static/media/[hash:10][ext][query]"
// }
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
//include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
use:[
{
loader:"thread-loader", //开启多进程
options:{
works:threads, //进程数量
}
},
{
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
// presets:["@babel/preset-env"]
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
plugins:['@babel/plugin-transform-runtime'],//减少代码体积
}
}
]
}
]
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache"), //指定缓存文件
threads,//开启多进程和设置进程数量
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
})
],
//开发服务器:不会输出资源,在内存中编译打包
devServer:{
host:"localhost",//启动服务器域名
port:"3000", //启动服务器端口号
open:true,//是否自动打开浏览器
hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
},
//模式
mode:'development',
devtool:"cheap-module-source-map",
}
vueCli开发模式配置vue3
npm init -y
安装
npm install -D vue-loader vue-template-compiler
配置webpack.dev.js 开发模式
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const {DefinePlugin} =require("webpack")
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const { VueLoaderPlugin}=require('vue-loader')
//定义一个函数抽取重复的代码 用来获取处理样式的loader
function getStyleLoader(pre){
return [ //执行顺序,从右到左(从下到上)
"vue-style-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:undefined,//绝对路径
//入口文件打包输出文件名
filename:'static/js/[name].js',
//给打包输出的其他文件命名
chunkFilename:"static/js/[name].chunk.js",
//图片,字体等通过type:asset处理资源命名方式
assetModuleFilename:"static/media/[hash:10][ext][query]"
},
//加载器
module:{
rules:[
//loader的配置
{
test:/\.css$/, //只检测.css结尾的文件
use:getStyleLoader(),
},
{
test: /\.less$/,
use:getStyleLoader('less-loader'),
},
{
test: /\.s[ac]ss$/,
use:getStyleLoader('sass-loader'),
},
{
test: /\.styl$/,
use:getStyleLoader('stylus-loader'),
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
}
},
{
test:/\.vue$/,
loader:'vue-loader'
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/.eslintcache"), //指定缓存文件
}),
new HtmlWebpackPlugin({
//模板。以public/index.html文件创建新的html文件
//新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
template:path.resolve(__dirname,"../public/index.html")
}),
new VueLoaderPlugin(),
//定义环境变量 cross-env定义的环境变量给打包工具使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
],
//开发服务器:不会输出资源,在内存中编译打包
devServer:{
host:"localhost",//启动服务器域名
port:"4000", //启动服务器端口号
open:true,//是否自动打开浏览器
hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
historyApiFallback:true, //解决前端路由刷新404问题
},
optimization:{
//代码分割配置
splitChunks:{
chunks:"all",
//其他都用默认值
},
runtimeChunk:{
name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
}
},
//webpack解析模块加载选项
resolve:{
//自动补全文件扩展名
extensions:['.js','.json','.vue']
},
//模式
mode:'development',
devtool:"cheap-module-source-map",
}
安装依赖
npm i eslint-webpack-plugin html-webpack-plugin vue-style-loader css-loader postcss-loader postcss-preset-env -D
npm i less-loader sass-loader sass stylus-loader babel-loader vue-loader webpack webpack-cli webpack-dev-server -D
.eslintrc.js 配置
module.exports={
root:true,
env:{
node:true,
},
extends:['plugin:vue/vue3-essential','eslint:recommended'],
parserOptions:{
parser:'@babel/eslint-parser'
}
};
npm i @babel/eslint-parser -D
babel.config.js 配置
module.exports={
presets:["@vue/cli-plugin-babel/preset"]
}
npm i @vue/cli-plugin-babel -D
npm i vue (默认是vue3的版本)
npm i cross-env -D
npm i eslint-plugin-vue -D
npm i vue-router
生产模式 webpack.prod.js
npm i mini-css-extract-plugin css-minimizer-webpack-plugin copy-webpack-plugin -D
下载图片
npm i image-minimizer-webpack-plugin imagemin -D
无损下载
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
不知道为什么,下载图片老是下载失败
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=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 TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
const CopyPlugin=require('copy-webpack-plugin')
const { VueLoaderPlugin}=require('vue-loader')
const {DefinePlugin} =require("webpack")
//定义一个函数抽取重复的代码 用来获取处理样式的loader
function getStyleLoader(pre){
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/[name].[contenthash:10].js',
//给打包输出的其他文件命名
chunkFilename:"static/js/[name].[contenthash:10].chunk.js",
//图片,字体等通过type:asset处理资源命名方式
assetModuleFilename:"static/media/[hash:10][ext][query]",
//原理,在打包前,将path整个目录内容清空,再进行打包
clean:true, //自动清空上次打包内容
},
//加载器
module:{
rules:[
//loader的配置
{
test:/\.css$/, //只检测.css结尾的文件
use:getStyleLoader(),
},
{
test: /\.less$/,
use:getStyleLoader('less-loader'),
},
{
test: /\.s[ac]ss$/,
use:getStyleLoader('sass-loader'),
},
{
test: /\.styl$/,
use:getStyleLoader('stylus-loader'),
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
}
},
{
test:/\.vue$/,
loader:'vue-loader'
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/.eslintcache"), //指定缓存文件
}),
new HtmlWebpackPlugin({
template:path.resolve(__dirname,"../public/index.html")
}),
new MiniCssExtractPlugin({
filename:'static/css/[name].[contenthash:10].css',
chunkFilename:'static/css/[name].[contenthash:10].chunk.css'
}),
new CopyPlugin({
patterns:[
{
from:path.resolve(__dirname,"../public"),
to:path.resolve(__dirname,"../dist"),
globOptions:{
//忽略index.html文件
ignore:["**/index.html"]
}
}
]
}),
new VueLoaderPlugin(),
//定义环境变量 cross-env定义的环境变量给打包工具使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
],
optimization:{
//压缩的操作
minimizer:[
//压缩css
new CssMinimizerPlugin(),
//压缩js
new TerserWebpackPlugin(),
//压缩图片 以下代码打包报错 不知道哪里问题
// new ImageMinimizerPlugin({
// minimizer: {
// implementation: ImageMinimizerPlugin.imageminGenerate,
// options: {
// plugins: [
// ["gifsicle", { interlaced: true }],
// ["jpegtran", { progressive: true }],
// ["optipng", { optimizationLevel: 5 }],
// [
// "svgo",
// {
// plugins: [
// "preset-default",
// "prefixIds",
// {
// name: "sortAttrs",
// params: {
// xmlnsOrder: "alphabetical",
// },
// },
// ],
// },
// ],
// ],
// },
// },
// }),
],
//代码分割配置
splitChunks:{
chunks:"all",
//其他都用默认值
},
runtimeChunk:{
name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
},
},
//模式
mode:'production',
devtool:"source-map",
//webpack解析模块加载选项
resolve:{
//自动补全文件扩展名
extensions:['.js','.json','.vue']
},
}
package.json
"scripts": {
"start": "npm run dev",
"dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.dev.js",
"build": "cross-env NODE_ENV=production webpack --config ./config/webpack.prod.js"
},
合并配置
webpack.config.js
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=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 TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
const CopyPlugin=require('copy-webpack-plugin')
const { VueLoaderPlugin}=require('vue-loader')
const {DefinePlugin} =require("webpack")
const isProduction=process.env.NODE_ENV==='production';
//定义一个函数抽取重复的代码 用来获取处理样式的loader
function getStyleLoader(pre){
return [ //执行顺序,从右到左(从下到上)
isProduction ? MiniCssExtractPlugin.loader : 'vue-style-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:isProduction ? path.resolve(__dirname,'../dist') : undefined,//绝对路径
//入口文件打包输出文件名
filename:isProduction ? 'static/js/[name].[contenthash:10].js' : 'static/js/[name].js',
//给打包输出的其他文件命名
chunkFilename:isProduction ? "static/js/[name].[contenthash:10].chunk.js":"static/js/[name].chunk.js",
//图片,字体等通过type:asset处理资源命名方式
assetModuleFilename:"static/media/[hash:10][ext][query]",
//原理,在打包前,将path整个目录内容清空,再进行打包
clean:true, //自动清空上次打包内容
},
//加载器
module:{
rules:[
//loader的配置
{
test:/\.css$/, //只检测.css结尾的文件
use:getStyleLoader(),
},
{
test: /\.less$/,
use:getStyleLoader('less-loader'),
},
{
test: /\.s[ac]ss$/,
use:getStyleLoader('sass-loader'),
},
{
test: /\.styl$/,
use:getStyleLoader('stylus-loader'),
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
}
},
{
test:/\.vue$/,
loader:'vue-loader'
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/.eslintcache"), //指定缓存文件
}),
new HtmlWebpackPlugin({
template:path.resolve(__dirname,"../public/index.html")
}),
isProduction && new MiniCssExtractPlugin({
filename:'static/css/[name].[contenthash:10].css',
chunkFilename:'static/css/[name].[contenthash:10].chunk.css'
}),
isProduction && new CopyPlugin({
patterns:[
{
from:path.resolve(__dirname,"../public"),
to:path.resolve(__dirname,"../dist"),
globOptions:{
//忽略index.html文件
ignore:["**/index.html"]
}
}
]
}),
new VueLoaderPlugin(),
//定义环境变量 cross-env定义的环境变量给打包工具使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
})
].filter(Boolean),
optimization:{
minimize:isProduction,
//压缩的操作
minimizer:[
//压缩css
new CssMinimizerPlugin(),
//压缩js
new TerserWebpackPlugin(),
//压缩图片 以下代码打包报错 不知道哪里问题
// new ImageMinimizerPlugin({
// minimizer: {
// implementation: ImageMinimizerPlugin.imageminGenerate,
// options: {
// plugins: [
// ["gifsicle", { interlaced: true }],
// ["jpegtran", { progressive: true }],
// ["optipng", { optimizationLevel: 5 }],
// [
// "svgo",
// {
// plugins: [
// "preset-default",
// "prefixIds",
// {
// name: "sortAttrs",
// params: {
// xmlnsOrder: "alphabetical",
// },
// },
// ],
// },
// ],
// ],
// },
// },
// }),
],
//代码分割配置
splitChunks:{
chunks:"all",
//其他都用默认值
},
runtimeChunk:{
name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
},
},
//模式
mode:isProduction ? 'production' :'development',
devtool:isProduction ? "source-map" :"cheap-module-source-map",
//webpack解析模块加载选项
resolve:{
//自动补全文件扩展名
extensions:['.js','.json','.vue']
},
//开发服务器:不会输出资源,在内存中编译打包
devServer:{
host:"localhost",//启动服务器域名
port:"4000", //启动服务器端口号
open:true,//是否自动打开浏览器
hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
historyApiFallback:true, //解决前端路由刷新404问题
},
}
package.json
"scripts": {
"start": "npm run dev",
"dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.config.js",
"build": "cross-env NODE_ENV=production webpack --config ./config/webpack.config.js"
},
优化配置
npm install element-plus --save
按需引入
npm install -D unplugin-vue-components unplugin-auto-import
报错解决
报错 1:AutoImport is not a function
解决:是 unplugin-auto-import版本高了,我用的0.17.3。后面降版本,改成0.16.7,这个问题就不报错了。
报错2:Components is not a function
解决:unplugin-vue-components 版本也高了,从0.27.0 降到了 0.25.2 ,就能正常运行了
webpack.config.js
const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=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 TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
const CopyPlugin=require('copy-webpack-plugin')
const { VueLoaderPlugin}=require('vue-loader')
const {DefinePlugin} =require("webpack")
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
const isProduction=process.env.NODE_ENV==='production';
//定义一个函数抽取重复的代码 用来获取处理样式的loader
function getStyleLoader(pre){
return [ //执行顺序,从右到左(从下到上)
isProduction ? MiniCssExtractPlugin.loader : 'vue-style-loader', //提取css成单独文件
"css-loader", //将css资源编译成commonjs的模块到js中
{
loader:"postcss-loader",
options:{ //配置项
postcssOptions:{
plugins:[
"postcss-preset-env",//能解决大多数兼容性问题
]
}
}
},
pre && {
loader:pre,
options:
pre === 'sass-loader'
? {
additionalData : `@use "@/styles/element/index.scss" as *;`,
}
: {},
},
].filter(Boolean);
}
module.exports={
//入口
entry:'./src/main.js', //相对路径
//输出
output:{
//所有文件的输出路径
//__dirname nodejs的变量,代表当前文件的文件夹目录
path:isProduction ? path.resolve(__dirname,'../dist') : undefined,//绝对路径
//入口文件打包输出文件名
filename:isProduction ? 'static/js/[name].[contenthash:10].js' : 'static/js/[name].js',
//给打包输出的其他文件命名
chunkFilename:isProduction ? "static/js/[name].[contenthash:10].chunk.js":"static/js/[name].chunk.js",
//图片,字体等通过type:asset处理资源命名方式
assetModuleFilename:"static/media/[hash:10][ext][query]",
//原理,在打包前,将path整个目录内容清空,再进行打包
clean:true, //自动清空上次打包内容
},
//加载器
module:{
rules:[
//loader的配置
{
test:/\.css$/, //只检测.css结尾的文件
use:getStyleLoader(),
},
{
test: /\.less$/,
use:getStyleLoader('less-loader'),
},
{
test: /\.s[ac]ss$/,
use:getStyleLoader('sass-loader'),
},
{
test: /\.styl$/,
use:getStyleLoader('stylus-loader'),
},
{
test:/\.(png|jpe?g|glf|webp|svg)$/,
type:"asset",
parser:{
dataUrlCondition:{
//小于10kb的图片转base64
//优点,减少请求数量,缺点,体积会更大
maxSize:10 * 1024,//10kb
}
},
},
{
test:/\.(ttf|woff2?|mp3|mp4|avi)$/, //处理字体图标资源或者其他资源
type:"asset/resource",
},
{
test:/\.js$/, //处理字体图标资源或者其他资源
include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
loader:'babel-loader',
//写这里也行,写外面babel.config.js里面也行
options:{
cacheDirectory:true,//开启babel缓存
cacheCompression:false,//关闭缓存文件压缩
}
},
{
test:/\.vue$/,
loader:'vue-loader',
options:{
//开启缓存
cacheDirectory:path.resolve(__dirname,"../node_modules/.cache/vue-loader"),
}
}
]
},
//插件
plugins:[
//plugin的配置
new ESLintPlugin({
//检测哪些文件
context:path.resolve(__dirname,"../src"),
exclude:"node_modules", //默认值
cache:true,//开启缓存
cacheLocation:path.resolve(__dirname,"../node_modules/.cache/.eslintcache"), //指定缓存文件
}),
new HtmlWebpackPlugin({
template:path.resolve(__dirname,"../public/index.html")
}),
isProduction && new MiniCssExtractPlugin({
filename:'static/css/[name].[contenthash:10].css',
chunkFilename:'static/css/[name].[contenthash:10].chunk.css'
}),
isProduction && new CopyPlugin({
patterns:[
{
from:path.resolve(__dirname,"../public"),
to:path.resolve(__dirname,"../dist"),
globOptions:{
//忽略index.html文件
ignore:["**/index.html"]
}
}
]
}),
new VueLoaderPlugin(),
//定义环境变量 cross-env定义的环境变量给打包工具使用
//DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题
new DefinePlugin({
__VUE_OPTIONS_API__:true,
__VUE_PROD_DEVTOOLS__:false
}),
//按需加载element-plus
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver({
//自定义主题,引入sass
importStyle:'sass'
})],
}),
].filter(Boolean),
optimization:{
minimize:isProduction,
//压缩的操作
minimizer:[
//压缩css
new CssMinimizerPlugin(),
//压缩js
new TerserWebpackPlugin(),
//压缩图片 以下代码打包报错 不知道哪里问题
// new ImageMinimizerPlugin({
// minimizer: {
// implementation: ImageMinimizerPlugin.imageminGenerate,
// options: {
// plugins: [
// ["gifsicle", { interlaced: true }],
// ["jpegtran", { progressive: true }],
// ["optipng", { optimizationLevel: 5 }],
// [
// "svgo",
// {
// plugins: [
// "preset-default",
// "prefixIds",
// {
// name: "sortAttrs",
// params: {
// xmlnsOrder: "alphabetical",
// },
// },
// ],
// },
// ],
// ],
// },
// },
// }),
],
//代码分割配置
splitChunks:{
chunks:"all",
//其他都用默认值
cacheGroups:{
vue:{
test:/[\\/]node_modules[\\/]vue(.*)?[\\/]/,
name:'vue-chunk',
priority:40,
},
elementPlus:{
test:/[\\/]node_modules[\\/]element-plus[\\/]/,
name:'elementPlus-chunk',
priority:30,
},
libs:{
test:/[\\/]node_modules[\\/]/,
name:'libs-chunk',
priority:20,
},
}
},
runtimeChunk:{
name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
},
},
//模式
mode:isProduction ? 'production' :'development',
devtool:isProduction ? "source-map" :"cheap-module-source-map",
//webpack解析模块加载选项
resolve:{
//自动补全文件扩展名
extensions:['.js','.json','.vue'],
//路径别名
alias:{
'@':path.resolve(__dirname,'../src'),
}
},
//开发服务器:不会输出资源,在内存中编译打包
devServer:{
host:"localhost",//启动服务器域名
port:"4000", //启动服务器端口号
open:true,//是否自动打开浏览器
hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
historyApiFallback:true, //解决前端路由刷新404问题
},
//关闭性能分析,提升打包速度
performance:false,
}
自定义主题 styles/element/index.scss
// styles/element/index.scss
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
'base': green,
),
),
);