项目实战 vite改造

391 阅读5分钟

1、引入vite

首先根据官网下载vite项目模板(本项目环境的npm版本),

# npm 6.x
npm init vite@latest my-vue-app --template vue

得到如下文件夹

截屏2022-06-18 下午7.41.40.png 然后将vue.config.js和index.html 文件夹移动到最外层;

在本项目中安装:(刚下载模版中package中的包)

 "devDependencies": {
    "@vitejs/plugin-vue": "^2.3.3",
    "vite": "^2.9.9"
  }
  // 安装
  yarn add @vitejs/plugin-vue vite --save-dev
  //在项目中package.json中添加启动命令
   "scripts": {
    "vite": "vite --port 8083""vitebuild": "vite build",
    "preview": "vite preview"
  },
  

2.入口文件报错

这个错误是没访问到项目的入口文件;项目中入口文件为 main.ts.

截屏2022-06-18 下午7.48.13.png 修改index.html,

<body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
</body>

3.未配置别名

这个问题不识别“@”

截屏2022-06-18 下午7.49.52.png 接下来配置相关别名:

import { resolve } from "path";
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": resolve(__dirname, "./src"),
    },
  },
});

记得安装:

yarn add path -save-dev

好,问题解决,接下来

4 不识别环境变量

截屏2022-06-18 下午7.56.00.png 不是识别环境变量: 在vite.config.js添加配置

// 添加define
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": resolve(__dirname, "./src"),
    },
  },
  define: {
    "process.env": process.env,
  },
});

5 不识别 scss 定义变量

