• vue-cli项目打包结果优化


    分析工具:webpack-bundle-analyzer

    使用范围:对于打包结果进行分析;

    使用方法:

    下载:

    npm install --save-dev webpack-bundle-analyzer;

    引入:在vue.config.js文件中,

       调整 webpack 配置最简单的方式就是在 vue.config.js 中的 configureWebpack 选项提供一个对象:

    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    
    module.exports = {
      configureWebpack:config=>{ //该配置会通过webpack-merge合并到webpack配置中
        if(process.env.NODE_ENV == 'production'){//判断执行环境,只有在生成环境中用到,开发环境中用不到分析工具,文档: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
          return {
         devtool: 'none', plugins: [
    new BundleAnalyzerPlugin() ] } } }, ... }

    通过分析工具可以看出,打包结果分为两部分:node_modules和src,其中前者是引入的公共包,后者是自己写的。

    前者分为:

    1. mockjs/dist不需要打包进入,

    2. vue. vue-router、vuex和axios不无法优化的固定代码:

      针对这部分可以采用cdn(content delivery network)方式引入公共的免费资源

      具体步骤:

    (1)告诉webpack,不要对vue. vue-router、vuex和axios这些可以从cdn上免费获取的公共资源进行打包;

        externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。

    //vue.config.js文件
    module.exports = { configureWebpack:config=>{ if(process.env.NODE_ENV == 'production'){ return { devtool: 'none', plugins: [ new BundleAnalyzerPlugin() ], externals:{ vue: 'Vue',//引入cdn上的资源后,将会生成全局变量Vue vuex: 'Vuex', 'vue-router': 'VueRouter', axios: 'axios' } } } },

     (2).在public目录下的index.html中,手动从cdn引入这几项,(注意用到了模板语法,这是html-webpack-plugin插件的语法)

    <!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">
    </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>
      <!-- ref cdn 开发环境不需要,生成环境需要,这是html-webpack-plugin的模板语法,当环境是生成环境时候,不需要引入cdn -->
      <% if( NODE_ENV === 'production' ){ %>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.min.js"></script>
        <script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.6.2/vuex.min.js"></script>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
        <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
      <% } %>
    </body>
    
    </html>

    此时,打包的文件没有了这四项公共的模块。

    (3)由于用cdn方式引入,模块化引入的方式是不能写的,比如Vue.use(Vuex),Vue.use(VueRouter)

    import Vue from 'vue';
    import VueRouter from 'vue-router';
    import routes from './routes';
    import setTitle  from '@/utils/setSiteTitle';
    //在production的条件下,由于vue.config.js中用了external, //把VueRouter暴露到全局,所以会存在,就不能用这种方式加载VueRouter了 if(!VueRouter){ Vue.use(VueRouter); } const router = new VueRouter({ mode: 'history', // base: process.env.BASE_URL, routes, })

    core-js是浏览器兼容的代码,

    它在babel.config.js文件的兼容要求基础上,模拟新的api
    module.exports = {
      presets: [
        '@vue/cli-plugin-babel/preset'
      ]
    }

    这个corejs是按需引入的,所以不需要我们在做处理。

    如果兼容的是新版本浏览器,可以不需要考虑兼容性,直接把babel.config.js里的preset值去掉就可以了。

    用npm run modern modern命令,打包出两种不同兼容性的代码;

    这篇博客挺好的:https://blog.csdn.net/weixin_34321753/article/details/89701992

    Vue CLI 构建两个版本的 js 包:一个面向支持现代浏览器的原生 ES2015+ 包,以及一个针对其他旧浏览器的包。

    但最酷的部分是没有特殊的部署要求。生成的HTML文件中自动适配。 这个方式采用了Phillip Walton 文章中讨论的技术方案

    • 在支持原生 ES2015+ 的浏览器中,js会通过 <script type="module"> 加载,并且可以使用 <link rel="modulepreload"> 预加载。

    • 在不支持的浏览器中使用 <script nomodule> 来加载编译版本,并且这会被支持ES模块的浏览器所忽略。

    <!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 href="/css/chunk-249149b2.bc811261.css" rel="prefetch"> //perfeth和preload都是懒加载,但preload的优先级要高
      <link href="/css/chunk-3de993f6.c13ff11f.css" rel="prefetch">
      <link href="/css/chunk-5d499e19.25e41ee9.css" rel="prefetch">
      <link href="/css/chunk-61542f76.899679a2.css" rel="prefetch">
      <link href="/css/chunk-71cb7586.eb46b54a.css" rel="prefetch">
      <link href="/js/chunk-249149b2.9522a5e5.js" rel="prefetch">
      <link href="/js/chunk-3de993f6.e812e81e.js" rel="prefetch">
      <link href="/js/chunk-5d499e19.b2738f79.js" rel="prefetch">
      <link href="/js/chunk-61542f76.62cfd7c4.js" rel="prefetch">
      <link href="/js/chunk-71cb7586.8a1a4a95.js" rel="prefetch">
      <link href="/css/app.ac0c3dd2.css" rel="preload" as="style">
      <link href="/js/app.cedc65b7.js" rel="modulepreload" as="script">
      <link href="/js/chunk-vendors.f5d25c35.js" rel="modulepreload" as="script">
      <link href="/css/app.ac0c3dd2.css" rel="stylesheet">
    </head>
    
    <body><noscript><strong>We're sorry but my-site doesn't work properly without JavaScript enabled. Please enable it to
          continue.</strong></noscript>
      <div id="app"></div>
      <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.min.js"></script>
      <script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.6.2/vuex.min.js"></script>
      <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
      <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
      <script type="module" src="/js/chunk-vendors.f5d25c35.js"></script> //非现代浏览器会忽略type=module的引入
      <script type="module" src="/js/app.cedc65b7.js"></script>
      <script>!function () { var e = document, t = e.createElement("script"); if (!("noModule" in t) && "onbeforeload" in t) { var n = !1; e.addEventListener("beforeload", function (e) { if (e.target === t) n = !0; else if (!e.target.hasAttribute("nomodule") || !n) return; e.preventDefault() }, !0), t.type = "module", t.src = ".", e.head.appendChild(t), t.remove() } }();</script>
      <script src="/js/chunk-vendors-legacy.f5d25c35.js" nomodule></script> //现代浏览器会忽略nomodule属性的标签
      <script src="/js/app-legacy.6a3f1c73.js" nomodule></script>
    </body>
    
    </html>

    对自己写的代码的优化

    路由懒加载:函数返回promise,结果是组件。打包后进行了分包

    import Home from '@/views/Home/index.vue'
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home,
        meta:{
          subTitle: '主页'
        }
      },
      {
        path: '/about',
        name: 'About',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import( '@/views/About/'),
        meta:{
          subTitle: '关于'
        }
      },

    刚打开网站的白屏处理:

    处理方法有多种:

    1.在#app元素中插入一张加载动画,

      如果vue没加载出来,#app中的内容不会消失,一旦new Vue()执行,因为有render函数介入,#app的内容会render的内容被覆盖。

    注意:该动画图片的路径必须是public目录下,因为该目录下,会经过copy-webpack-plugin的插件,原封不动的复制到dist目录。而不是和assets目录下的图片,会经过loader解析,成为新文件。

    静态文件分为static和asset文件,,static是纯静态文件,而assets是经过loader处理的文件,在vue-cli中,static文件放在public目录中

       

     2.在加载中添加进度条

      在vue-cli中,可以直接在代码中判断当前的环境是开发还是生产环境。用 

  • 相关阅读:
    let和const====均参考阮大神的es6入门
    面向对象封装
    记忆函数
    PHP面试题一[转]
    TDSSNIClient 初始化失败,出现错误 0x7e,状态代码 0x60。
    针对hasp加密狗服务器客户机ip不在同一个网段的解决方案
    sql 语句用isnull函数的用法
    如何用JS获取键盘上任意按键的值?兼容FireFox和IE js获取键盘ASCII码?js键盘事件全面控制
    adobe captivate 5.5 中文教程
    档案软件演示版下载安装说明书
  • 原文地址:https://www.cnblogs.com/dangdanghepingping/p/14887883.html
Copyright © 2020-2023  润新知