vue/cli4 vue.config.js

本文详细介绍了Vue项目的配置文件vue.config.js的用法,涵盖了公共路径、输出目录、CSS处理、别名设置、代码分割、Webpack代理、图片压缩、性能优化等多个方面,旨在帮助开发者更好地理解和优化Vue项目的构建过程。
摘要由CSDN通过智能技术生成
// vue.config.js
const path = require("path");

function resolve(dir) {
  console.log(path); 
  //path大对象,里面有很多方法
  console.log(dir);
  //src/components/icon/svg
  console.log(path.join(__dirname, dir));
  //C:\Users\yang\Desktop\WORK\CePing-dl\src\components\icon\svg
  return path.join(__dirname, dir);
}
module.exports = {
  publicPath: "/",

  // 将构建好的文件输出到哪里
  outputDir: "dist",

  // 放置生成的静态资源(js、css、img、fonts)的目录。
  assetsDir: "static",

  // 指定生成的 index.html 的输出路径
  indexPath: "index.html",

  // 是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了,但是这会让你的应用额外增加 10kb 左右。
  runtimeCompiler: false,

  // 默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在这个选项中列出来。
  transpileDependencies: [],

  // 生产环境关闭 source map
  productionSourceMap: false,
//设置为 true 或 'warning' 时,eslint-loader 会将 lint 错误输出为编译警告。默认情况下,警告仅仅会被输出到命令行,且不会使得编译失败。
  // lintOnSave: true,

  // 配置css
  css: {
    // 是否使用css分离插件 ExtractTextPlugin
    extract: true,
    sourceMap: true,
    // css预设器配置项,移动端常用
    loaderOptions: {
      postcss: {
        plugins: [
          require("postcss-px2rem")({
            remUnit: 100
          })
        ]
      }
    },
    // 启用 CSS modules for all css / pre-processor files.
    modules: false
  },

  // 是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改。
  //函数写法
  chainWebpack: config => {
    // 配置别名
    config.resolve.alias
      .set("@", resolve("src"))
      .set("assets", resolve("src/assets"))
      .set("components", resolve("src/components"))
      .set("views", resolve("src/views"));

    config.optimization.minimizer("terser").tap(args => {
      // 去除生产环境console
      args[0].terserOptions.compress.drop_console = true;
      return args;
    });

    const svgRule = config.module.rule("svg");
    svgRule.uses.clear();
    svgRule.exclude.add(/node_modules/);
    svgRule
      .test(/\.svg$/)
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
        symbolId: "icon-[name]"
      });

    const imagesRule = config.module.rule("images");
    imagesRule.exclude.add(resolve("src/components/icon/svg"));
    config.module.rule("images").test(/\.(png|jpe?g|gif|svg)(\?.*)?$/);
  },
//对象的配置的写法(和函数写法二选一)
  // configureWebpack: {
  //   resolve: {
  //     alias: {
  //       "@": resolve("src"),
  //       'assets': resolve('src/assets')
  //     }
  //   }
  // }
  configureWebpack: config => {
    /*有插件就在这里配置
    config.plugins.push(xxx);
    if (process.env.NODE_ENV === "production") {
      config.plugins.push(xxx);
    }
    */
    //这里可以修改打包提示文件过大的配置
   // if (process.env.NODE_ENV === "production") {
  //     // 为生产环境修改配置...
  //     config.mode = "production";
  //     config["performance"] = {
  //       //打包文件大小配置
  //       maxEntrypointSize: 10000000,
  //       maxAssetSize: 30000000,
  //     };
  //   }
  },
  performance: { hints: false }, //关闭打包提示文件过大的警告
  // 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
  parallel: require("os").cpus().length > 1,

  devServer: {
    host: "0.0.0.0",
    port: 8088, // 端口号
    https: false, // https:{type:Boolean}
    open: false, // 配置自动启动浏览器  open: 'Google Chrome'-默认启动谷歌

    // 配置多个代理
    proxy: {
      "/api": {
        target: "http://xxx",
        // ws: true, // 代理的WebSockets
        changeOrigin: true, // 允许websockets跨域
        pathRewrite: {
          "^/api": "/api"
        }
      },
      "/api2": {
        target: "http://xxx/",
        // ws: true, // 代理的WebSockets
        changeOrigin: true, // 允许websockets跨域
        pathRewrite: {
          "^/api2": "/api"
        }
      },
      "/api3": {
        target: "http://dceccn.com:8888/",
        // ws: true, // 代理的WebSockets
        changeOrigin: true, // 允许websockets跨域
        pathRewrite: {
          "^/api3": "/api"
        }
      }
    }
  }
};


