122、Vue Cli3 項(xiàng)目打包優(yōu)化

一、新建項(xiàng)目

使用 vue-cli3 構(gòu)建一個初始的Vue項(xiàng)目:Cli3 官方文檔

因?yàn)槭褂昧薱li3,很多目錄結(jié)構(gòu)不見了,而相關(guān)配置是放在vue.config.js里面的,因此在根目錄,新建一個vue.config.js

module.exports = {}

二、正式優(yōu)化

1、將 productionSourceMap 設(shè)為 false

(1) 在vue.config.jsmodule.exports寫入:

module.exports = {
    productionSourceMap: false
}

2、圖片壓縮

vue正常打包之后一些圖片文件很大,使打包體積很大,通過image-webpack-loader插件可將大的圖片進(jìn)行壓縮從而縮小打包體積

(1) 先安裝依賴:cnpm install image-webpack-loader --save-dev
(2) 在vue.config.jsmodule.exports寫入:

module.exports = {
    productionSourceMap: false,
    chainWebpack: config => {
        // ============壓縮圖片 start============
        config.module
            .rule('images')
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({ bypassOnDebug: true })
            .end()
        // ============壓縮圖片 end============
    }
}

3、cdn配置(可選)

(1) 在vue.config.js 最上邊寫入:

// 是否為生產(chǎn)環(huán)境
const isProduction = process.env.NODE_ENV !== 'development'

// 本地環(huán)境是否需要使用cdn
const devNeedCdn = false

// cdn鏈接
const cdn = {
    // cdn:模塊名稱和模塊作用域命名(對應(yīng)window里面掛載的變量名稱)
    externals: {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter'
    },
    // cdn的css鏈接
    css: [],
    // cdn的js鏈接
    js: [
        'https://cdn.staticfile.org/vue/2.6.10/vue.min.js',
        'https://cdn.staticfile.org/vuex/3.0.1/vuex.min.js',
        'https://cdn.staticfile.org/vue-router/3.0.3/vue-router.min.js'
    ]
}

(2) 在vue.config.js module.exports chainWebpack中寫入:

// ============注入cdn start============
config.plugin('html').tap(args => {
    // 生產(chǎn)環(huán)境或本地需要cdn時(shí),才注入cdn
    if (isProduction || devNeedCdn) args[0].cdn = cdn
    return args
})
// ============注入cdn start============

(3) 在vue.config.js module.exports configureWebpack中寫入:

configureWebpack: config => {
    // 用cdn方式引入,則構(gòu)建時(shí)要忽略相關(guān)資源
    if (isProduction || devNeedCdn) config.externals = cdn.externals
}

(4) 當(dāng)前配置的vue.config.js

// 是否為生產(chǎn)環(huán)境
const isProduction = process.env.NODE_ENV !== 'development'

// 本地環(huán)境是否需要使用cdn
const devNeedCdn = false

// cdn鏈接
const cdn = {
    // cdn:模塊名稱和模塊作用域命名(對應(yīng)window里面掛載的變量名稱)
    externals: {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter'
    },
    // cdn的css鏈接
    css: [],
    // cdn的js鏈接
    js: [
        'https://cdn.staticfile.org/vue/2.6.10/vue.min.js',
        'https://cdn.staticfile.org/vuex/3.0.1/vuex.min.js',
        'https://cdn.staticfile.org/vue-router/3.0.3/vue-router.min.js'
    ]
}

module.exports = {
    productionSourceMap: false,
    chainWebpack: config => {
        // ============壓縮圖片 start============
        config.module
            .rule('images')
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({ bypassOnDebug: true })
            .end()
        // ============壓縮圖片 end============

        // ============注入cdn start============
        config.plugin('html').tap(args => {
            // 生產(chǎn)環(huán)境或本地需要cdn時(shí),才注入cdn
            if (isProduction || devNeedCdn) args[0].cdn = cdn
            return args
        })
        // ============注入cdn start============
    },
    configureWebpack: config => {
        // 用cdn方式引入,則構(gòu)建時(shí)要忽略相關(guān)資源
        if (isProduction || devNeedCdn) config.externals = cdn.externals
    }
}

(5) 在public index.html 寫入

