vue-cli3 dist包体积过大的解决办法

背景:项目打包后的dist包体积过大,达到了35m以上比较沉重了,需要给它瘦身减肥。

1. 使用路由懒加载
js 复制代码
{
  path: '/login',
  name: '登录页',
  component: () => import(/* webpackChunkName: "page" */ '@/page/login/index'),
}
2. 安装插件

借助webpack插件"webpack-bundle-analyzer"生成代码分析报告

js 复制代码
npm install --save-dev webpack-bundle-analyzer

vue-cli3:配置vue.config.js文件

js 复制代码
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
module.exports = {
    configureWebpack: (config) => {
           config.plugins.push(
               new BundleAnalyzerPlugin({
                    openAnalyzer: false, // 在默认浏览器中是否自动打开报告,默认 true
                })
           )
    }
}

详细配置:

js 复制代码
module.exports = {
    configureWebpack: (config) => {
            config.plugins.push(
                new BundleAnalyzerPlugin({
                    analyzerMode:'server', // 可以是 server、static、json、disabled。在server模式下,分析器将启动HTTP服务器来显示软件包报告。在"静态"模式下,会生成带有报告的单个HTML文件。在disabled模式下,你可以使用这个插件来将generateStatsFile设置为true来生成Webpack Stats JSON文件。
                    analyzerHost: '127.0.0.1', // 将在"服务器"模式下使用的端口启动HTTP服务器
                    analyzerPort: 8888, // 端口号
                    reportFilename: 'report.html', // 路径捆绑,将在static模式下生成的报告文件。相对于捆绑输出目录
                    defaultSizes: 'parsed', // 默认显示在报告中的模块大小匹配方式。应该是stat,parsed或者gzip中的一个
                    openAnalyzer: false, // 在默认浏览器中是否自动打开报告,默认 true
                    generateStatsFile: false, // 如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成
                    statsFilename: 'stats.json', // 相对于捆绑输出目录
                    statsOptions: null, //stats.toJson()方法的选项。例如,您可以使用source:false选项排除统计文件中模块的来源。在这里查看更多选项:https://github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
                    logLevel: 'info', // 日志级别,可以是info, warn, error, silent
                    excludeAssets:null, // 用于排除分析一些文件
                })
            )
    }
};
plugins: [
	
]

在执行nom run dev 或 npm run build命令,生成分析报告

3. gzip压缩

下载插件 compression-webpack-plugin (注意版本:可能会版本不匹配而报错)

js 复制代码
npm install --save-dev compression-webpack-plugin@1.1.12
js 复制代码
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = ['js','css'] ;

module.exports = {
    configureWebpack: (config) => {
           config.plugins.push(
               new CompressionWebpackPlugin({
                    filename: '[path].gz[query]',
                    algorithm: 'gzip',
                    test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
                    threshold: 10240,
                    minRatio: 0.8,
                    deleteOriginalAssets: true
                }),
           )
           config.output.filename = `system/[name].js`  //打包生成的文件(可以改变路径用于分类)
           config.output.chunkFilename = `system/[name].js`
    }
}

分类后的效果:

4. 公共文件CDN

需要在两个地方配置:vue.config.js、index.html

vue.config.js文件中编辑配置,externals指的是排除以下依赖包的打包。vue等依赖包是公共基础。

注意引入后变量的使用,注意externals对象中值的书写规则,如element-ui,必须使用大写的ELEMENT变量来引用

可以上官网自己找自己项目需要的:www.bootcdn.cn/

js 复制代码
module.exports = {
    configureWebpack: (config) => {
           config.externals = { 
                vue: 'Vue',
                'vue-router': 'VueRouter',
                axios: 'axios',
                "element-ui": "ELEMENT",
                "moment": "moment",
                'vuex': 'Vuex',
                'echarts': 'echarts'
            }
    }
}
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
    <div id="app"></div>
    //可以进行判断
    <% if (NODE_ENV === 'xxx') { %>
      <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js"></script>
      <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.5.1/vue-router.min.js"></script>
      <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
      <script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.6.2/vuex.min.js"></script>
      <script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.1/index.js"></script>
      <script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.9.0-rc.1/echarts.min.js"></script>
    <% } %> 
</body>

</html>

也可以自己下载cdn到自己的项目中,例如我放在了public/static/cdn文件夹下:

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
    <div id="app"></div>
    //可以进行判断
    <% if (NODE_ENV === 'xxx') { %>
     <script src="/static/cdn/vue.min.js"></script>
      <script src="/static/cdn/vue-router.min.js"></script>
      <script src="/static/cdn/axios.min.js"></script>
      <script src="/static/cdn/vuex.min.js"></script>
      <script src="/static/cdn/element-index.js"></script>
      <script src="/static/cdn/echarts.min.js"></script>
    <% } %> 
