vue.config.js 实用配置(生成zip文件,生产环境删除console.log,gzp配置,qiankun微前端配置等

使用vue-cli开发项目,免不了需要做些配置。特别是项目比较复杂时。这里列出一些有用的配置。当然,每个项目需求不同,或许对你来说,这并不实用。

这里所用的都是基于vue-cli3的配置哦。vue是2.x的。还在用vue-cli2的童鞋,该换新了,比较vue3都出来了,当然了,老项目可能没办法(我说的是没办法去升级成vue-cli3,可能因为时间成本,想要这些配置,也是可以的,只是写法和这里有区别罢了),至于vue3的,还没去研究额,再说vue3多了个vite。

基本路径 publickPath

如果你的项目部署在根目录下,这或许不用去管。但是,如果项目部署在子路径下,那就得改下咯

配置代码示例:

module.exports={
    publicPath: '/system/',
}

其中,system是访问项目的子路径,这里是和服务器对应的。也就是前端浏览器通过输入http://test.com/system/类似的路径访问项目首页

生产环境自动删除console.log

应该 有很多程序员像我一样,喜欢用console.log调试吧。额,虽然有人推荐debug,或者其他工具。但是习惯了console.log,也还没到必须改的时候。但是,生产环境下,如果打印一大堆console.log,那体验是不好的。当然如果你习惯看完就删除或者注释,也很好。这里说的是针对比较懒的那种人,比如我,不想动手,那就只能动代码咯。

配置有多种方法,这里使用TerserPlugin插件

配置代码示例:


const TerserPlugin=require('terser-webpack-plugin')
const isProduction = process.env.NODE_ENV === 'production'
module.exports={
    configureWebpack: config => {
        if (isProduction) {
            // 为生产环境修改配置...
            config.plugins.push(
                //生产环境自动删除console
                new TerserPlugin({
                    terserOptions: {
                        ecma: undefined,
                        warnings: false,
                        parse: {},
                        compress: {
                            drop_console: true,
                            drop_debugger: false,
                            pure_funcs: ['console.log'] // 移除console
                        }
                    },
                    sourceMap: false,
                    parallel: true,
                })
            )
         )
     }
  }
}

这里要注意的是terser-webpack-plugin版本,版本通常不能太高,插件没有做向下兼容,我这里vue版本是2.6,terser-webpack-plugin版是 "^3.1.0",反正如果你已经安装了以来,弄上去,报错莫名其妙说什么东西没有,那就是版本不兼容,通常需要降级。

开启gip压缩

开启gzp压缩是优化代码体积用的,如果项目不大,那也没必要。开启gip压缩需要后端配合才能生效,这里之说前端的配置。

使用 CompressionWebpackPlugin 插件

配置代码示例:

const CompressionWebpackPlugin = require('compression-webpack-plugin')
const isProduction = process.env.NODE_ENV === 'production'
module.exports={
    configureWebpack: config => {
        if (isProduction) {
            // 开启gzp压缩
            config.plugins.push(
                new CompressionWebpackPlugin({
                    // 正在匹配需要压缩的文件后缀
                    test: /\.(js|css|svg|woff|ttf|json|html)$/,
                    // 大于10kb的会压缩
                    threshold: 10240
                    // 其余配置查看compression-webpack-plugin
                })
            )
        }
    }
}

这里要注意的是CompressionWebpackPlugin版本,版本通常不能太高,插件没有做向下兼容,我这里vue版本是2.6,CompressionWebpackPlugin版是 "^5.0.0"。反正如果你已经安装了以来,弄上去,报错莫名其妙说什么东西没有,那就是版本不兼容,通常需要降级。

生成zip文件

懒人的福音,打包后,是不是要弄成压缩包发给后端或者运营部署?可是就是不想动手!那就只能动代码呗。当然,这可能带来的后果就是,打包需要 更多的时间,因为需要处理文件,弄成zip。

