關于vue-cli 3配置打包優(yōu)化要點

本文同步更新于我的個人博客點擊前往。如果對您有幫助,請為我點個小星星。首先說下我目前已經做的優(yōu)化點,本文是在此基礎上做的進一步優(yōu)化:

  • 配置路由懶加載,封裝了異步組件引入的方法,接收一個地址做參數(shù)
/**
 *  返回異步組件
 * @tips 請注意頁面只能掛載在views文件下,非此路徑請勿使用
 */
const AsyncComponentHook = (path: String): Function => (): any => {
    // 通過 webpack 的內聯(lián)注釋,設置模塊名
    let component = import(/* webpackChunkName: "view-[request]" */ `@/views/${path}.vue`);
    component.catch((e) => {
        console.error(e);
    });
    return component;
};
  • 配置代碼壓縮
    // 安裝
    npm install uglifyjs-webpack-plugin

    // 在vue.config.js文件中添加配置
    configureWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            // 為生產環(huán)境修改配置...
            config.plugins.push(
                //生產環(huán)境自動刪除console
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            warnings: false,
                            drop_debugger: true,
                            drop_console: true,
                        },
                    },
                    sourceMap: false,
                    parallel: true,
                })
            );
        }
    },

  • 配置引用別名

  • 設置插件的按需引入,本文使用的是element-ui,點擊查看詳情

...

經過一些基礎的配置后,我們來看下目前打包后的效果。

從下圖可以看到,打包出來后最大的包有1.33M。然后再看下請求,哇,217個請求、首頁下載需要3.2M

image

image

...

好吧,開始折騰

1. 優(yōu)化scss配置文件的引入

我們在搭建項目的過程中經常性的會將一些scss配置文件抽離出來,例如主題色等,然后在每個需要的組件中引入。這樣會顯得很繁瑣,我們可以借助sass-loader幫我們進行預處理,
這樣我們就不用在每一個頁面都進行引入樣式,就能直接引用。

例如我們的樣式文件目錄下有一個theme.scss,我們可以在vue.config.js中作如下處理

// vue.config.js 配置
module.exports = {
  css: {
    // css預設器配置項
    loaderOptions: {
        // pass options to sass-loader
        sass: {
            // 引入全局變量樣式,@使我們設置的別名,執(zhí)行src目錄
            data: `
                @import "@/stylePath/theme.scss";
            `
        }
    },
  },
}

通過以上配置,就可以在組件模板中注釋以下代碼

<style lang="scss">
   /* @import "@/stylePath/theme.scss"; */
</style>

2. 針對請求數(shù)進行優(yōu)化

我們發(fā)現(xiàn)請求數(shù)增多是因為我們頁面預先渲染了其它組件,會在html頁面中插入像這樣的東西<link rel="prefetch">,這該怎么優(yōu)化呢?

首先我們先看下vue.config.js的官方文檔,點擊前往
官方說明: <link rel="prefetch"> 是一種 resource hint,用來告訴瀏覽器在頁面加載完成后,利用空閑時間提前獲取用戶未來可能會訪問的內容。

所以我們添加如下配置

// vue.config.js
module.exports = {
  chainWebpack: config => {
    // 移除 prefetch 插件
    config.plugins.delete('prefetch')
    // 移除 preload 插件
    config.plugins.delete('preload');
  }
}

3. 公用代碼提取,使用cdn加載

對于vue, vuex, vue-router,axios等我們可以利用wenpackexternals參數(shù)來配置,這里我們設定只需要在生產環(huán)境中才需要使用:

// vue.config.js
const isProduction = process.env.NODE_ENV === 'production';
const cdn = {
    css: [],
    js: [
        'https://cdn.bootcss.com/vue/2.5.17/vue.runtime.min.js',
        'https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js',
        'https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js',
        'https://cdn.bootcss.com/axios/0.18.0/axios.min.js',
    ]
}
module.exports = {
    chainWebpack: config => {
        // 生產環(huán)境配置
        if (isProduction) {
            // 生產環(huán)境注入cdn
            config.plugin('html')
                .tap(args => {
                    args[0].cdn = cdn;
                    return args;
                });
        }
    },
    configureWebpack: config => {
        if (isProduction) {
            // 用cdn方式引入
            config.externals = {
                'vue': 'Vue',
                'vuex': 'Vuex',
                'vue-router': 'VueRouter',
                'axios': 'axios'
            }
        }
    },
}

接著修改html文件,添加注入代碼

<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <!-- 使用CDN的CSS文件 -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
  <% } %>
  <!-- 使用CDN的JS文件 -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
    <link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">
  <% } %>
</head>

<body>
  <noscript>
    <strong>We're sorry but eye-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
  </noscript>
  <div id="app"></div>
  <!-- built files will be auto injected -->
  <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
  <% } %>
</body>

</html>

然后打包重啟,我們再來看下目前的變化。

嗯,真香~從下圖可以看到,打包出來后最大的包文件只有775kb。然后再看下請求,哇,43個請求、首頁下載只需要1.4M。

