Vue.config.js 个人学习理解使用

在Vue-cli3 的前端底层搭建中,个人理解 最困难的地方在于Vue.config.js 的配置,在原来的基础上, Vue-Cli3 所搭建的环境更加简洁,运行起来更加方便,同样的 我们所需要配置的部分,集中在vue.config.js 中,这里面包括我们对webpack的一些从简单(configureWebpack)到详细(chainWebpack)的处理。
官网 地址
https://cli.vuejs.org/zh/config/#vue-config-js
这里 我们首先要知道 在配置vue.config.js中的各个部分
1.基本的对项目的配置 包括 项目打包的基本路径publicPath(vue-cli3.3+新版本使用),outputDir(build打包时的文件目录),assetsDir(存放静态资源的目录) 等等一些简单的基本的配置
2.devServer (webpack-dev-server 相关配置)
众所周知webpack-dev-serve用来快速搭建本地运行环境的工具 ,所以,这里必然是我们本地项目环境一些基础配置的东西 ,比如说 项目运行完毕后时候自动弹开浏览器啊! 端口号是啥啊!是否热更新啊!
对了 忘记说了 关于 如 hot,hotOnly,open port
host 等这些属性 我们完全可以在package文件中配置的
具体例子:
这个不是从VUE那里搞过来的 是React的 不过 写法是一样的

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "NODE_ENV=development  webpack-dev-server --config  webpack.develop.config.js --hot --open --host 0.0.0.0",
  },

等等这些东西,还有这里面最重要的一点就是proxy (跨域 代理部分)
这个地址是webpack官方地址 咋说呢 进去看看 就能了解很多关于dev-server属性的问题了,我今天也是看了一遍。
https://webpack.js.org/configuration/dev-server/
3,就是一些重点内容,关于webpack的配置啦 configureWebpack与chainWebpack的配置使用 这个 我也是看的一愣一愣的 就不多做妄言了 等啥时候 能搞明白了 在详细写一下。

抛出这些 还有如css的处理,第三方插件的处理(pluginOptions)等一下东西。

-----------分界线 请直接看最下面部分 直接的纯扯淡没用--------

这个下面的 是自己写的 基础的大家可以参考一下,涉及到webpack那部分的(configureWebpack与chainWebpack),直接忽略 无视就好