<!DOCTYPE html>
<html lang="en">
    <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" />
        <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
        <!-- 使用CDN的CSS文件 -->
        <% for (var i in htmlWebpackPlugin.options.cdn &&
        htmlWebpackPlugin.options.cdn.css) { %>
        <link
            href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"
            rel="stylesheet"
        />
        <% } %>
        <!-- 使用CDN的CSS文件 -->
        <title>cli3_base</title>
    </head>
    <body>
        <noscript>
            <strong
                >We're sorry but cli3_base doesn't work properly without
                JavaScript enabled. Please enable it to continue.</strong
            >
        </noscript>
        <div id="app"></div>

        <!-- 使用CDN的JS文件 -->
        <% for (var i in htmlWebpackPlugin.options.cdn &&
        htmlWebpackPlugin.options.cdn.js) { %>
        <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
        <% } %>
        <!-- 使用CDN的JS文件 -->

        <!-- built files will be auto injected -->
    </body>
</html>

(6) 重啟項(xiàng)目npm run serve
(7) 在src/router.js修改

Vue.use(Router)

改為

if (!window.VueRouter) Vue.use(Router)

(8) 重新啟動npm run serve即可,現(xiàn)在的配置是開發(fā)環(huán)境,在瀏覽器的Network JS里面是看不到的。若想查看,請將vue.config.js里面的

// 本地環(huán)境是否需要使用cdn
const devNeedCdn = false

改為

// 本地環(huán)境是否需要使用cdn
const devNeedCdn = true

然后再次重啟npm run serve,然后瀏覽器查看Network JS

4、代碼壓縮

(1) 安裝依賴:cnpm i -D uglifyjs-webpack-plugin
(2) 在vue.config.js 最上邊引入依賴

// 代碼壓縮
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

(3) 在vue.config.js module.exports configureWebpack 里面新增

// 生產(chǎn)環(huán)境相關(guān)配置
if (isProduction) {
    // 代碼壓縮
    config.plugins.push(
        new UglifyJsPlugin({
            uglifyOptions: {
                //生產(chǎn)環(huán)境自動刪除console
                compress: {
                    warnings: false, // 若打包錯誤,則注釋這行
                    drop_debugger: true,
                    drop_console: true,
                    pure_funcs: ['console.log']
                }
            },
            sourceMap: false,
            parallel: true
        })
    )
}

5、開啟Gzip

(1) 安裝依賴:cnpm install --save-dev compression-webpack-plugin
(2) 在vue.config.js 頂部引入依賴

// gzip壓縮
const CompressionWebpackPlugin = require('compression-webpack-plugin')

(3) 在vue.config.js module.exports configureWebpack 里面新增,直接放在代碼壓縮下邊即可

// 生產(chǎn)環(huán)境相關(guān)配置
if (isProduction) {
    // 代碼壓縮
    // ..................
    // gzip壓縮
    const productionGzipExtensions = ['html', 'js', 'css']
    config.plugins.push(
        new CompressionWebpackPlugin({
            filename: '[path].gz[query]',
            algorithm: 'gzip',
            test: new RegExp(
                '\\.(' + productionGzipExtensions.join('|') + ')$'
            ),
            threshold: 10240, // 只有大小大于該值的資源會被處理 10240
            minRatio: 0.8, // 只有壓縮率小于這個值的資源才會被處理
            deleteOriginalAssets: false // 刪除原文件
        })
    )
}

6、公共代碼抽離

(1) 在vue.config.js module.exports configureWebpack 里面新增,直接放在gzip壓縮下邊即可

// 公共代碼抽離
config.optimization = {
    splitChunks: {
        cacheGroups: {
            vendor: {
                chunks: 'all',
                test: /node_modules/,
                name: 'vendor',
                minChunks: 1,
                maxInitialRequests: 5,
                minSize: 0,
                priority: 100
            },
            common: {
                chunks: 'all',
                test: /[\\/]src[\\/]js[\\/]/,
                name: 'common',
                minChunks: 2,
                maxInitialRequests: 5,
                minSize: 0,
                priority: 60
            },
            styles: {
                name: 'styles',
                test: /\.(sa|sc|c)ss$/,
                chunks: 'all',
                enforce: true
            },
            runtimeChunk: {
                name: 'manifest'
            }
        }
    }
}

完整的vue.config.js

// 代碼壓縮
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

// gzip壓縮
const CompressionWebpackPlugin = require('compression-webpack-plugin')

// 是否為生產(chǎn)環(huán)境
const isProduction = process.env.NODE_ENV !== 'development'

// 本地環(huán)境是否需要使用cdn
const devNeedCdn = true