需要使用两个插件,BundleAnalyzerPlugin和FileManagerPlugin,结合node-cmd插件,并定义一个自己打开文件夹的类OpenFolderPlugin。很暖心有木有,文件夹都给你打开了,还想怎样???

配置代码示例:

const cmd = require("node-cmd")
const FileManagerPlugin = require("filemanager-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin
const OUTPUT_FILE_NAME='my-zip-file-test' //这里定义最终打包的zip文件名,和文件夹名称
class OpenFolderPlugin {
    apply(compiler) {
        compiler.hooks.done.tap("Open Folder Plugin", function() {
            cmd.run("start .\\dist");
        });
    }
}//这是打开文件夹的类
module.exports={
 // 输出文件目录
    outputDir: `dist/${OUTPUT_FILE_NAME}`,
    configureWebpack: config => {
            if (["build", "build-dev"].includes(process.env.npm_lifecycle_event)) {
            const outputFile = `./dist/${OUTPUT_FILE_NAME}.zip`;
            config.plugins.push(
              new BundleAnalyzerPlugin({
                  analyzerMode: "disabled",
                  generateStatsFile: true,
                  statsFilename: "../stats.json"//这里是生成代码分析文件,可以查看代码性能哟。当然主要针对包模块体积
              }),
              new FileManagerPlugin({
                  events:{
                      onStart:{
                          delete: ['./dist/'],
                      },
                      onEnd: {
                          archive: [
                              {
                                  source: `./dist/${OUTPUT_FILE_NAME}`,
                                  destination: outputFile
                              }
                          ]
                      }
                  }

              }),//这个webpack插件的功能挺多的,这里只用两个,开始打包事件和打包结束事件,我们打包后的文件依然放在dist文件夹里面,只是里面多了分析文件,zip文件,还有吧未压缩的生产环境用的文件单独放在一个文件夹里面
              new OpenFolderPlugin()
            );
        }
     }
}

同样,这里也要注意版本问题,因为这些插件到一定版本后,就会不兼容之前的版本。这里着实想吐槽一下,不过人家肯定也有难言之隐不是。我们就自己小心点了。

filemanager-webpack-plugin和webpack-bundle-analyzer,我这里都是用4.4.0版本哦。高了会报错的,不兼容。

build和build-dev是打包运行的命令,这里是监听命令的,因为我们只需要在打包时采用这个配置,通常来说,都是npm run build,如果你改了命令,这里也要做相应的更改。

微前端——乾坤 qiankun.js子项目配置

如果项目中使用了微前端,并且是使用qiankun开发的,那么这里就用上了。当然,只需要配置子项目,主项目不需要这个配置。

配置代码示例:

const {name} = require('./package')
module.exports={
    devServer: {
        port:6661,//因为主项目需要通过访问地址去访问子项目,所以端口最好不要配置成容易被占用的,否则一旦你启动多个项目,可能就得该代码里面的访问路径
        // 允许被主应用跨域fetch请求到,这里是必须的,不然跨越无法访问
        headers: {
            'Access-Control-Allow-Origin':'*'
        },
    },
    //需要配置打包模式,不然qiankun无法获取。不要问为什么,qiankun要求的,可以问问qiankun为啥要这么做。当然这里要说的是,qiankun会通过package里面的包名去读取文件,所以name必须是package的包名,不然获取文件会失败
        configureWebpack: config=>{
        // console.log(config)
        config.output.library=name
        config.output.libraryTarget= 'umd'
        config.output.jsonpFunction=`webpackJsonp_${name}`
     }
}

反向代理配置

什么时候需要配置反向代理?

开发换跨越,那是肯定出现的,因为是前后端分离项目,但是生产环境下,又不跨越,因为访问域名和api请求域名是一致的了(当然如果不一致,也会跨越,但是这不是前端能解决的了)。这种情况下,我们不需要后端小伙伴或者运维去解决,前端配置反向代理就好了,而且用起来也省心,因为不需要在请求接口的时候加上域名。

通常来说,一个项目的请求域名,只有一个,如果项目使用hash模式,那么就简单很多,直接在proxy那里写上api域名即可。

如果使用了history模式,就不能这样了,这会和服务器冲突的,必须要匹配路径去配置。这里示例一下history模式的配置。

//因为可能会有很多个路径匹配,这里不想写一大串if语句,所以,搞了个函数,使用循环。

//其中,/code,/admin,/auth是api请求除去域名的部分的开头,例如请求api路径是 http://test.com/admin/user/add-user-info

let proxys=function (){
    let apiPathArr=['/code','/auth','/admin']
    let proxys={}
    for(let i=0;i<apiPathArr.length;i++){
        proxys[apiPathArr[i]]={
            target: 'http://10.2.100.20',
            ws: false,
            changeOrigin: true,
            pathRewrite:{
                [`^${apiPathArr[i]}`]:apiPathArr[i]
            }
        }
    }
    return proxys
}()
module.exports={

    devServer: {
        proxy:proxys,// 配置多个代理
     
     },
}

暂时就这些了,下面给个完整的代码

const cmd = require("node-cmd")
const {name} = require('./package')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const TerserPlugin=require('terser-webpack-plugin')
const isProduction = process.env.NODE_ENV === 'production'
const FileManagerPlugin = require("filemanager-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin
const OUTPUT_FILE_NAME='loudi-wisdom-construction-site'
class OpenFolderPlugin {
    apply(compiler) {
        compiler.hooks.done.tap("Open Folder Plugin", function() {
            cmd.run("start .\\dist");
        });
    }
}

let proxys=function (){
    let apiPathArr=['/code','/auth','/admin']
    let proxys={}
    for(let i=0;i<apiPathArr.length;i++){
        proxys[apiPathArr[i]]={
            target: 'http://10.2.100.20',
            ws: false,
            changeOrigin: true,
            pathRewrite:{
                [`^${apiPathArr[i]}`]:apiPathArr[i]
            }
        }
    }
    return proxys
}()
module.exports = {
    // 基本路径
    publicPath: '/system/',
    // 输出文件目录
    outputDir: `dist/${OUTPUT_FILE_NAME}`,
    configureWebpack: config => {
        config.output.library=name
        config.output.libraryTarget= 'umd'
        config.output.jsonpFunction=`webpackJsonp_${name}`
        if (isProduction) {
            // 为生产环境修改配置...
            config.plugins.push(
                //生产环境自动删除console
                new TerserPlugin({
                    terserOptions: {
                        ecma: undefined,
                        warnings: false,
                        parse: {},
                        compress: {
                            drop_console: true,
                            drop_debugger: false,
                            pure_funcs: ['console.log'] // 移除console
                        }
                    },
                    parallel: true,
                })
            )
            // 开启gzp压缩
            config.plugins.push(
                new CompressionWebpackPlugin()
            )
        }
        if (["build", "build-dev"].includes(process.env.npm_lifecycle_event)) {
            const outputFile = `./dist/${OUTPUT_FILE_NAME}.zip`;
            config.plugins.push(
              new BundleAnalyzerPlugin({
                  analyzerMode: "disabled",
                  generateStatsFile: true,
                  statsFilename: "../stats.json"
              }),
              new FileManagerPlugin({
                  events:{
                      onStart:{
                          delete: ['./dist/'],
                      },
                      onEnd: {
                          archive: [
                              {
                                  source: `./dist/${OUTPUT_FILE_NAME}`,
                                  destination: outputFile
                              }
                          ]
                      }
                  }

              }),
              new OpenFolderPlugin()
            );
        }

    },
    devServer: {
        open: false,                                 //配置自动启动浏览器,想自动打开就设为true
         port:6661,
        // 允许被主应用跨域fetch请求到
        headers: {
            'Access-Control-Allow-Origin':'*'
        },                         
       proxy:proxys,// 配置多个代理
      
     },
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容