</body>

</html>
5. html-webpack-plugin压缩html代码

将 webpack中entry配置的相关入口chunk 和 extract-text-webpack-plugin抽取的css样式 插入到该插件提供的template或者templateContent配置项指定的内容基础上生成一个html文件,具体插入方式是将样式link插入到head元素中,script插入到head或者body

下载插件:

js 复制代码
npm install html-webpack-plugin@4.5.0 -D

如果没有具体配置可以不进行配置

js 复制代码
const HtmlPlugin =require('html-webpack-plugin') ; 
 
module.exports = {
    configureWebpack: (config) => {
           config.plugins.push(
                new HtmlPlugin({
                    // template:'./src/index.html', //指定源文件的存放路径
                    // filename: './html/index.html', //指定生成文件的存放路径
                    //template: path.join(__dirname, 'default_index.ejs'),
                    //filename: 'index.html', 
                    //hash: false, 
                    //inject: true, 
                    //compile: true, 
                    //favicon: false, 
                    //minify: false, 
                    //cache: true, 
                    //showErrors: true, 
                    //chunks: 'all', 
                    //excludeChunks: [], 
                    //title: 'Webpack App', 
                    //xhtml: false
                }),
           )
    }
}

最后附上全部代码:

vue.config.js文件

js 复制代码
const CompressionWebpackPlugin = require('compression-webpack-plugin') // npm install --save-dev compression-webpack-plugin@1.1.12 npm下载
const productionGzipExtensions = ['js','css'] ;
const HtmlPlugin =require('html-webpack-plugin') ; 
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;


module.exports = {
    publicPath: "./",
    assetsDir: './static',
    productionSourceMap: false,
    devServer: {
        open: true,
        disableHostCheck: false,
        host: "0.0.0.0",
        port: 3002,
        https: false,
        hotOnly: true,
    },
    configureWebpack: (config) => {
        // 在这里配置后,减少了压缩的包内容,需要在public/index.html通过cdn方式再引入,注意对应的版本
        if (process.env.NODE_ENV === 'qa') {
            config.plugins.push(
                new CompressionWebpackPlugin({
                    filename: '[path].gz[query]',
                    algorithm: 'gzip',
                    test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
                    threshold: 10240,
                    minRatio: 0.8,
                    deleteOriginalAssets: true
                }),
                new HtmlPlugin({}),
                new BundleAnalyzerPlugin()
            )
            config.output.filename = `system/[name].js`  //打包生成的文件
            config.output.chunkFilename = `system/[name].js`
            config.externals = { 
                vue: 'Vue',
                'vue-router': 'VueRouter',
                axios: 'axios',
                "element-ui": "ELEMENT",
                "moment": "moment",
                'vuex': 'Vuex',
                'echarts': 'echarts'
            }
        }
    }
};

index.html文件

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
    <div id="app"></div>
    //可以进行判断
    <% if (NODE_ENV === 'qa') { %>
     <script src="/static/cdn/vue.min.js"></script>
      <script src="/static/cdn/vue-router.min.js"></script>
      <script src="/static/cdn/axios.min.js"></script>
      <script src="/static/cdn/vuex.min.js"></script>
      <script src="/static/cdn/element-index.js"></script>
      <script src="/static/cdn/echarts.min.js"></script>
    <% } %> 
</body>

</html>

打包完生成.gz文件

记得在nginx修改配置

js 复制代码
#gzip on;
gzip on;
gzip_static on; # 开启静态文件压缩
gzip_buffers 32 4K;
gzip_comp_level 6;
gzip_min_length 100;
gzip_types application/javascript text/css text/xml;
gzip_disable "MSIE [1-6]."; #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip_vary on;

gzip_static on; 很重要一定要加上

至此,dist包的瘦身计划已经完成,dist包从35m降到了2m内;因为已经达到了项目的要求,所以就这样了。有问题的话欢迎大家在评论区讨论。

相关推荐
cwj&xyp2 小时前
Python(二)str、list、tuple、dict、set
前端·python·算法
dlnu20152506222 小时前
ssr实现方案
前端·javascript·ssr
古木20192 小时前
前端面试宝典
前端·面试·职场和发展
轻口味3 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王4 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发4 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀4 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪5 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef6 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端