webpack 基础_优化
webpack 优化配置
dll:动态连接库
dll与external类似,指示 webpack哪些库是不参与打包的;可以单独对某些库进行单独打包,将多个库打包成一个 chunk
-
作用:将第三方库拆开打包成不同的 chunk,更利于性能优化
-
下载插件
npm i add-asset-html-webpack-plugin -D
- 修改配置
// webpack.config.js
// nodejs
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 将 css从 js中提取出来,并到单独的文件中
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// css代码压缩
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// pwa
// const WorkboxWebpackPlugin = require('workbox-webpack-plugin')
// dll
const webpack = require('webpack')
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
// 定义 nodejs环境变量:决定使用 browserslist的哪个环境
// process.env.NODE_ENV = 'production'
// process.env.NODE_ENV = 'development'
// loader复用
const commonCSSLoader = [
// 'style-loader',
// 将 css代码提取到一个指定的文件中
MiniCssExtractPlugin.loader,
/**
* 问题:
* MiniCssExtractPlugin.loader当前不能将 less文件单独提取出来放到指定的文件中
*/
// 将 css加载到 js中
'css-loader',
/**
* css兼容性处理:只能针对 css代码来操作
* postcss ->
* postcss-loader ->
* postcss-preset-env:帮助 postcss识别某些环境,加载指定的配置
*/
{
/**
* 需要在 package.json中定义 browserslist里面的配置
*/
loader: 'postcss-loader',
options: {
// 告诉它要做哪些兼容性配置
ident: 'postcss',
plugins: () => [
/**
* postcss的插件
* 帮助 postcss找到 package.json中 browserslist里面的配置,
* 通过配置加载指定的 css兼容性样式
*/
require('postcss-preset-env')(),
],
},
},
];
// commonjs
module.exports = {
// entry: ['./src/js/index.js', './src/index.html'],
entry: './src/js/index.js',
output: {
/**
* 给文件添加 hash值,防止缓存:[hash:8]
*/
filename: 'js/built.[contenthash:8].js',
path: resolve(__dirname, 'build'),
},
module: {
rules: [
{
/**
* 只检查源代码,忽略第三发库
* eslint-loader
* eslint
* 在 package.json的 eslintConfig中设置检查规则,推荐 airbnb
*/
test: /\.js$/,
exclude: /node_modules/,
// 优先执行此 loader
enforce: 'pre',
loader: 'eslint-loader',
options: {
// 自动修复 eslint错误
fix: true,
},
},
{
/**
* oneOf:提升打包构建速度,阻止每种类型的文件都被以下 loader判断一次
* 在 oneOf中的 loader只会匹配一个
* 注意:在 oneOf中不能有两个及以上的配置处理同一种类型的文件
* 如果有,需要拿到 oneOf外边处理
*/
oneOf: [
// css代码处理
{
test: /\.css$/,
use: [
...commonCSSLoader,
],
},
{
test: /\.less$/,
use: [
...commonCSSLoader,
// MiniCssExtractPlugin.loader,
// 'css-loader',
'less-loader',
],
},
/**
* 正常来讲,一个文件只能被一个 loader处理;
* 当一个文件要被多个 loader处理,那一定要指定 loader执行的先后顺序
* 如下面的 .js文件:应该先执行 eslint再执行 bable,通过 enforce属性指定
*/
// js语法检查:规范项目代码,检查常见语法错误
{
// js兼容性处理:babel-loader、@babel/preset-env、@babel/core
test: /\.js$/,
exclude: /node_modules/,
use: [
/**
* 开启多进程打包:
*/
{
loader: 'thread-loader',
options: {
workers: 2 // 规定只开启两个进程,默认是 cpu核数 - 1
}
},
{
loader: 'babel-loader',
options: {
// 预设:指示 babel做怎样的兼容处理
presets: [
[
// 只能作简单的语法兼容处理
'@babel/preset-env',
// corejs可以作复杂的语法兼容处理
{
// 按需加载
useBuiltIns: 'usage',
// 指定 core-js版本
corejs: {
version: 3,
},
// 指定兼容性做到哪个版本的浏览器
targets: {
chrome: '60',
firefox: '50',
safari: '10',
edge: '17',
ie: '9',
},
},
],
],
/**
* 开启 babel缓存
* 第二次构建时,会读取缓存,提升构建速度
*/
cacheDirectory: true
},
}
],
},
// 处理图片资源
{
test: /\.(png|gif|jpg|jpeg)$/,
loader: 'url-loader',
options: {
// 对于图片小于 8-12kb的可以进行 base64处理
limit: 8 * 1024,
// 关闭 ES6解析,使用 commonjs解析
esModule: false,
name: '[hash:10].[ext]',
outputPath: 'imgs',
},
},
// 处理 HTML中的 img资源
{
test: /\.html$/,
// 处理 HTML中的 img资源
loader: 'html-loader',
},
// 处理其它资源
{
exclude: /\.(html|js|css|less|png|gif|jpg|jpeg)/,
// 将其它资源原封不动的输出
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media',
},
},
],
}
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
// html代码压缩
minify: {
collapseWhitespace: true,
removeComments: true,
},
}),
new MiniCssExtractPlugin({
// 对提取出的 css代码放到统一的文件中,并命名
filename: 'css/built.[contenthash:8].css',
}),
// css代码压缩
new OptimizeCssAssetsWebpackPlugin(),
/**
* dll:
* webpack.DllReferencePlugin:告诉 webpack哪些库不参与打包,
* 同时使用时的名称也要变
*/
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, 'dll/manifest.json')
}),
/**
* dll的支持插件
* 将某个打包的文件引入,并在 html中自动引入该资源
*/
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, 'dll/jquery.js')
})
/**
* pwa:
* 1.帮助 serviceworker快速启动
* 2.删除旧的 serviceworker
* 最终:生成一个 serviceworker配置文件
* 然后在入口文件中注册 serviceworker
*/
// new WorkboxWebpackPlugin.GenerateSW({
// clientsClaim: true,
// skipWaiting: true
// })
],
mode: 'production',
// mode: 'development',
/**
* externals:
* 添加不被打包的第三方库
*/
// externals: {
// // 忽略的库名 -> npm包名
// jquery: 'jQuery'
// },
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 3030,
open: true,
// 开启 HRM功能
hot: true,
},
/**
* source-map的设置:
* [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
* source-map:内联
* 错误提示:错误代码准确信息和 源代码的错误位置
* inline-source-map:内联
* 1.将生成的 .map文件放在 .js文件中
* 2.只生成一个内联的 source-map文件
* 错误提示:错误代码准确信息和 源代码的错误位置
* hidden-source-map(防止源代码泄露):外联
* 1.将生成的一个 source-map文件放在单独的 .map文件中
* 错误提示:错误代码错误原因,但是没有错误位置,
* 不能追踪源代码错误,只能提示到构建后代码的错误位置
* eval-source-map:内联
* 1.针对每一个文件都生成一个单独的 source-map文件,放在 .js文件的 eval函数中
* 错误提示:错误代码准确信息 和 源代码的错误位置
* nosource-source-map(防止源代码泄露):外联
* 错误提示:错误代码准确信息, 但是没有任何源代码信息(可以防止源代码泄露)
* cheap-source-map:外联
* 错误提示:错误代码准确信息 和 源代码的错误位置,只能精确到行
* cheap-module-source-map:外联
* 错误提示:错误代码准确信息 和 源代码的错误位置,
* module会将 loader的 source-map加入
*
*/
// 开启构建后代码与源码的映射
devtool: 'eval-source-map' // development
// devtool: 'source-map' // production
};
- 添加配置文件
// webpack.dll.js
const { resolve } = require("path");
const webpack = require("webpack");
/**
* 需要添加一个配置文件
* 使用 dll技术,对指定的库(第三方库:jquery、react、vue...)进行单独打包
* 当运行 webapck指令时,默认查找的是 webpack.config.js配置文件
* 需求:需要运行 webpack.dll.js配置文件
* -> webpack --config webpack.dll.js
*/
module.exports = {
entry: {
/**
* jquery -> 最终打包生成的名字
* ['jquery'] -> 被打包的库是 jquery
*/
jquery: ['jquery']
},
output: {
// filename: '[name].[contenthash:8].js'
filename: '[name].js',
path: resolve(__dirname, 'dll'),
// library:指定打包的库里面向外暴露出去的内容叫什么名字
// 如:jquery_325221b0
library: '[name]_[hash:8]'
},
plugins: [
// webpack.DllPlugin:打包生成一个 manifest.json -> 提供和 jquery的映射关系
new webpack.DllPlugin({
// name:映射库暴露的内容名称,要与 library的一致
name: '[name]_[hash:8]',
// 指定输出文件路径
path: resolve(__dirname, 'dll/manifest.json')
})
],
mode: 'production'
}
- 运行命令:
npx webpack --config webpack.dll.js
npx webpack
webpack 性能优化总结
开发环境性能优化
主要考虑打包速度和代码调试方面
优化打包构建速度:HMR 热模块替换
当构建代码时,只会构建修改的模块,其它模块使用缓存,提升代码构建速度,使得开发体验更好
- css:经过 style-loader处理后就会有 HMR功能
- js:需要开发者自己写
- html:不需要此功能
优化代码调试:source-map
在开发环境下使得调试更加友好,要搞清楚每个值的含义,并使用推荐的写法
- 开发环境下:
- eval-source-map(推荐):速度快
- eval-cheap-module-source-map:打包信息完整
- 生产环境下:
- source-map(推荐):比较完整的映射关系
- cheap-module-source-map:速度快,信息完整
生产环境性能优化
优化打包构建速度:
oneOf:
减少 loader的的遍历,在 oneOf中,一种文件类型被对应的 loader处理后,不会被其它 loader遍历
babel缓存:
优化打包构建速度,将第一次 babel构建的结果缓存起来,在之后的打包中直接使用缓存,提升打包构架速度
多进程打包:
打包默认是单继承的,开启多进程打包可以提升打包速度;当程序较大时可以使用,因为每个进程开启大概需要 600ms
externals:
使得某些库不打包,额外使用 cdn等在 html文件中引入不打包的库
dll:
先将某些库在本地打包好,在使用的时候直接引入。
可以考虑将 dll和 code split结合,将 node_modules中的库分别打包,减少文件体积,提升速度
优化代码运行的性能
文件缓存(hash、chunkhash、contenthash)
- hash:webpack打包时,生成新的唯一 hash值
- chunkhash:webpack打包时,如果打包时是同一个入口,那就同属于一个 chunk,则 chunkhash值相同;因为 css文件和 js文件同属于一个 chunk,当 js变化后,css的 chunkhash也会变化
- contenthash:根据文件的内容生成 contenthash值;可以保证再次打包时如果文件内容不变,则 contenthash值也不变
tree shaking:
去除程序中引用了但没有使用的代码文件,减少代码体积
- 必须开启 ES6模块化
- webapck生产环境默认启动
- sideEffect[...]:声明不能删除的文件,如样式文件、babel文件...
code split:代码分割
- 单入口:引入为一个 chunk,输出为一个 bundle
- 将 bundle中的一个 总的js文件拆分为多个小的js文件
- 使用 optimization处理 node_modules文件
- 通过 import引入的文件会自动分割代码
- 多入口:多入口会引入多个 chunk,输出多个 bundle
- optimization
- import
懒加载/预加载
- 懒加载:某个 js代码刚开始不加载,需要的时候才加载;需要和 code split配合使用:异步 + code split
- 预加载(兼容性差):当需要的代码全部加载完成后,才偷偷去加载其它代码
pwa(兼容性):离线可访问技术
在离线情况下,也可以访问网站
- serviceWorker
- cach
webpack 配置详解
entry:
string: './src/index.js'
字符串单入口,打包形成一个 chunk,输出一个 bundle文件,如 built.js, 如使用 [name].js,此时 chunk使用默认名称 main.js
array: [...]
数组多入口,所有入口文件最终会形成一个 chunk,最终输出结果只有一个 bundle文件
- 作用:在 HMR功能中,让 html热更新生效
object:{...}
对象多入口,有几个入口文件就形成几个 chunk,结果就输出对应个数的 bundle文件 此时,chunk的名称就是对应的 key
特殊用法:
将 2和 3搭配使用,分别按照 2、3的规则进行打包;如 dll中的用法
webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { resolve } = require("path");
/**
* entry: 入口起点
* 1. string: './src/index.js'
* 字符串单入口,打包形成一个 chunk,输出一个 bundle文件,如 built.js,
* 如使用 [name].js,此时 chunk使用默认名称 main.js
* 2. array: [...]
* 数组多入口,所有入口文件最终会形成一个 chunk,最终输出结果只有一个 bundle文件
* 作用:在 HMR功能中,让 html热更新生效
* 3. object:{...}
* 对象多入口,有几个入口文件就形成几个 chunk,结果就输出对应个数的 bundle文件
* 此时,chunk的名称就是对应的 key
*
* 4. 特殊用法:
* 将 2和 3搭配使用,分别按照 2、3的规则进行打包;如 dll中的用法
*/
module.exports = {
// entry: './src/index.js',
// entry: [
// './src/index.js',
// './src/add.js'
// ],
// entry: {
// index: './src/index.js',
// add: './src/add.js'
// },
entry: {
index: ['./src/index.js', './src/count.js'],
add: './src/add.js'
},
output: {
filename: '[name].js',
// filename: 'built.js',
path: resolve(__dirname, 'built')
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development'
}
output:
- filename: 文件名称(指定名称 + 目录),如 'js/built.js'
- path: 输出文件目录(将来所有资源输出的公共目录)
- publicPath: 所有资源引入公共路径前缀,'imgs/a.jpg' -> 打包后 '/imgs/a.js'
- chunkFilename: 非入口文件的 chunk名称
- import异步加载
- optimization
- library: 整个库向外暴露一个全局变量 name,一般结合 dll使用
- libraryTarget: 指定向外暴露的全局变量挂载的位置
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { resolve } = require("path");
/**
* output:出口
* filename: 文件名称(指定名称 + 目录)'js/built.js'
* path: 输出文件目录(将来所有资源输出的公共目录)
* publicPath: 所有资源引入公共路径前缀,'imgs/a.jpg' -> 打包后 '/imgs/a.js'
* chunkFilename: 非入口文件的 chunk名称
* 1. import异步加载
* 2. optimization
* library: 整个库向外暴露一个全局变量 name,一般结合 dll使用
* libraryTarget: 指定向外暴露的全局变量挂载的位置
*/
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/[name].js',
// filename: 'built.js',
path: resolve(__dirname, 'built'),
publicPath: '/',
chunkFilename: 'js/[name]_chunk.js',
library: '[name]',
// browser
libraryTarget: 'window',
// node
// libraryTarget: 'global',
// 使用 commonjs的语法规则暴露全局变量
// libraryTarget: 'commonjs'
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development'
}
module:
- test
- exclude
- include
- enforce
- loader
- options
- oneOf
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { resolve } = require("path");
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/[name].js',
// filename: 'built.js',
path: resolve(__dirname, 'built'),
publicPath: '/',
chunkFilename: 'js/[name]_chunk.js',
library: '[name]',
// browser
libraryTarget: 'window',
// node
// libraryTarget: 'global',
// 使用 commonjs的语法规则暴露全局变量
// libraryTarget: 'commonjs'
},
module: {
rules: [
{
test: /\.css$/,
// 多个 loader使用数组 use
use: [
'use-loader',
'css-loader'
]
},
{
test: /\.js$/,
// 排除 node_modules下的 js文件
exclude: /node_modules/,
// 只检查 src下的 js文件
include: resolve(__dirname, 'src'),
// pre 优先执行, post 延后执行
// enforce: 'pre',
// 单个 loader使用 loader
loader: 'eslint-loader',
// options指定 loader的配置
// options: {}
},
{
// oneOf中,同种类型的 loader,只会执行一个
oneOf: []
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development'
}
resolve:
- alias: 配置解析模块路径别名
- extensions: 配置省略文件路径的后缀名
- modules: 告诉 webpack解析模块是去找哪个目录
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { resolve } = require("path");
/**
* resolve: 解析模块的规则
* 1. alias: 配置解析模块路径别名
* 2. extentions: 配置省略文件路径的后缀名
* 3. modules: 告诉 webpack解析模块是去找哪个目录
*/
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
// filename: 'built.js',
path: resolve(__dirname, 'built'),
// publicPath: '/',
chunkFilename: 'js/[name]_chunk.js',
// library: '[name]',
// browser
// libraryTarget: 'window',
// node
// libraryTarget: 'global',
// 使用 commonjs的语法规则暴露全局变量
// libraryTarget: 'commonjs'
},
module: {
rules: [
{
test: /\.css$/,
// 多个 loader使用数组 use
use: [
// 在程序运行时,可以在浏览器的控制台中看到 style
'style-loader',
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development',
resolve: {
// 配置解析模块路径别名
alias: {
$css: resolve(__dirname, 'src/css')
},
// 配置省略文件路径的后缀名
extensions: [
'.js',
'.json'
],
// 告诉 webpack解析模块是去找哪个目录
modules: [
resolve(__dirname, '../../node_modules'),
'node_modules'
]
}
}
optimization:
- splitChunks: 提取公共代码 node_modules成单独的 chunk进行单独打包
- runtimeChunk: 主要解决 splitChunks的 hash值问题
- minimizer: 配置生产环境的压缩方案:js和 css
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { resolve } = require("path");
const Terser = require('terser-webpack-plugin')
/**
* optimization: 只在 生产环境中执行
*/
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name]_[contenthash:8].js',
// filename: 'built.js',
path: resolve(__dirname, 'built'),
// publicPath: '/',
chunkFilename: 'js/[name]_[contenthash:8]_chunk.js',
// library: '[name]',
// browser
// libraryTarget: 'window',
// node
// libraryTarget: 'global',
// 使用 commonjs的语法规则暴露全局变量
// libraryTarget: 'commonjs'
},
module: {
rules: [
{
test: /\.css$/,
// 多个 loader使用数组 use
use: [
'style-loader',
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'production',
resolve: {
// 配置解析模块路径别名
alias: {
$css: resolve(__dirname, 'src/css')
},
// 配置省略文件路径的后缀名
extensions: [
'.js',
'.json'
],
// 告诉 webpack解析模块是去找哪个目录
modules: [
resolve(__dirname, '../../node_modules'),
'node_modules'
]
},
devServer: {
// 运行打包后代码的目录
contentBase: resolve(__dirname, 'build'),
// 监视 contentBase目录下的所有文件,一旦文件变化就会 reload
watchContentBase: true,
// 监视配置
watchOptions: {
// 忽略文件
ignored: /node_modules/
},
// 启动 gzip压缩,减小代码体积
compress: true,
// 端口号
port: 5000,
// 域名
host: 'localhost',
// 打开默认浏览器
open: true,
// 开启 HMR功能
hot: true,
// 日志方面的内容
// 不要显示启动服务器有关的日志信息
clientLogLevel: 'none',
// 除了一些基本启动信息外,其它内容都不要显示
quiet: true,
// 如果出错,不要全屏提示
overlay: false,
/**
* 服务器代理: 解决开发环境跨域问题
*/
proxy: {
/**
* 一旦 devServer(5000)服务器接收到 /api/xxx的请求,
* 就会自动将请求转发到另外一个服务器(3000)
*/
'/api': {
target: 'http://localhost:3000',
// 请求路径重写:/api/xxx -> /xxx 去掉 /api
pathRewrite: {
'^/api': ''
}
}
}
},
optimization: {
// 代码分割 node_modules
// 提取公共代码 node_modules成单独的 chunk进行单独打包
splitChunks: {
chunks: 'all',
/**
* 以下都为默认值:一般不用修改
*/
// 分割的 chunk最小为 30kb
minSize: 30 * 1024,
// 最大没有限制
maxSize: 0,
// 要提取的 chunk最少要被引用一次
minChunks: 1,
// 按需加载时,并行加载的文件的最大数量
maxAsyncRequests: 5,
// 入口 js文件,最大并行请求数量
maxInitialRequests: 3,
// 名称连接符
automaticNameDelimiter: '~',
// 可以使用命名规则
name: true,
cacheGroups: {
/**
* 分割 chunk的组:也满足上面个的公共规则
*/
vendors: {
// node_modules文件会被打包到 vendors组的 chunk中: vendors~xxx.js
//
test: /[\\/]node_modules[\\/]/,
// 优先级
priority: -10
},
default: {
// 要提取的 chunk最少被引用 2次
minChunks: 2,
// 优先级
priority: -20,
// 如果当前被打包的模块和之前已经被提取的模块是同一个,就会复用,解决重复打包问题
reuseExistingChunk: true,
}
}
},
/**
* runtimeChunk:主要解决 splitChunks的 hash值问题
* 将当前模块记录的其它模块的 hash值单独打包成一个文件 runtime
* 作用:防止因打包文件的 hash值改变,造成其它引用此模块的 hash值变化,避免造成缓存失效
*/
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
},
/**
* 配置生产环境的压缩方案:js和 css
*/
minimizer: [
// 4.26版之后,使用 Terser压缩替换 uglify压缩
new Terser({
// 开启缓存
cache: true,
// 开启多进程打包
parallel: true,
// 启动 source-map
sourceMap: true
})
]
}
}
devServer:
具体配置参照下面代码
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { resolve } = require("path");
/**
* devServer:
*/
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
// filename: 'built.js',
path: resolve(__dirname, 'built'),
// publicPath: '/',
chunkFilename: 'js/[name]_chunk.js',
// library: '[name]',
// browser
// libraryTarget: 'window',
// node
// libraryTarget: 'global',
// 使用 commonjs的语法规则暴露全局变量
// libraryTarget: 'commonjs'
},
module: {
rules: [
{
test: /\.css$/,
// 多个 loader使用数组 use
use: [
'style-loader',
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development',
resolve: {
// 配置解析模块路径别名
alias: {
$css: resolve(__dirname, 'src/css')
},
// 配置省略文件路径的后缀名
extensions: [
'.js',
'.json'
],
// 告诉 webpack解析模块是去找哪个目录
modules: [
resolve(__dirname, '../../node_modules'),
'node_modules'
]
},
devServer: {
// 运行打包后代码的目录
contentBase: resolve(__dirname, 'build'),
// 监视 contentBase目录下的所有文件,一旦文件变化就会 reload
watchContentBase: true,
// 监视配置
watchOptions: {
// 忽略文件
ignored: /node_modules/
},
// 启动 gzip压缩,减小代码体积
compress: true,
// 端口号
port: 5000,
// 域名
host: 'localhost',
// 打开默认浏览器
open: true,
// 开启 HMR功能
hot: true,
// 日志方面的内容
// 不要显示启动服务器有关的日志信息
clientLogLevel: 'none',
// 除了一些基本启动信息外,其它内容都不要显示
quiet: true,
// 如果出错,不要全屏提示
overlay: false,
/**
* 服务器代理: 解决开发环境跨域问题
*/
proxy: {
/**
* 一旦 devServer(5000)服务器接收到 /api/xxx的请求,
* 就会自动将请求转发到另外一个服务器(3000)
*/
'/api': {
target: 'http://localhost:3000',
// 请求路径重写:/api/xxx -> /xxx 去掉 /api
pathRewrite: {
'^/api': ''
}
}
}
}
}
webpack5:
主要是对 tree shaking的优化
module.exports = {
// entry: './src/index.js',
// output: {
// filename: '[name].js',
// path: resolve(__dirname, 'dist')
// },
/**
* 以上配置是默认的,不用配置
*/
// mode: 'development'
mode: 'production'
}