// vite.config.js
 css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@import "@/assets/css/common/var.scss";@import "@/assets/css/common/mixin.scss";`
      }
    }
  },

image.png

6 配置接口代理

server:{
  proxy: {
            '/snow': { // 匹配请求路径,localhost:3000/snow
                target: 'https://www.snow.com/', // 代理的目标地址
                changeOrigin: true, // 开发模式,默认的origin是真实的 origin:localhost:3000 代理服务会把origin修改为目标地址
                // secure: true, // 是否https接口
                // ws: true, // 是否代理websockets
                // rewrite target目标地址 + '/abc',如果接口是这样的,那么不用重写
                // rewrite: (path) => path.replace(/^\/snow/, '') // 路径重写,本项目不需要重写
            }
        }
     }

7、图片找不到

image.png 再添加个环境变量 '~@'

// 添加define
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": resolve(__dirname, "./src"),
      '~@': resolve(__dirname, './src')
    },
  },
  define: {
    "process.env": process.env,
  },
});

8. 样式使用警告问题

image.png

// 原来的样子
padding-top: $--walrus-table-row-margin/2

// 修改后的样子
padding-top:  calc($--walrus-table-row-margin/2);

9、element-plus 按需引入

下载两个插件

npm install -D unplugin-vue-components unplugin-auto-import

在项目的vite.config.ts中引入并配置plugins

// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default {
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
}

好,经过这一系列操作,页面终于打开了,耶耶耶~~~ 再试试打包吧, 其他项目遇到问题

优化

1、unplugin-vue-components 按需导入的依赖项更新导致页面无限次重载

image.png 在vite.config.js 中添加配置:

import fs from 'fs';
const optimizeDepsElementPlusIncludes = ['element-plus/es'];
fs.readdirSync('node_modules/element-plus/es/components').map((dirname) => {
  fs.access(
    `node_modules/element-plus/es/components/${dirname}/style/css.mjs`,
    (err) => {
      if (!err) {
        optimizeDepsElementPlusIncludes.push(
          `element-plus/es/components/${dirname}/style/css`
        );
      }
    }
  );
});

optimizeDeps: {
    include: optimizeDepsElementPlusIncludes
  },

引入打包解析工具,以便优化;

import {visualizer} from 'rollup-plugin-visualizer';

export default {
plugins:[visualizer()]
}

打包完,会报如下问题:

image.png

有些包超过500k,下面有三种解决方案,我们选一种就好,最后还有一个巨无霸包,添加下面manualChunks配置代码进行拆分:

 build: {
    outDir: 'vite_dist',
    chunkSizeWarningLimit: 1000,
    rollupOptions: {
      output: {
        chunkFileNames: 'static/js/[name]-[hash].js',
        entryFileNames: 'static/js/[name]-[hash].js',
        assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString();
          }
        }
      }
    }
  }

如果项目开启了gzip压缩我们可以配置:vite-plugin-compression 开启gzip、br压缩,

walrus项目暂时没开启,暂不配置


import viteCompression from 'vite-plugin-compression';
plugin:[
    viteCompression({
        //生成压缩包gz
        verbose: true, // 输出压缩成功
        disable: false, // 是否禁用
        threshold: 1, // 体积大于阈值会被压缩,单位是b
        algorithm: 'gzip', // 压缩算法
        ext: '.gz', // 生成的压缩包后缀
        deleteOriginFile: true
      })
]

接下来看下效果: image.png 再分析下打包的代码模块,用'rollup-plugin-visualizer'中visualizer, 中visualizer类似于 webpack-bundle-analyzer 将代码文件可视化,生成代码分析报告

打开目录下生成的stats.html,

image.png 可将 loadsh.js 优化

// 第一种 引入方式
   export { default as debounce } from 'lodash/debounce'
   
// 第二种 lodash-es为[ES]modules版本的库,只打包使用到的函数
 import { debounce} from 'loadsh-es'
 

image.png

非常好~,接下来让我们试试,vite新添加的preview功能吧 记得在预览前,记得先打包喔~~~

9.npm run preview

preview做了这几件事:注入选项参数,调用跨域,代理,compression中间件,启动本地服务器;

看下效果吧~~ (期待的眼神)

image.png

哭了~~

添加个插件,'vite-plugin-require-transform'试下,

import requireTranfrom from 'vite-plugin-require-transform';
plugins:[requireTranfrom()]

打包,npm run preview ,凉凉~,

依然报相同的错误,定位这个错误是依赖里面引入require引发的,无力感十足~~~

有办法了,在 index.html添加如下代码:

 <script> window.require = () => {} </script>

打包,启动,页面终于出来了,棒棒哒~~~

webpack 和vite 实战PK

启动时间

walrus项目用webpack项目可安装speed-measure-webpack-plugin插件。运行后可查看启动项目的时间;

// 安装
npm install speed-measure-webpack-plugin --save-dev

webpack启动时间:27.77s

image.png

vite启动时间 .4.008s

image.png

启动时间来看 vite 完胜!

渲染时间对比

webpack发送了11个请求,首次页面加载时间:1.14s, 渲染完成时间1.55s; image.png

vite 首次登录页渲染 :请求114次,首次页面加载时间:7.93s, 渲染完成时间8.49s;

image.png 结论:vite 首屏渲染时间较慢,原因是 vite中模块以原生 esm 的形式被浏览器加载,加载是用es6原生的模块加载机制,没有对代码进行打包压缩处理,所以服务启动很快。那下载的js文件是没有处理的过的源码,那文件大小自然要比webpack处理过的js文件大很多。这个原因导致首屏加载时间相差这么多。(所以vite是牺牲了页面首次加载时间来达到启动时间快的目的。)

二次渲染时,webpack 和vite 差不多时间

热更新时间对比

webpack:页面加载时间是2.55s,页面渲染完成时间2.56s

image.png

vite:页面加载时间是1.66s,页面渲染完成时间1.67s

image.png

显然 vite会更快些,从实际体验上也是vite 更新时间会更快些,使用webpack,如果一行代码进行了修改,webpack需要重新进行打包,随着项目的增大热更新需要的时间也就越长。而vite只需重新处理有修改的模块。

打包大小对比

webpack:63个文件,3.08M

image.png

vite:131个文件,2.88M

image.png

虽然 vite 比webpack 打出来的包少小,但文件个数比较多vite文件数量是webpack 2倍;

以上就是初改造项目的情况。

后续持续优化中~~~