主要的目的是减少项目打包体积,提升页面的加载速度,现以vue-cli3为例,vue-cli3项目的webpack配置统一放在vue.config.js内,首先创建一个vue.config.js的文件

创建配置文件,抛出一个配置对象

const vueConfig = {}
module.exports = vueConfig

2.图片压缩

1.设置productionSourceMap=false

const vueConfig = {
    productionSourceMap: false
}

图片压缩我是写了两种方案感觉都不错,任选其一。

第一种:使用image-webpack-loader

/* 安装image-webpack-loader */
npm i image-webpack-loader

在配置文件中引入并使用

const vueConfig = {
    productionSourceMap: false,
    chainWebpack: config => {
       /* ============压缩图片 start============ */
        config.module
            .rule('images')
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({ bypassOnDebug: true })
            .end()
        /* ============压缩图片 end============ */
    }
}

第二种:使用tinyimg-webpack-plugin

npm i tinyimg-webpack-pluginx


 

在配置文件内使用

const TinyimgPlugin = require('tinyimg-webpack-plugin')
const vueConfig = {
    productionSourceMap: false,
    configureWebpack: config => {
        config.plugins.push(
            new TinyimgPlugin({
                enabled: process.env.NODE_ENV === 'production',
                logged: true
            })
        )
    }
}

3.CDN配置

vue.config.js 上边写入声明:

/* 是否为生产环境 */
const isProduction = process.env.NODE_ENV !== 'development'

/* 本地环境是否需要使用cdn */
const devNeedCdn = false

/* cdn链接 */
const cdn = {
    /* cdn:模块名称和模块作用域命名(对应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'
    ]
}

vue.config.js vue.config.js chainWebpack中写入:

/* ============注入cdn start============ */
config.plugin('html').tap(args => {
    /* 生产环境或本地需要cdn时,才注入cdn */
    if (isProduction || devNeedCdn) args[0].cdn = cdn
    return args
})
/* ============注入cdn end============ */

vue.config.js configureWebpack中写入:

configureWebpack: config => {
    /* 用cdn方式引入,则构建时要忽略相关资源 */
    if (isProduction || devNeedCdn) config.externals = cdn.externals
}

当前配置的vue.config.js

/* 是否为生产环境 */
const isProduction = process.env.NODE_ENV !== 'development'

/* 本地环境是否需要使用cdn */
const devNeedCdn = false

/* cdn链接 */
const cdn = {
    /* cdn:模块名称和模块作用域命名(对应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 => {
            /* 生产环境或本地需要cdn时,才注入cdn */
            if (isProduction || devNeedCdn) args[0].cdn = cdn
            return args
        })
        /* ============注入cdn end============ */
    },
    configureWebpack: config => {
        /* 用cdn方式引入,则构建时要忽略相关资源 */
        if (isProduction || devNeedCdn) config.externals = cdn.externals
    }
}

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>


src/router.js修改

Vue.use(Router)
/** 改为 */
if (!window.VueRouter) Vue.use(Router)

重启项目npm run serve, 然后浏览器查看Network JS

4.代码压缩

安装依赖:cnpm i -D uglifyjs-webpack-plugin

vue.config.js 上边引入依赖

/* 代码压缩 */
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

vue.config.js vueConfig configureWebpack 里面新增

/* 生产环境相关配置 */
if (isProduction) {
    /* 代码压缩 */
    config.plugins.push(
        new UglifyJsPlugin({
            uglifyOptions: {
                /* 生产环境自动删除console */
                compress: {
                    warnings: false, /* 若打包错误,则注释这行 */
                    drop_debugger: true,
                    drop_console: true,
                    pure_funcs: ['console.log']
                }
            },
            sourceMap: false,
            parallel: true
        })
    )
}

 

5.开启GZIP

安装依赖:cnpm install --save-dev compression-webpack-plugin
vue.config.js 顶部引入依赖

/* gzip压缩 */
const CompressionWebpackPlugin = require('compression-webpack-plugin')

vue.config.js vueConfig configureWebpack 里面新增,直接放在代码压缩下边即可

/* 生产环境相关配置 */
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 /* 删除原文件 */
        })
    )
}

需要配合nginx(Apache)使用

server {
        listen       9900 default_server;
        server_name  _;
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                root         /data/micro-front;
                index /index.html;
                try_files $uri $uri/ /index.html;
                gzip on; # 开启GZIP
                gzip_static on; # gzip_static是nginx对于静态文件的处理模块,该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。
                gzip_min_length 1k; # 启用gzip压缩的最小文件;小于设置值的文件将不会被压缩
                gzip_http_version 1.1;
                gzip_comp_level 9; # gzip 压缩级别 1-10 
                # 进行压缩的文件类型。
                gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;

                 # 是否在http header中添加Vary: Accept-Encoding,建议开启
                 gzip_vary on;
                
                if ($request_filename ~* .*\.(?:html|html)$)
                {
                    add_header Cache_Control "no-cache, must-revalidate";
                    add_header "Prama" "no-cache";
                    add_header "Expires" "0";
                }
                
                if ($request_filename ~* .*\.(?:js|css)$)
                {
                    add_header Cache_Control "no-cache";
                    expires 7d;
                }

                if ($request_filename ~* .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$)
                {
                    expires 7d;
                }

                if ($request_method = "OPTIONS") {
                    return 204;
                }
        }
}

 

6.公共代码抽离

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'
            }
        }
    }
}

 

完整的配置文件

/* 代码压缩 */
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

/* gzip压缩 */
const CompressionWebpackPlugin = require('compression-webpack-plugin')

/* 是否为生产环境 */
const isProduction = process.env.NODE_ENV !== 'development'

/* 本地环境是否需要使用cdn */
const devNeedCdn = true

/* cdn链接 */
const cdn = {
    /* cdn:模块名称和模块作用域命名(对应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'
    ]
}

const vueConfig = {
    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 => {
            /* 生产环境或本地需要cdn时,才注入cdn */
            if (isProduction || devNeedCdn) args[0].cdn = cdn
            return args
        })
        /* ============注入cdn end============ */
    },
    configureWebpack: config => {
        /* 用cdn方式引入,则构建时要忽略相关资源 */
        if (isProduction || devNeedCdn) config.externals = cdn.externals

        /* 生产环境相关配置 */
        if (isProduction) {
            /* 代码压缩 */
            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        /*生产环境自动删除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'
                        }
                    }
                }
            }
        }
    }
}

module.exports = vueConfig

 

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注