全面配置

持续更新?

图片压缩

cnpm install --save-dev image-webpack-loader
module.exports = {
  // 根据你的实际情况更改这里
  publicPath,
  assetsDir: 'assets',
  lintOnSave: true,
  // image 压缩 定义在 chainWebpack 中
 chainWebpack: config => {
   config.module
      .rule('images')
      .use('image-webpack-loader')
      .loader('image-webpack-loader')
      .options({
        bypassOnDebug: true
      })
      .end()}
}

公共代码抽离

从 webpack4 开始官方移除了 commonchunk 插件,改用了 optimization 属性进行更加灵活的配置,这也应该是从 V3 升级到 V4 的代码修改过程中最为复杂的一部分

splitChunks: {
    chunks: "async,//默认作用于异步 chunk,值为 all/initial/async/function(chunk),值为 function 时第一个参数为遍历所有入口 chunk 时的 chunk 模块,chunk._modules 为 chunk 所有依赖的模块,通过 chunk 的名字和所有依赖模块的 resource 可以自由配置,会抽取所有满足条件 chunk 的公有模块,以及模块的所有依赖模块,包括 css
    minSize: 30000,  //表示在压缩前的最小模块大小,默认值是 30kb
    minChunks: 1,  // 表示被引用次数,默认为 1;
    maxAsyncRequests: 5,  //所有异步请求不得超过 5 个
    maxInitialRequests: 3,  //初始话并行请求不得超过 3 个
   automaticNameDelimiter:'~',//名称分隔符,默认是~
    name: true,  //打包后的名称,默认是 chunk 的名字通过分隔符(默认是~)分隔
    cacheGroups: { //设置缓存组用来抽取满足不同规则的 chunk,下面以生成 common 为例
       common: {
         name: 'common',  //抽取的 chunk 的名字
         chunks(chunk) { //同外层的参数配置,覆盖外层的 chunks,以 chunk 为维度进行抽取
         },
         test(module, chunks) {  //可以为字符串,正则表达式,函数,以 module 为维度进行抽取,只要是满足条件的 module 都会被抽取到该 common 的 chunk 中,为函数时第一个参数是遍历到的每一个模块,第二个参数是每一个引用到该模块的 chunks 数组。自己尝试过程中发现不能提取出 css,待进一步验证。
         },
        priority: 10,  //优先级,一个 chunk 很可能满足多个缓存组,会被抽取到优先级高的缓存组中
       minChunks: 2,  //最少被几个 chunk 引用
       reuseExistingChunk: true//  如果该 chunk 中引用了已经被抽取的 chunk,直接引用该 chunk,不会重复打包代码
       enforce: true  // 如果 cacheGroup 中没有设置 minSize,则据此判断是否使用上层的 minSize,true:则使用 0,false:使用上层 minSize
       }
    }
}

第三方模块抽离

// 公共代码抽离
configureWebpack: config => {
//....
//优化项配置
config.optimization = {
    splitChunks: { // 分割代码块
        cacheGroups: {
            vendor: {//第三方库抽离
                chunks: 'all',
                test: /node_modules/,
                name: 'vendor',
                minChunks: 1,//在分割之前,这个代码块最小应该被引用的次数
                maxInitialRequests: 5,
                minSize: 0,//大于 0 个字节
                priority: 100//权重
            },
            common: {  //公用模块抽离
                chunks: 'all',
                test: /[\\/]src[\\/]js[\\/]/,
                name: 'common',
                minChunks: 2,在分割之前,这个代码块最小应该被引用的次数
                maxInitialRequests: 5,
                minSize: 0,//大于 0 个字节
                priority: 60
            },
            styles: { //样式抽离
                name: 'styles',
                test: /\.(sa|sc|c)ss$/,
                chunks: 'all',
                enforce: true
            },
            runtimeChunk: {
                name: 'manifest'
            }
        }
    }
}
}

完整配置

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

https://nbyx.xyz/?p=1078

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值