module.exports = {
    //基本路径
    //baseUrl: './',//vue-cli3.3以下版本使用
    publicPath: './',//vue-cli3.3+新版本使用
    outputDir: 'dist', // 运行时生成的生产环境构建文件的目录(默认''dist'',构建之前会被清除)
    lintOnSave: false, //是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
    //放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
    assetsDir: 'static',
    pages: undefined,  //在 multi-page 模式下构建应用  multi-page 直译为多页   就是每个页面或者内容 打包生成的内容我们是可以选择控制的
    runtimeCompiler: false,  //是否使用包含运行时编译器的 Vue 构建版
    //是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建,在适当的时候开启几个子进程去并发的执行压缩
    parallel: require('os').cpus().length > 1,
    //生产环境是否生成 sourceMap 文件,一般情况不建议打开
    productionSourceMap: false,   //Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置
//调整 webpack 配置 https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
    configureWebpack: config => {     //生产and测试环境
        let pluginsPro = [
            new CompressionPlugin({ //文件开启Gzip,也可以通过服务端(如:nginx)(https://github.com/webpack-contrib/compression-webpack-plugin)
                filename: '[path].gz[query]',
                algorithm: 'gzip',
                test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$', ),
                threshold: 8192,
                minRatio: 0.8,
            }),
            //	Webpack包文件分析器(https://github.com/webpack-contrib/webpack-bundle-analyzer)
            new BundleAnalyzerPlugin(),
        ];
        //开发环境
        let pluginsDev = [
            //移动端模拟开发者工具(https://github.com/diamont1001/vconsole-webpack-plugin  https://github.com/Tencent/vConsole)
            new vConsolePlugin({
                filter: [], // 需要过滤的入口文件
                enable: true // 发布代码前记得改回 false
            }),
        ];
        if (process.env.NODE_ENV === 'production') { // 为生产环境修改配置...process.env.NODE_ENV !== 'development'
            config.plugins = [...config.plugins, ...pluginsPro];
        } else {
            // 为开发环境修改配置...
            config.plugins = [...config.plugins, ...pluginsDev];
        }
    },



    css: {
        // 启用 CSS modules        //在VUE4 中已经被 放弃使用
        //在VUE 4 中 css.requireModuleExtension 默认情况下,
        //只有 *.module.[ext] 结尾的文件才会被视作 CSS Modules 模块。
        //设置为 false 后你就可以去掉文件名中的 .module 并将所有的 *.(css|scss|sass|less|styl(us)?) 文件视为 CSS Modules 模块。
        modules: false,

        // 是否使用css分离插件 生产环境下是 true,开发环境下是 false
        extract: true, //是否将组件中的 CSS 提取至一个独立的 CSS 文件中 (而不是动态注入到 JavaScript 中的 inline 代码)。

        // 开启 CSS source maps,一般不建议开启 设置为 true 之后可能会影响构建的性能  默认为 false
        sourceMap: false,
        // css预设器配置项
        loaderOptions: {
            sass: {
                //设置css中引用文件的路径,引入通用使用的scss文件(如包含的@mixin)
                data: `
				$baseUrl: "/";
				@import '@/assets/scss/_common.scss';
				`
                // css: {
                // 这里的选项会传递给 css-loader
                // },
                //   postcss: {
                // 这里的选项会传递给 postcss-loader
                //   }
            }
        }
    },

    // webpack-dev-server 相关配置 https://webpack.js.org/configuration/dev-server/
    devServer: {
        // host: 'localhost',
        host: "0.0.0.0",    // 服务器检测地址 
        port: 8080, // 端口号
        https: false, // https:{type:Boolean}
        open: true, //配置自动启动浏览器  http://172.11.11.22:8888/rest/XX/ 

        hotOnly: true, // 热更新    hot 和 hotOnly 的区别是在某些模块不支持热更新的情况下,前者会自动刷新页面,后者不会刷新页面,而是在控制台输出热更新失败

        // proxy: 'http://localhost:8000'   // 配置跨域处理,只有一个代理
        // 如果你的前端应用和后端 API 服务器没有运行在同一个主机上,
        // 你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。
        proxy: { //配置自动启动浏览器
            '/api': {
                target: 'http://198.46.188.16:9090/',
                changeOrigin: true,     // 是否改变域名
                pathRewrite: {   // 路径重写
                    '^/api': ''
                },
                "/XX2/*": {
                    target: "http://172.12.12.12:2018",
                    changeOrigin: true,
                    //ws: true,//websocket支持
                    secure: false
                },
            },
            //出现编译器错误或警告时,在浏览器中显示全屏覆盖。如果显示显示警告和错误:   只想显示编译器错误:overlay: true
            overlay: {
                warnings: false,
                errors: true
            },
            //将标头添加到所有响应:
            //   headers: {
            //     'X-Custom-Foo': 'bar'
            //   }
            //openPage: '/different/page'  指定打开浏览器时要浏览的页面
        },
    },

    // 第三方插件配置 https://www.npmjs.com/package/vue-cli-plugin-style-resources-loader
    pluginOptions: {    //定义资源的模式
        'style-resources-loader': {//https://github.com/yenshih/style-resources-loader
            preProcessor: 'scss',//声明类型
            'patterns': [
                //path.resolve(__dirname, './src/assets/scss/_common.scss'), 
            ],
            //injector: 'append'
        }
    },
    //chainWebpack 是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改。
    chainWebpack(config) {
        // config.plugins.delete('preload') // TODO: need test
        // config.plugins.delete('prefetch') // TODO: need test
    
        // set svg-sprite-loader
        config.module
          .rule('svg')
          .exclude.add(resolve('src/icons'))
          .end()
        config.module
          .rule('icons')
          .test(/\.svg$/)
          .include.add(resolve('src/icons'))
          .end()
          .use('svg-sprite-loader')
          .loader('svg-sprite-loader')
          .options({    
            symbolId: 'icon-[name]'
          })
          .end()
    
        // set preserveWhitespace
        config.module
          .rule('vue')
          .use('vue-loader')
          .loader('vue-loader')
          .tap(options => {
            options.compilerOptions.preserveWhitespace = true
            return options
          })
          .end()
    
        config
          // https://webpack.js.org/configuration/devtool/#development
          .when(process.env.NODE_ENV === 'development',
            config => config.devtool('cheap-source-map')
          )
    
        config
          .when(process.env.NODE_ENV !== 'development',
            config => {
              config
                .plugin('ScriptExtHtmlWebpackPlugin')
                .after('html')
                .use('script-ext-html-webpack-plugin', [{
                  // `runtime` must same as runtimeChunk name. default is `runtime`
                  inline: /runtime\..*\.js$/
                }])
                .end()
              config
                .optimization.splitChunks({
                  chunks: 'all',
                  cacheGroups: {
                    libs: {
                      name: 'chunk-libs',
                      test: /[\\/]node_modules[\\/]/,
                      priority: 10,
                      chunks: 'initial' // only package third parties that are initially dependent
                    },
                    elementUI: {
                      name: 'chunk-elementUI', // split elementUI into a single package
                      priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                      test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
                    },
                    commons: {
                      name: 'chunk-commons',
                      test: resolve('src/components'), // can customize your rules
                      minChunks: 3, //  minimum common number
                      priority: 5,
                      reuseExistingChunk: true
                    }
                  }
                  
                })
              config.optimization.runtimeChunk('single')
            }
          )
      }

-------------------------20201106-----------------分界线-----------------

下面这部分是我在学习Vue跟TypeScript结合的时候编写的 并且 当天看到一个关于大厂面试题后 关于处理首屏加载问题 结合网上的一些写法。
主要是学习gzip、cdn、pxtorem 这三部分

const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require("terser-webpack-plugin");                               // 优化压缩js
// const MiniCssExtractPlugin = require("mini-css-extract-plugin");                       // 分离css成单独的文件;
// const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');         // 优化 压缩css
// gzip压缩插件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
function resolve (dir) {
  return path.join(__dirname, dir)
}
const cdn = {
  // 忽略打包的第三方库
  externals: {
    'vue': 'Vue',
    'vuex': 'Vuex',
    'vue-router': 'VueRouter',
    'axios': 'axios'
  },
  // 通过cdn方式使用
  js: [
    'https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js',
    'https://cdn.bootcss.com/vue-router/3.1.2/vue-router.min.js',
    'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
    'https://cdn.bootcss.com/axios/0.19.2/axios.min.js',
    'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js',
    'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js'
  ],
  css: []
}
module.exports = {
  outputDir: 'disTypeScript',
  filenameHashing: true,      // 为静态文件添加Hash 能避免缓存问题
  parallel: true,             // 为bable使用thread-loader
  assetsDir: 'static',         // 静态资源文件
  publicPath: '/',             //在webpack中 关系与按需加载与外部引用的资源路径是否正确 此选项指定在浏览器中所引用的「此输出目录对应的公开 URL」
  devServer: {
    port: 8090,
    open: true,
    host: '0.0.0.0',
    overlay: {
      warnings: false,
      errors: true
    },
     // 需要gzip压缩的文件
    before (app, server) {
      
      app.get(/.*.(ts)$/, (req, res, next) => {
        req.url = req.url + '.gz'
        res.set('Content-Encoding', 'gzip')
        next()
      })
    }
  },
  configureWebpack: config => {    
    if (process.env.NODE_ENV === 'production') {
      //忽略打包配置
      config.externals = cdn.externals
      // 代码压缩去除console.log
      config.plugins.push(
        new TerserPlugin({
          terserOptions: {
            ecma: undefined,
            warnings: false,
            parse: {},
            compress: {
              drop_console: true,
              drop_debugger: false,
              pure_funcs: ['console.log'] // 移除console
            }
          }
        })
      )
      // 开启gzip压缩
      config.plugins.push(
        new CompressionWebpackPlugin(
          {
            filename: info => {
              return `${info.path}.gz${info.query}`
            },
            algorithm: 'gzip',
            threshold: 10240, // 只有大小大于该值的资源会被处理 10240
            test: new RegExp('\\.(' + ['js'].join('|') + ')$'
            ),
            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
            }
          }
        }
      }
    }
  },
  //对webpack 内部进行更细致的更改。 一些内部的配置使用  可以定义具名的 loader 规则和具名插件
  chainWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      // 配置cdn引入
      config.plugin('html').tap(args => {
        args[0].cdn = cdn
        return args
      })
    }
    // 移除prefetch插件,避免加载多余的资源
    config.plugins.delete('prefetch')
    config.resolve.symlinks(true); // 修复热更新失效
    config.resolve.alias // 添加别名
      .set('@', resolve('src'))
      .set('@assets', resolve('src/assets'))
      .set('@components', resolve('src/components'))
      .set('@views', resolve('src/views'))
      .set('@store', resolve('src/store'));
  },
  css: {
    //px转rem的配置(postcss-plugin-px2rem插件)
    loaderOptions: {
        postcss: {
            plugins: [
                require('postcss-plugin-px2rem')({
                  //现在测试中 我的默认是50px = 0.5rem  1rem = 100px
                    // rootValue: 100, //换算基数, 默认100  ,这样的话把根标签的字体规定为1rem为50px,这样就可以从设计稿上量出多少个px直接在代码中写多上px了。
                    // unitPrecision: 5, //允许REM单位增长到的十进制数字。
                    //propWhiteList: [],  //默认值是一个空数组,这意味着禁用白名单并启用所有属性。
                    // propBlackList: [], //黑名单
                    exclude: /(node_module)/,  //默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
                    // selectorBlackList: [], //要忽略并保留为px的选择器
                    // ignoreIdentifier: false,  //(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
                    // replace: true, // (布尔值)替换包含REM的规则,而不是添加回退。
                    mediaQuery: false,  //(布尔值)允许在媒体查询中转换px。
                    minPixelValue: 3 //设置要替换的最小像素值(3px会被转rem)。 默认 0
                }),
            ]
        }
    }
},
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值