基建 – Vue-cli3 脚手架搭建

说明:vue inspect 查看当前项目默认的webpack配置信息 (重要)

插件地址:www.webpackjs.com/plugins/

一、compression-webpack-plugin 开启Gzip压缩

1、compression-webpack-plugin作用

作用:提升网络传输速率=>优化web页面加载时间

可以借助CompressionWebpackPlugin插件来提前对文件进行Gzip压缩。

这样服务器查找到有与源文件同名的.gz文件就会直接读取,不会主动压缩,降低cpu负载,优化了服务器性能。

*基本原理

1)浏览器请求资源文件时会自动带一个Accept-Encoding的请求头告诉服务器支持的压缩编码类型;

2)服务器配置开启gzip选项:
接收客户端资源文件请求,查看请求头Content-encoding支持的压缩编码格式,如果是包含gzip那么在每次响应资源请求之前进行gzip编码压缩后再响应返回资源文件(在响应头会带上Content-encoding: gzip)。

3)浏览器接收到响应后查看请求头是否带有Content-encoding:gzip,如果有进行对返回的资源文件进行解压缩然后再进行解析渲染。

2、compression-webpack-plugin 项目使用

1、安装 compression-webpack-plugin

npm install compression-webpack-plugin --save-dev
复制代码

*npm地址www.npmjs.com/package/com…

2、Vue-cli3 的 vue.config.js 配置

const CompressionWebpackPlugin = require('compression-webpack-plugin');

module.exports = {
	// 设置一些webpack配置项,用这些配置项和默认的配置项合并 
  configureWebpack: {
  		plugins: [
      	new CompressionWebpackPlugin({
          	// 发现这货2.x版本将1.x版本的配置项asset更换成了filename
          	filename: info => `${info.path}.gz${info.query}`, // 打包后,在dist文件中有.gz文件
            algorithm: 'gzip', // 开启gzip
          	threshold: 10240, // 对超过10.24k的数据压缩
          	test: new RegExp(`\\.(${['js'].join('|')})$`), // 匹配文件名
          	// test: new RegExp('.(' + ['js', 'css'].join('|') + ')$'),
            minRatio: 0.8, // 压缩比
            deleteOriginalAssets: false, // 不删除源文件
				})
      ]
  }
}
复制代码

二、image-webpack-loader图片压缩使用

1、image-webpack-loader 作用

webpack 中使用图片压缩 (PNG, JPEG, GIF, SVG和WEBP) 能极大的减少包的大小,对于前端来说也是一个重要的优化点。

这里就推荐使用 image-webpack-loader,还有像 img-loader 和 imagemin-webpack-plugin 等其实底层调用的借口都是类似的。

2、image-webpack-loader 项目使用

**1、**安装 image-webpack-loader

npm install image-webpack-loader --save-dev
复制代码

*npm地址www.npmjs.com/package/ima…

**2、**Vue-cli3 的 vue.config.js 配置

module.exports = {
  // 直接去修改内置的webpack配置项
   chainWebpack: (config) => {
      // 图片压缩
      config.module
            .rule('images')
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({
              bypassOnDebug: true,
            })
            .end();
   }
}
复制代码

2、遇到的问题

webpack图片压缩image-webpack-loader无法安装或安装卡死,安装完后,再install的时候直接卡死,半天不动。

*总结问题:包安装的问题,npm下载下来的时候因为翻墙的问题,包下载的不完全 (问题必现)

3、解决方法

操作步骤方法1:(win操作)

1、若安装过 image-webpack-loader 先卸载

npm uninstall image-webpack-loader
复制代码

2、使用 cnpm , 这一步意思就是安装 cnpm 然后将全局的 registry 设置成阿里的镜像,国内阿里比较快

npm install cnpm -g --registry=https://registry.npm.taobao.org
复制代码

3、使用 cnpm 安装 image-webpack-loader 会发现很快就安装好了

cnpm install --save-dev  image-webpack-loader 
复制代码

操作步骤方法2:(Mac操作)

1、暂时去掉:package.json。例如:”image-webpack-loader”: “^7.0.1”

2、vue.config.js 注释代码

.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
   bypassOnDebug: true,
})
.end();
复制代码

3、包安装成功后,cnpm 安装 image-webpack-loader,然后vue.config.js 恢复

sudo cnpm install image-webpack-loader --save-dev
复制代码

三、uglifyjs-webpack-plugin 代码压缩,删除console与注释

1、uglifyjs-webpack-plugin作用

uglifyJsPlugin 用来对js文件进行压缩,减小js文件的大小。其会拖慢webpack的编译速度,建议开发环境时关闭,生产环境再将其打开。

2、uglifyjs-webpack-plugin 项目使用

1、安装uglifyjs-webpack-plugin

npm install uglifyjs-webpack-plugin --save-dev
复制代码

*npm地址www.npmjs.com/package/ugl…

2、Vue-cli3 的 vue.config.js 配置

const UglifyPlugin = require('uglifyjs-webpack-plugin');

optimization: {
      minimizer: [
        new UglifyPlugin({
          uglifyOptions: {
            // 删除注释
            output:{
              comments:false
            },
            // 删除console debugger 删除警告
            compress: {
              warnings: false,
              drop_console: true,//console
              drop_debugger: false,
              pure_funcs: ['console.log']//移除console
            }
          }
      })
    ]
}
复制代码

四、配置代理转发devServer.proxy

1、devServer.proxy作用

跨域处理的方式。跨域指协议、域名、端口三者之间任意一个与当前页面url不同。

2、devServer.proxy 项目使用