可以看出,我們這一系列的操作后請求數(shù)減少了174個,首頁渲染減少了1.8m,真是可喜可賀

image

image

最后,附上完整的vue-config.js文件

const path = require("path");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

const isProduction = process.env.NODE_ENV === 'production';
const cdn = {
    css: [],
    js: [
        'https://cdn.bootcss.com/vue/2.5.17/vue.runtime.min.js',
        'https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js',
        'https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js',
        'https://cdn.bootcss.com/axios/0.18.0/axios.min.js',
    ]
}

function resolve(dir) {
    return path.join(__dirname, dir)
}

module.exports = {
    // 基本路徑
    baseUrl: './',
    // 輸出文件目錄
    outputDir: 'dist',
    // 放置生成的靜態(tài)資源 (js、css、img、fonts) 的 (相對于 outputDir 的) 目錄。
    // assetsDir: "./",
    // 指定生成的 index.html 的輸出路徑 (相對于 outputDir)。也可以是一個絕對路徑
    indexPath: './',
    // eslint-loader 是否在保存的時候檢查
    lintOnSave: true,
    // webpack配置
    // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
    chainWebpack: config => {
        config
            .entry('index')
            .add('babel-polyfill')
            .end();
        // 配置別名
        config.resolve.alias
            .set("@", resolve("src"))
            .set("@img", resolve("src/assets/images"))
            .set("@css", resolve("src/assets/styles/css"))
            .set("@scss", resolve("src/assets/styles/scss"));
        // 生產環(huán)境配置
        if (isProduction) {
            // 刪除預加載
            config.plugins.delete('preload');
            config.plugins.delete('prefetch');
            // 壓縮代碼
            config.optimization.minimize(true);
            // 分割代碼
            config.optimization.splitChunks({
                chunks: 'all'
            })
            // 生產環(huán)境注入cdn
            config.plugin('html')
                .tap(args => {
                    args[0].cdn = cdn;
                    return args;
                });
        }
    },
    configureWebpack: config => {
        if (isProduction) {
            // 用cdn方式引入
            config.externals = {
                'vue': 'Vue',
                'vuex': 'Vuex',
                'vue-router': 'VueRouter',
                'axios': 'axios'
            }
            // 為生產環(huán)境修改配置...
            config.plugins.push(
                //生產環(huán)境自動刪除console
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            warnings: false,
                            drop_debugger: true,
                            drop_console: true,
                        },
                    },
                    sourceMap: false,
                    parallel: true,
                })
            );
        } else {
            // 為開發(fā)環(huán)境修改配置...
        }
    },
    // 生產環(huán)境是否生成 sourceMap 文件
    productionSourceMap: false,
    // css相關配置
    css: {
        // 是否使用css分離插件 ExtractTextPlugin
        extract: true,
        // 開啟 CSS source maps?
        sourceMap: false,
        // css預設器配置項
        loaderOptions: {
            // pass options to sass-loader
            sass: {
                // 引入全局變量樣式
                data: `
                    @import "@/stylePath/theme.scss;
                `
            }
        },
        // 啟用 CSS modules for all css / pre-processor files.
        modules: false,
    },
    // use thread-loader for babel & TS in production build
    // enabled by default if the machine has more than 1 cores
    parallel: require('os').cpus().length > 1,
    devServer: {
        port: 8888,  // 端口
        open: true, // 自動開啟瀏覽器
        compress: false, // 開啟壓縮
        overlay: {
            warnings: true,
            errors: true
        }
    },
}

以上就是我針對打包后做的優(yōu)化處理,當然還有其它優(yōu)化點,比如開啟gzip壓縮,不過這個需要后臺服務器支持,所以暫不配置。如果你還有其它優(yōu)化點,歡迎一起討論!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • vue-cli3項目搭建配置以及性能優(yōu)化 在之前的開發(fā)中主要用的是vue-cli2,最近空閑時間比較多,接下來有新...
    bayi_lzp閱讀 19,547評論 16 68
  • ## 框架和庫的區(qū)別?> 框架(framework):一套完整的軟件設計架構和**解決方案**。> > 庫(lib...
    Rui_bdad閱讀 3,146評論 1 4
  • 一:什么是閉包?閉包的用處? (1)閉包就是能夠讀取其他函數(shù)內部變量的函數(shù)。在本質上,閉包就 是將函數(shù)內部和函數(shù)外...
    xuguibin閱讀 10,009評論 1 52
  • 從18年7月16號入職到現(xiàn)在已經5個月多了,入職之后就一直使用vue,來這邊溫習記錄下使用的步驟。在我的理解中vu...
    好市民學編程閱讀 2,097評論 2 12
  • 最近一直市醫(yī)院、家里兩頭跑,婆婆的甲狀腺檢查,折騰了好久。本以為昨天到市里,可以直接做手術,沒想到還白跑了一趟,說...
    凌波微步007閱讀 1,174評論 0 1

友情鏈接更多精彩內容