为什么选择vite

借用vite官网的介绍https://cn.vitejs.dev/guide/why.html#the-problems
本人更换vite主要就是两个原因:

  1. webpack dev环境启动太慢了,公司项目启动平均要一分半钟;
  2. webpack build需要的内存较大,公司项目平均2.3G内存;

初步准备

  • 如果不想要webpack和vite共存,那么我建议直接新建一个文件夹。
  • 我所用的项目为vue2.7项目(所以我会讲我用到的vue2.x的包,3.x的建议直接yarn create vite my-vue-app –template vue)。

更换过程

  • 首先 npm init 创建package.json, 已有项目直接复制过来就好

  • 安装必要的npm包,vite, @vitejs/plugin-vue2(vue3.x安装@vitejs/plugin-vue),项目中需要的其他包根据自己的需要添加,以上为vite运行必须的包

    1
    npm i vite @vitejs/plugin-vue2 -D
  • 新建vite.config.js文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // vite.config.js
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue2'
    import { fileURLToPath } from 'url'

    export default defineConfig(({ command, mode }) => {
    reutrn {
    // 写vue的一般都用‘@’作为‘src’的别名,我这里就配了这一个,有需要则自行添加
    resolve: {
    alias: {
    '@': fileURLToPath(new URL('./src', import.meta.url))
    },
    extensions: ['.js', '.vue']
    },
    plugins: [
    // 解析vue2.x需要的插件
    vue()
    ],
    server: {
    // dev环境代理服务
    proxy: {
    '/api': {
    target: '',
    changeOrigin: true,
    rewrite: (path) => path.replace('/api', '')
    }
    }
    },
    // 打包时去掉debugger和console
    esbuild: {
    drop: command === 'build' ? ['debugger', 'console'] : [],
    },
    }
    })
  • 此时将旧版项目的src复制到新的项目下,目录结构为

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    src/
    compontents/
    **.vue
    router/
    index.js
    store/
    index.js
    utils/
    App.vue
    main.js
    index.html
    jsconfig.json
    package.json
    vite.config.js
  • main.js 需要进行调整

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    // main.js

    // 只有new Vue部分修改,其余部分可继续沿用,例如element-ui
    import Vue from 'vue'
    import router from './router'
    import store from './store/index.js'

    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI); // 全局使用ElementUI


    import App from './App'
    // 原
    // const instance = new Vue({
    // el: '#app',
    // router,
    // store,
    // components: { App },
    // template: '<App/>'
    // })
    // export default instance

    // 现
    const instance = new Vue({
    router,
    store,
    render: (h) => h(App)
    }).$mount('#app')
    export default instance
  • index.html需要增加main.js的引用

    1
    2
    3
    4
    <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
    </body>

此时项目应该可以运行起来了

npm包在生产环境进行cdn引入

本人使用rollup-plugin-external-globals包进行cdn的使用

  • 安装 rollup-plugin-external-globals

    1
    npm i rollup-plugin-external-globals -D
  • 修改vite.config.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // vite.config.js

    // 省略上面配置过的
    ...
    import externalGlobals from 'rollup-plugin-external-globals'


    export default defineConfig(({ command, mode }) => {
    reutrn {
    // 省略上面配置过的
    ...
    // 增加build打包后cdn的配置
    build: {
    rollupOptions: {
    // 代码中引用的包名
    external: ['vue', 'vue-router', 'element-ui'],
    plugins: [
    // 属性名为项目中使用的名字,值为cdn暴露的全局变量名
    externalGlobals({
    vue: 'Vue',
    'vue-router': 'VueRouter',
    'element-ui': 'ELEMENT',
    })
    ]
    }
    }
    }
    })
  • 修改index.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <head>
    <link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.10/lib/theme-chalk/index.css"></link>
    </head>
    <body>
    <div id="app"></div>
    <script src="https://unpkg.com/vue@2.7.13/dist/vue.js"></script>
    <script src="https://unpkg.com/element-ui@2.15.10"></script>
    <script src="https://unpkg.com/vue-router@3.6.5"></script>

    <script type="module" src="/src/main.js"></script>
    </body>

此时打包已经将vueelement-uivue-router排除了。

使用vite-plugin-html可以进行html内的cdn自动导入

cdn自动引入

使用vite-plugin-html包完成cdn自动引入index.html

  • 安装

    1
    npm i vite-plugin-html -D
  • 创建一个js文件,我这里取名cdn.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // config/cdn.js
    export default {
    // 属性名自己起
    js: [
    'https://unpkg.com/vue@2.7.13/dist/vue.js',
    'https://unpkg.com/element-ui@2.15.10',
    'https://unpkg.com/vue-router@3.6.5'
    ],
    css: [
    'https://unpkg.com/element-ui@2.15.10/lib/theme-chalk/index.css'
    ]
    }
  • 修改vite.config.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    // vite.config.js
    // 省略上面配置过的
    ...
    import { createHtmlPlugin } from 'vite-plugin-html'
    import cdn from '/config/cdn.js'

    export default defineConfig(({ command, mode }) => {
    reutrn {
    // 省略上面配置过的
    ...
    plugins: [
    ...
    createHtmlPlugin({
    minify: true, // 是否压缩 html
    /**
    * 如果你想将 `index.html`存放在指定文件夹,可以修改它,否则不需要配置
    * @default index.html
    */
    template: "/index.html",
    inject: {
    data: {
    // 这个属性名也是自己起
    injectScript: cdn.js,
    injectLink: cdn.css,
    },
    },
    })
    ]
    }
    })
  • 修改index.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <head>
    <% for (let i in injectLink) { %>
    <link rel="stylesheet" href="<%= injectLink[i] %>" />
    <% } %>
    </head>
    <body>
    <div id="app"></div>
    <!-- 这里的injectScript就是vite.config.js里自己起的名 -->
    <% for (let i in injectScript) { %>
    <script src="<%= injectScript[i] %>"></script>
    <% } %>

    <script type="module" src="/src/main.js"></script>
    </body>

启用Gzip

  • 安装vite-plugin-compression

    1
    npm i vite-plugin-compression -D
  • vite.config.js使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // vite.config.js
    ... // 省略上面已有的
    import viteCompression from 'vite-plugin-compression'

    export default defineConfig(({ command, mode }) => {
    reutrn {
    // 省略上面配置过的
    ...
    // 增加build打包后cdn的配置
    build: {
    rollupOptions: {
    ...
    plugins: [
    ...
    viteCompression()
    ]
    }
    }
    }
    })

启用打包分析

  • 安装rollup-plugin-visualizer

    1
    npm i rollup-plugin-visualizer -D
  • vite.config.js中使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // vite.config.js
    // 省略上面配置过的
    ...
    import { visualizer } from 'rollup-plugin-visualizer';

    export default defineConfig(({ command, mode }) => {
    reutrn {
    // 省略上面配置过的
    ...
    plugins: [
    ...
    visualizer({ open: true })
    ]
    }
    })

插件总结

  • vite vite包
  • @vitejs/plugin-vue2 vue2.x语法解析
  • vite-plugin-compression Gzip压缩
  • rollup-plugin-visualizer 打包依赖分析
  • vite-plugin-eslint eslint校验,需配合eslint, @babel/eslint-parser, eslint-plugin-vue
  • @vitejs/plugin-vue2-jsx vue2.x jsx插件
  • vite-plugin-mock mock插件,需配合mockjs
  • vite-plugin-html html模版自动导入cdn