3. 修改 vue.config.js 配置完成打包分析和优化

个性化构建结果 - vue.config.js

在基础的配置上,自定义构建的结果 - 可以使用 vue.config.js

文档地址:cli.vuejs.org/zh/config/#...

PublicPath

  • PublicPath - 部署应用包时的基本 URL, 这个配置对应的是 webpack 的 PublicPath 属性

    • 默认值为 '/' ,Vue CLI 会假设你的应用是被部署在一个域名的根路径上 abc.com/
    • 可以设置为子路径 - 如果你的应用被部署在 abc.com/sub/ 那么就设置为 '/sub'
    • 可以设置为 CDN 路径 - 在我们的应用中,最后静态资源是要全部上传到 CDN 的,(脚手架自动完成),所以这里可以设置为一个 CDN 域名 - 'oss.imooc-lego.com/editor'
    • 还可以设置为绝对路径('' 或者 './'),这样所有的资源都会被链接为相对路径
js 复制代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  publicPath: process.env.NODE_ENV === 'production' ? 'https://oss.imooc-lego.com/editor' : '/'
})

打包之后:

html 复制代码
<!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">
    <link rel="icon" href="https://oss.imooc-lego.com/editor/favicon.ico">
    <title>project</title>
    <script defer="defer" src="https://oss.imooc-lego.com/editor/js/chunk-vendors.1f898ac5.js"></script>
    <script defer="defer" src="https://oss.imooc-lego.com/editor/js/app.c1aa142b.js"></script>
    <link href="https://oss.imooc-lego.com/editor/css/app.2cf79ad6.css" rel="stylesheet">
</head>

<body><noscript><strong>We're sorry but project doesn't work properly without JavaScript enabled. Please enable it to
            continue.</strong></noscript>
    <div id="app"></div>
</body>
</html>

css.loaderOptions 属性

向 CSS 相关的 loader 传递选项

Ant-design-vue 的样式变量:www.antdv.com/docs/vue/cu...
github.com/vueComponen...

添加更多的 CSS 预处理器:cli.vuejs.org/zh/guide/cs...

特别注意 less 和 less-loader 的版本问题。不要装最新的,建议选用:

js 复制代码
"less": "^3.12.0",
"less-loader": "^7.1.0"
js 复制代码
module.exports = {
  // 生产环境要使用 OSS 地址
  // 其他环境都使用绝对路径
  publicPath: (isProduction && !isStaging) ? 'https://oss.imooc-lego.com/' : '',
  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          modifyVars: {
            'primary-color': '#3E7FFF',
          },
          javascriptEnabled: true
        }
      }
    }
  }
}

bundle 打包分析工具

webpack-bundle-analyzer - www.npmjs.com/package/web...

js 复制代码
const { defineConfig } = require('@vue/cli-service')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = defineConfig({
  transpileDependencies: true,
  publicPath: process.env.NODE_ENV === 'production' ? 'https://oss.imooc-lego.com/editor' : '/',
  configureWebpack: (config) => {
    if (process.env.NODE_ENV === 'production') {
      config.plugins.push(new BundleAnalyzerPlugin({
        analyzerMode: 'static'
      }))
    }
  }
})
  • 看看有没有什么重复的模块,或者没有用的模块被打包到了最终的代码中
  • 看看 package.json,对比一下是否有应该在 devDeps 的模块,被错误的放置到了 deps 当中
  • 检查是否有重复加载的模块,或者是功能大体相同的模块。
  • 使用 ** es ** 版本的第三方库,享受 tree - shaking 的红利。
  • 检查是否有没有用的模块是否打包到了最终的文件中。
  • 使用 webpack ignore plugin webpack.js.org/plugins/ign...
js 复制代码
configureWebpack: config => {
  config.plugins.push(
    new webpack.IgnorePlugin({
      resourceRegExp: /^./locale$/,
      contextRegExp: /moment$/,
    })
  )
  // 打包后资源分析
  if (isAnalyzeMode) {
    config.plugins.push(
      new BundleAnalyzerPlugin({
        analyzerMode: 'static',
      })
    )
  }
}

