使用vite插件可以扩展vite的能力,比如解析用户自定义的文件输入,在打包代码前转译代码。

插件钩子

  1. export default function(options){
  2. return {
  3. name: 'my-vite-plugin',
  4. // 修改vite配置
  5. config(){},
  6. // vite配置确认
  7. configResolved(){},
  8. // 用于配置dev server
  9. configureServer(){},
  10. // 用于转换宿主页
  11. transformIndexHtml(){},
  12. // 创建自定义确认函数
  13. resolveId(id){},
  14. // 创建自定义加载函数,可用于返回自定义内容
  15. load(id){},
  16. // 可用于转换已加载的模块内容
  17. transform(code){},
  18. // 自定义hrm更新时调用
  19. handleHotUpdate(){}
  20. }
  21. }

手写一个vite插件

我们来实现一个多语言的插件吧。
image.png

1. 定义多语言文件

我们尝试把配置文件以标签的形式写在vue中。

  1. export default defineComponent({
  2. name: 'App',
  3. setup(){
  4. }
  5. })
  6. </script>
  7. <i18n>
  8. {
  9. "en": {
  10. "language": "en",
  11. "message": "this is message content"
  12. },
  13. "zh": {
  14. "language": "中文",
  15. "message": "我是消息的啊"
  16. }
  17. }
  18. </i18n>

2. 引入vite插件

我们的vite需要解析这个i18n标签,就要自定义一个插件来实现。

  1. export default {
  2. name: 'vite-vue-i18n',
  3. transform(code, id){
  4. // 将load进来的代码进行加工
  5. if (/vue&type=i18n/.test(id)){
  6. return `export default Components => {
  7. Components.i18n = ${code};
  8. }`
  9. }
  10. return null;
  11. }
  12. }

加载插件,在vite.config.js中修改。

  1. import { defineConfig } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import I18n from './plugins/vite-vue-i18n'
  4. // https://vitejs.dev/config/
  5. export default defineConfig({
  6. plugins: [vue(), I18n]
  7. })

经过上面的配置,我们就可以在界面中发现已解析了i18n的标签。
image.png

3. 如何使用

加载的插件是挂载到vue实例当中的,所以我们需要从实例中获取。

  1. <script lang="ts">
  2. import { defineComponent, ref, getCurrentInstance, computed } from 'vue'
  3. export default defineComponent({
  4. name: 'App',
  5. setup(){
  6. // 获取当前vue实例
  7. const ins: any = getCurrentInstance();
  8. const useI18n = () => {
  9. const locale = ref('zh');
  10. // 拿到实例中的i18n数据
  11. const i18n = ins.type.i18n;
  12. const t = (msg: string) => {
  13. // t 返回一个计算属性,动态取值
  14. return computed(() => i18n[locale.value][msg]).value;
  15. }
  16. return {t, locale};
  17. }
  18. const { locale, t } = useI18n();
  19. return { locale, t }
  20. }
  21. })
  22. </script>

vue模板文件

  1. <template>
  2. <label>{{t('language')}}</label>
  3. <select v-model="locale">
  4. <option value="en">en</option>
  5. <option value="zh">zh</option>
  6. </select>
  7. <p>{{t('message')}}</p>
  8. </template>

实现以上的功能,我们就完成啦。

😁