devServer: { //匹配规则
  open: false, // 自动启动浏览器
  host: '0.0.0.0', // localhost
  port: 6060, // 端口号
  https: false,
  hotOnly: false, // 热更新
  proxy: {
    '/api': {
      target: "https://www.baidu.cn/", //跨域网址
      ws: true, //开启WebSocket
      secure: false, // 如果是https接口,需要配置这个参数
      changeOrigin: true, // //自动修改http header里面的host
      pathRewrite: {
          "^/api": "", //路径的替换规则
        }
    }
  }
}
复制代码

**说明:**pathRewrite:如果不写则只能修改代理的域名,如果写则可以修改代理的域名和后边的路径。

五、只打包改变的文件

安装 npm i webpack -D

const { HashedModuleIdsPlugin } = require('webpack');
configureWebpack: config => {	
	const plugins = [];
	plugins.push(
		new HashedModuleIdsPlugin()
	)
}
复制代码

六、开启分析打包日志

安装 npm i webpack-bundle-analyzer -D

chainWebpack: config => {
	config
		.plugin('webpack-bundle-analyzer')
		.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
}
复制代码

七、vue.config.js 完整的架构配置(参考)

const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 去掉注释
const CompressionWebpackPlugin = require('compression-webpack-plugin'); // 开启压缩
const { HashedModuleIdsPlugin } = require('webpack');

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

const isProduction = process.env.NODE_ENV === 'production';

// cdn预加载使用
const externals = {
    'vue': 'Vue',
    'vue-router': 'VueRouter',
    'vuex': 'Vuex',
    'axios': 'axios',
    "element-ui": "ELEMENT"
}

const cdn = {
    // 开发环境
    dev: {
        css: [
            'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
        ],
        js: []
    },
    // 生产环境
    build: {
        css: [
            'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
        ],
        js: [
            'https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js',
            'https://cdn.jsdelivr.net/npm/vue-router@3.0.1/dist/vue-router.min.js',
            'https://cdn.jsdelivr.net/npm/vuex@3.0.1/dist/vuex.min.js',
            'https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js',
            'https://unpkg.com/element-ui/lib/index.js'
        ]
    }
}

module.exports = {

    lintOnSave: false, // 关闭eslint
    productionSourceMap: false,
    publicPath: './', 
    outputDir: process.env.outputDir, // 生成文件的目录名称
    chainWebpack: config => {

        config.resolve.alias
            .set('@', resolve('src'))

        // 压缩图片
        config.module
            .rule('images')
            .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({ bypassOnDebug: true })

        // webpack 会默认给commonChunk打进chunk-vendors,所以需要对webpack的配置进行delete
        config.optimization.delete('splitChunks')

        config.plugin('html').tap(args => {
            if (process.env.NODE_ENV === 'production') {
                args[0].cdn = cdn.build
            }
            if (process.env.NODE_ENV === 'development') {
                args[0].cdn = cdn.dev
            }
            return args
        })
        
        config
            .plugin('webpack-bundle-analyzer')
            .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    },

    configureWebpack: config => {
        const plugins = [];

        if (isProduction) {
            plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        output: {
                            comments: false, // 去掉注释
                        },
                        warnings: false,
                        compress: {
                            drop_console: true,
                            drop_debugger: false,
                            pure_funcs: ['console.log']//移除console
                        }
                    }
                })
            )
            // 服务器也要相应开启gzip
            plugins.push(
                new CompressionWebpackPlugin({
                    algorithm: 'gzip',
                    test: /\.(js|css)$/,// 匹配文件名
                    threshold: 10000, // 对超过10k的数据压缩
                    deleteOriginalAssets: false, // 不删除源文件
                    minRatio: 0.8 // 压缩比
                })
            )

            // 用于根据模块的相对路径生成 hash 作为模块 id, 一般用于生产环境
            plugins.push(
                new HashedModuleIdsPlugin()
            )

            // 开启分离js
            config.optimization = {
                runtimeChunk: 'single',
                splitChunks: {
                    chunks: 'all',
                    maxInitialRequests: Infinity,
                    minSize: 1000 * 60,
                    cacheGroups: {
                        vendor: {
                            test: /[\\/]node_modules[\\/]/,
                            name(module) {
                                // 排除node_modules 然后吧 @ 替换为空 ,考虑到服务器的兼容
                                const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
                                return `npm.${packageName.replace('@', '')}`
                            }
                        }
                    }
                }
            };

            // 取消webpack警告的性能提示
            config.performance = {
                hints: 'warning',
                //入口起点的最大体积
                maxEntrypointSize: 1000 * 500,
                //生成文件的最大体积
                maxAssetSize: 1000 * 1000,
                //只给出 js 文件的性能提示
                assetFilter: function (assetFilename) {
                    return assetFilename.endsWith('.js');
                }
            }

            // 打包时npm包转CDN
            config.externals = externals;
        }

        return { plugins }
    },

    pluginOptions: {
        // 配置全局less
        'style-resources-loader': {
            preProcessor: 'less',
            patterns: [resolve('./src/style/theme.less')]
        }
    },
    devServer: {
        open: false, // 自动启动浏览器
        host: '0.0.0.0', // localhost
        port: 6060, // 端口号
        https: false,
        hotOnly: false, // 热更新
        proxy: {
            '^/sso': {
                target: process.env.VUE_APP_SSO, // 重写路径
                ws: true,   //开启WebSocket
                secure: false,      // 如果是https接口,需要配置这个参数
                changeOrigin: true
            }
        }
    }
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享