// cdn鏈接
const cdn = {
    // cdn:模塊名稱和模塊作用域命名(對應(yīng)window里面掛載的變量名稱)
    externals: {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter'
    },
    // cdn的css鏈接
    css: [],
    // cdn的js鏈接
    js: [
        'https://cdn.staticfile.org/vue/2.6.10/vue.min.js',
        'https://cdn.staticfile.org/vuex/3.0.1/vuex.min.js',
        'https://cdn.staticfile.org/vue-router/3.0.3/vue-router.min.js'
    ]
}

module.exports = {
    productionSourceMap: false,
    chainWebpack: config => {
        // ============壓縮圖片 start============
        config.module
            .rule('images')
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({ bypassOnDebug: true })
            .end()
        // ============壓縮圖片 end============

        // ============注入cdn start============
        config.plugin('html').tap(args => {
            // 生產(chǎn)環(huán)境或本地需要cdn時(shí),才注入cdn
            if (isProduction || devNeedCdn) args[0].cdn = cdn
            return args
        })
        // ============注入cdn start============
    },
    configureWebpack: config => {
        // 用cdn方式引入,則構(gòu)建時(shí)要忽略相關(guān)資源
        if (isProduction || devNeedCdn) config.externals = cdn.externals

        // 生產(chǎn)環(huán)境相關(guān)配置
        if (isProduction) {
            // 代碼壓縮
            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        //生產(chǎn)環(huán)境自動刪除console
                        compress: {
                            warnings: false, // 若打包錯誤,則注釋這行
                            drop_debugger: true,
                            drop_console: true,
                            pure_funcs: ['console.log']
                        }
                    },
                    sourceMap: false,
                    parallel: true
                })
            )

            // gzip壓縮
            const productionGzipExtensions = ['html', 'js', 'css']
            config.plugins.push(
                new CompressionWebpackPlugin({
                    filename: '[path].gz[query]',
                    algorithm: 'gzip',
                    test: new RegExp(
                        '\\.(' + productionGzipExtensions.join('|') + ')$'
                    ),
                    threshold: 10240, // 只有大小大于該值的資源會被處理 10240
                    minRatio: 0.8, // 只有壓縮率小于這個值的資源才會被處理
                    deleteOriginalAssets: false // 刪除原文件
                })
            )

            // 公共代碼抽離
            config.optimization = {
                splitChunks: {
                    cacheGroups: {
                        vendor: {
                            chunks: 'all',
                            test: /node_modules/,
                            name: 'vendor',
                            minChunks: 1,
                            maxInitialRequests: 5,
                            minSize: 0,
                            priority: 100
                        },
                        common: {
                            chunks: 'all',
                            test: /[\\/]src[\\/]js[\\/]/,
                            name: 'common',
                            minChunks: 2,
                            maxInitialRequests: 5,
                            minSize: 0,
                            priority: 60
                        },
                        styles: {
                            name: 'styles',
                            test: /\.(sa|sc|c)ss$/,
                            chunks: 'all',
                            enforce: true
                        },
                        runtimeChunk: {
                            name: 'manifest'
                        }
                    }
                }
            }
        }
    }
}

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

相關(guān)閱讀更多精彩內(nèi)容

  • 第一次與傳說中的勵志人士親密接觸,他就是劉大銘,小小的病體不能阻擋他前進(jìn)的腳步! 大銘分享了五個他生命里...
    shary江閱讀 127評論 0 0
  • 可能是因?yàn)殛幱赀B綿 這樣的夜是無法入睡的 隨著雨水的滴落,心也會無比寂寥 這種寂寥讓人不知所措 理想、鄉(xiāng)愁、生活的...
    阿莫西林_閱讀 400評論 0 0
  • 有風(fēng)穿過馬路穿過孩子發(fā)熱的胸膛。 這樣一個難得的季節(jié)一件薄外套就能對清晨有所交代快落地的枯葉,陽光中也襯得溫柔老黃...
    魚東閱讀 315評論 1 7
  • 深秋的這樣一個黎明,無限清醒在心底,遠(yuǎn)行的我看著天空慢慢亮起來 ------《深秋的黎明》 很多時(shí)我們把精力都放在...
    凌風(fēng)傳說閱讀 1,145評論 1 1
  • 依依是三年級的小女生,長得清秀,愛跳舞,小嘴巴吧啦吧啦愛說話,是個可愛的孩子。但是挑食,挑得還挺嚴(yán)重。每次吃飯,依...
    格乃閱讀 1,408評論 15 36

友情鏈接更多精彩內(nèi)容