做这些优化 主要是为了 vue第一次 加载能快一点
第一: image-webpack-loader
image-webpack-loader api使用减小图片体积
chainWebpack: (config) => {
config.module
.rule("image")
.test(/\.(png|jpe?g|gif)(\?.*)?$/)
.use("image-webpack-loader")
.loader("image-webpack-loader")
.options({
// 此处为ture的时候不会启用压缩处理,目的是为了开发模式下调试速度更快
disable: process.env.NODE_ENV == "development" ? true : false,
})
.end();
},
第二: optimization配置中 使用splitChunks插件进行代码分割,将第三方库和应用代码分离,以提升缓存效率
splitChunks: {
chunks: "all",
cacheGroups: {
vendor: {
name: "chunk-vendors",
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: "all",
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
第三: plugins中使用compression-webpack-plugin压缩体积
plugins: [
// 定义全局常量
new DefinePlugin({
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false,
}),
// 使用CompressionPlugin进行Gzip压缩
new CompressionPlugin({
filename: "[path][base].gz", // 输出文件名格式
algorithm: "gzip", // 压缩算法
test: /\.(js|css|html|svg)$/, // 需要压缩的文件类型
threshold: 10240, // 文件超过10KB才进行压缩
minRatio: 0.8, // 压缩比例
deleteOriginalAssets: false, // 不删除原始文件
}),
new BundleAnalyzerPlugin(), // 使用BundleAnalyzerPlugin进行打包分析
],
第四: optimization中做做代码分割
optimization: {
/**
* runtimeChunk可选值有:true或'multiple'或'single'
* true或'multiple'会有每个入口对应的chunk。不过一般情况下
* 考虑到要模块初始化,设置为single就够多数情况下使用啦。
* 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk
* */
runtimeChunk: "single",
/**
* 以前是CommonsChunkPlugin,现在换成optimization.splitChunks。普通项目下方的配置就足够用啦
* 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationsplitchunks
* */
splitChunks: {
chunks: "all", // 可选值:all,async 和 initial。all功能最强大,所以咱们就使用all
maxInitialRequests: Infinity, // 最大并行请求数,为了以防万一,设置无穷大即可
minSize: 20000, // 引入的模块大于20kb才做代码分割,官方默认20000,这里不用修改了
maxSize: 60000, // 若引入的模块大于60kb,则告诉webpack尝试再进行拆分
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/, // 使用正则匹配node_modules中引入的模块
priority: -10, // 优先级值越大优先级越高,默认-10,不用修改
name(module) {
// 设定分包以后的文件模块名字,按照包名字替换拼接一下
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
)[1];
return `npm.${packageName.replace("@", "")}`;
},
},
},
},
},
全部配置 提供参考
const path = require("path");
const { defineConfig } = require("@vue/cli-service");
const { DefinePlugin } = require("webpack");
const CompressionPlugin = require("compression-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const BundleAnalyzerPlugin =
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
// 配置坏境
function getProxyConfig() {
const config = {
development: {
"/Main_api": {
target: "url",
changeOrigin: true,
pathRewrite: { "^/Main_api": "" },
},
"/media": {
target: "url",
changeOrigin: true,
pathRewrite: { "^/media": "" },
},
},
};
return config[process.env.NODE_ENV] || {};
}
module.exports = defineConfig({
outputDir: process.env.NODE_ENV, // 打包后的文件名时候生成的一个文件名
publicPath: process.env.BASE_URL,
transpileDependencies: true,
productionSourceMap: false, // 关闭生产环境的Source Map,减少打包后文件的体积
pwa: {
workboxOptions: {
// 配置 service worker 略过等待,立即接管页面
skipWaiting: true,
// 配置 service worker 立即在所有客户端上生效
clientsClaim: true,
// 清理过时的缓存
cleanupOutdatedCaches: true,
},
},
chainWebpack: (config) => {
config.module
.rule("image")
.test(/\.(png|jpe?g|gif)(\?.*)?$/)
.use("image-webpack-loader")
.loader("image-webpack-loader")
.options({
// 此处为ture的时候不会启用压缩处理,目的是为了开发模式下调试速度更快
disable: process.env.NODE_ENV == "development" ? true : false,
})
.end();
},
configureWebpack: {
output: {
// 输出的 JavaScript 文件名称,带有8位内容哈希值
filename: "js/[name].[contenthash:8].js",
// 输出的分块文件名称,带有8位内容哈希值
chunkFilename: "js/[name].[contenthash:8].js",
},
resolve: {
alias: {
"ant-design-vue/es": path.resolve(
__dirname,
"node_modules/ant-design-vue/es"
),
},
extensions: [".js", ".jsx"], // 解析文件扩展名
},
optimization: {
// 使用splitChunks插件进行代码分割,将第三方库和应用代码分离,以提升缓存效率
splitChunks: {
chunks: "all",
cacheGroups: {
vendor: {
name: "chunk-vendors",
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: "all",
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
// 使用TerserPlugin进行代码压缩,并移除console语句
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // 删除所有的console.*语句
},
},
}),
],
},
plugins: [
// 定义全局常量
new DefinePlugin({
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false,
}),
// 使用CompressionPlugin进行Gzip压缩
new CompressionPlugin({
filename: "[path][base].gz", // 输出文件名格式
algorithm: "gzip", // 压缩算法
test: /\.(js|css|html|svg)$/, // 需要压缩的文件类型
threshold: 10240, // 文件超过10KB才进行压缩
minRatio: 0.8, // 压缩比例
deleteOriginalAssets: false, // 不删除原始文件
}),
new BundleAnalyzerPlugin(), // 使用BundleAnalyzerPlugin进行打包分析
],
optimization: {
/**
* runtimeChunk可选值有:true或'multiple'或'single'
* true或'multiple'会有每个入口对应的chunk。不过一般情况下
* 考虑到要模块初始化,设置为single就够多数情况下使用啦。
* 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk
* */
runtimeChunk: "single",
/**
* 以前是CommonsChunkPlugin,现在换成optimization.splitChunks。普通项目下方的配置就足够用啦
* 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationsplitchunks
* */
splitChunks: {
chunks: "all", // 可选值:all,async 和 initial。all功能最强大,所以咱们就使用all
maxInitialRequests: Infinity, // 最大并行请求数,为了以防万一,设置无穷大即可
minSize: 20000, // 引入的模块大于20kb才做代码分割,官方默认20000,这里不用修改了
maxSize: 60000, // 若引入的模块大于60kb,则告诉webpack尝试再进行拆分
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/, // 使用正则匹配node_modules中引入的模块
priority: -10, // 优先级值越大优先级越高,默认-10,不用修改
name(module) {
// 设定分包以后的文件模块名字,按照包名字替换拼接一下
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
)[1];
return `npm.${packageName.replace("@", "")}`;
},
},
},
},
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
"thread-loader", // 使用多线程加载器来加快构建速度
"babel-loader", // 使用Babel加载器来处理JavaScript文件
],
},
],
},
cache: {
type: "filesystem", // 启用持久化缓存,以加快后续的构建速度
},
},
devServer: {
port: 80, // 开发服务器端口
proxy: getProxyConfig(),
},
});