resourceRegExp: /^./locale$/:表示要忽略的资源(模块路径)匹配以 ./locale 开头的模式。在这里,是为了忽略 moment 库中的 locale(语言 locale 相关)模块,因为很多情况下我们可能不需要 moment 库自带的所有语言 locale 文件,忽略它们可以减小打包体积。

contextRegExp: /moment$/:表示要忽略的模块所在的上下文(即模块所在的目录等相关匹配),这里匹配 moment 相关的上下文,结合 resourceRegExp,就是在 moment 相关的模块中,忽略 ./locale 相关的模块。

按需加载第三方组件库

  • 全局引入的方式
js 复制代码
import Antd from 'ant-design-vue'
app.use(Antd).use(LegoBricks).use(router).use(store)
app.mount('#app')
  • 按需引入
    configAntD.ts
js 复制代码
import { Button, Input, InputNumber, Slider, Radio, Select } from 'ant-design-vue'
import { App } from 'vue'
const components = [
    Button, Input, InputNumber, Slider, Radio, Select
]
const install = (app: App) => {
  components.forEach(component => {
    app.component(component.name, component)
  })
}
export default {
  install
}

vender 拆分

  • 充分利用浏览器的缓存
  • 浏览器支持平行加载多个文件
    • HTTP1 对同一域名并行加载的个数限制
    • HTTP2 完全突破这个限制

配置代码:

js 复制代码
const { defineConfig } = require('@vue/cli-service')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = defineConfig({
  transpileDependencies: true,
  publicPath: process.env.NODE_ENV === 'production' ? 'https://oss.imooc-lego.com/editor' : '/',
  configureWebpack: (config) => {
    if (process.env.NODE_ENV === 'production') {
      config.plugins.push(new BundleAnalyzerPlugin({
        analyzerMode: 'static'
      }))
    }
    config.optimization.splitChunks = {
      maxInitialRequests: Infinity,
      minSize: 0,
      chunks: 'all',
      cacheGroups: {
        antVendor: {
          name: 'ant-design-vue',
          test: /[\\/]node_modules[\\/](ant-design-vue)[\\/]/,
        },
        canvasVendor: {
          test: /[\\/]node_modules[\\/](html2canvas)[\\/]/,
          name: 'html2canvas'
        },
        vendor: {
          name: 'vendor',
          test: /[\\/]node_modules[\\/](!html2canvas)(!ant-design-vue)[\\/]/
        }
      }
    }
  }
})

按照大小拆分

js 复制代码
config.optimization.splitChunks = {
  maxInitialRequests: Infinity,
  minSize: 300 * 1024,
  chunks: 'all',
  cacheGroups: {
    antVendor: {
      test: /[\/]node_modules[\/]/,
      name(module) {
        const packageName = module.context.match(/[\/]node_modules[\/](.*?)([\/]|$)/)[1];
        return `npm.${packageName.replace('@', '')}`;
      }
    }
  }
};

路由懒加载

js 复制代码
[
  {
    path: '/editor/:id',
    name: 'editor',
    component: () => import(/* webpackChunkName: "editor" */ '../views/EditorView.vue'),
    meta: { requiredLogin: true, title: '编辑我的设计' }
  },
  {
    path: '/login',
    name: 'login',
    component: () => import(/* webpackChunkName: "login" */ '../views/LoginView.vue'),
    meta: { redirectAlreadyLogin: true, title: '登录到慕课乐高', disableLayout: true }
  }
]

使用效果:

相关推荐
文心快码BaiduComate2 小时前
轻松实践:用Python实现“名字大作战”游戏,表白Zulu!
前端·后端·微信小程序
神毓逍遥kang3 小时前
最近学习rust,然后使用rust构建你的前端cli工具助力前端生态
前端
1024小神3 小时前
Android冷启动和热启动以及温启动都是什么意思
前端
June_liu3 小时前
列太多vxe-table自动启用横向虚拟滚动引起的bug
前端·javascript
齐杰拉4 小时前
useSse 开源:如何把流式数据请求/处理简化到极致
前端·chatgpt
起风了啰4 小时前
Android & IOS兼容性问题
前端
云枫晖4 小时前
手写Promise-then的基础实现
前端·javascript
养生达人_zzzz4 小时前
飞书三方登录功能实现与行业思考
前端·javascript·架构
布列瑟农的星空4 小时前
从webpack到vite——配置与特性全面对比
前端