vue-cli配置

1 篇文章 0 订阅
const { resolve } = require("path");
// 图片压缩 webpack-image-loader
const hardPlugin = require("hard-source-webpack-plugin") // 使用缓存,优化启动速度

// const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer") // 打包分析插件

const CompressionPlugin = require("compression-webpack-plugin"); // 版本是 5.0.1 开启gzip压缩, 按需引用 后端也需要配置gzip

const UglifyJsPlugin = require('uglifyjs-webpack-plugin') // js压缩,附带去除console,貌似说不支持es6,被terser替代,目前没发现毛病

 // PurgecssPlugin去除无用的css
const PurgecssPlugin = require('purgecss-webpack-plugin');

const glob = require('glob-all');

const path = require('path');

const prod = process.env.NODE_ENV === 'production' // 判断是否是生产环境
let cdn = {
  css: [
    'https://unpkg.com/element-ui/lib/theme-chalk/index.css' // element-ui css 样式表
  ],
  js: [
    // vue must at first!
    'https://unpkg.com/vue@2.6.12/dist/vue.js', // vuejs
    'https://unpkg.com/vue-router@3.5.3/dist/vue-router.min.js', // vue-router js
    'https://unpkg.com/vuex@3.6.2/dist/vuex.min.js', // vuex js
    'https://unpkg.com/element-ui/lib/index.js', // element-ui js
  ]
}

function setLess(config,types) {
  types.forEach(type => {
    let rule = config.module.rule('less').oneOf(type)
    rule.use('style-resource')
    .loader('style-resources-loader')
    .options({
        patterns: [resolve(__dirname, './src/assets/less/common.less')]
    });
  });
}

module.exports = {
  publicPath: './',
  productionSourceMap: false, // 生产环境是否要生成 sourceMap
  outputDir: 'dist', // 打包生成的包名
  assetsDir: 'assets', //  放置静态文件夹目录
  
  // configureWebpack有两种写法,一种是对象的写法,还有一种是函数的写法
  // configureWebpack对象写法
  // configureWebpack: {
  //   plugins: [
  //     new hardPlugin({
  //       cacheDirectory: resolve(__dirname, "cache")
  //     }),
  //     // new BundleAnalyzerPlugin() // 模块打包分析插件
  //   ]
  // },
  // configureWebpack函数写法
  configureWebpack: {
    // PurgecssPlugin去除无用的css
    plugins: [
      new PurgecssPlugin({
        paths: glob.sync([
          path.join(__dirname, './src/index.html'),
          path.join(__dirname, './**/*.vue'),
          path.join(__dirname, './src/**/*.js')
        ])
      })
    ]
  },
  configureWebpack: config => {
    if(prod) {
      const plugins = [];
      plugins.push(
        new hardPlugin({
          cacheDirectory: resolve(__dirname, "cache")
        }),
        // new BundleAnalyzerPlugin() // 模块打包分析插件
        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              // warnings: false,
              drop_debugger: true, // console
              drop_console: true,
              pure_funcs:['console.log'] // 移除console
            },
          },
          sourceMap: false,
          parallel: true,
        })
      );
      config.plugins = [...config.plugins, ...plugins];
    }
  },
  chainWebpack: config => {
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];
    setLess(config,types);

    config.resolve.alias // 设置别名
    .set('@', resolve('src'))

    if(prod) {
      config.module.rule('images').use('url-loader') // 图片转为base64,不用手动下载url-loader的
      .tap(options => ({
        name: './assets/images/[name].[contenthash:6].[ext]',
        quality: 85,
        limit: 10*1024, // 小于10kb的转为base64
        esModule: false,
      }));

      // js文件output输出配置
      config.output.filename('./js/[name].[chunkhash:6].js');
      config.output.chunkFilename('./js/[name].[chunkhash:6].js');

      // css合并  相当于webapck中的 mini-css-extract-plugin,可写可不写,@vue/cli已经默认打包到合并到css文件
      config.plugin('extract-css').tap(args => [{
        filename: 'css/[name].[contenthash:6].css',
        chunkFilename: 'css/[name].[contenthash:6].css'
      }]);

      // js压缩插件 相当于webpack中的terser-webpack-plugin
      // config.optimization.minimize(true)
      // .minimizer('terser')
      // .tap(args => {
      //   let { terserOptions } = args[0];
      //   terserOptions.compress.drop_console = true;
      //   terserOptions.compress.drop_debugger = true;
      //   return args
      // });
      // js gzip压缩
      config.plugin("compression").use(CompressionPlugin, [
        {
          test: /\.(js|css)?$/i, // 哪些文件要压缩
          filename: "[path].gz[query]", // 压缩后的文件名
          algorithm: "gzip", // 使用gzip压缩
          minRatio: 0.8, // 压缩率小于0.8才会压缩
          deleteOriginalAssets: false, // 删除未压缩的文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false
        },
      ]);
 
      // 排除npm包
      config.externals({
        vue: "Vue",
        "vue-router": "VueRouter",
        vuex: "Vuex",
        "element-ui": 'ElementUI'
      });
      config.plugin('preload').tap(() => [
        {
          rel: 'preload',
          fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
          include: 'initial'
        }
      ])
      // 注入cdn变量 (打包时会执行)
      config.plugin('html').tap(args => {
       // html-webpack-plugin
        args[0].cdn = cdn // 配置cdn给插件
        return args
      })
    }
  },
  devServer: {
    port: '9527', // 开发时运行的端口
    host: 'localhost', // 开发运行时域名
    open: true, // 是否自动打开浏览器
    proxy: { // 处理跨域
      "/api": {
        target: 'http://localhost:5000', // target代理到后端接口: http://localhost:5000
        changeOrigin: true,
        pathRewrite: { // 路径重写
          "^/api": ''
        }
      }
    }
  }
}
public下的html文件配置cdn
<!DOCTYPE html>
<html lang="">
  <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">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <!-- 引入样式 -->
    <% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
      <link rel="stylesheet" href="<%=css%>">
    <% } %>
    <% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
      <script src="<%=js%>"></script>
    <% } %>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- cdn的地址: https://www.jsdelivr.com/ -->
    <!-- 引入样式 -->
      <!-- 引入JS -->

    <!-- 引入组件库 -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.3/dist/vue-router.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuex@3.6.2/dist/vuex.min.js"></script> -->
    <!-- 引入JS -->

  </body>
</html>

最终显示

在这里插入图片描述

在这里插入图片描述

REFERENCE

参考:https://juejin.cn/post/7004045635620405278

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lxslxskxs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值