如何让 vite + vue3 项目自动注册 vue 插件

547 阅读2分钟

起步

创建项目

首先需要创建一个 vite 项目

npm create vite


进入项目

创建项目之后是在项目之外,我们需要进入到项目中。

请将以下的 project 替换为你的项目名称

cd project

或者用 vscode 打开

code project


安装依赖

创建完的 vite 项目是未安装 node_modules 依赖的,所以需要安装依赖

npm i


运行项目

最后可以运行下项目看看有没有问题

npm run dev

start.gif



模块自动加载

仓库

模块自动加载插件 npm 包已实现,具体可见该仓库 👉 vite-plugin-use-modules



原理

Glob 导入

vite 中有个非常好用的功能叫做 Glob 导入

例如你可以通过下边的方式自动引入 src/modules 下的所有 js 模块

const modules = import.meta.globEager(
	'/src/modules/**/*.js'
)

console.log(modules) // 将以对象的方式输出到前端控制台

globEager.gif



自动注册

根据上边的原理,我们就可以自动注册 vue 模块

例如注册 pinia

npm i pinia -D

然后创建模块 src/modules/pinia.js

// src/modules/pinia.js
import { createPinia } from 'pinia'

export default app => app.use(createPinia())

然后在 src/main.js 下书写以下代码

import App from './App.vue'
import { createApp } from 'vue'

const app = createApp(App)

// 引入所有模块
const modules = import.meta.globEager(
	'/src/modules/**/*.js'
)
// 安装插件
Object.values(modules).forEach(module => {
	if (typeof module.default === 'function') {
		module.default(app)
	}
})

app.mount('#app')

以上就算自动注册 pinia 成功了,可以创建 src/stores/counter.js 验证一下

// src/stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
	state() {
		return {
			counter: 0
		}
	},
	actions: {
		inc() {
			this.counter++
		}
	}
})

最后就可以在 src/App.vue 中使用了

<script setup>
	import { useCounterStore } from './stores/counter'

	const store = useCounterStore()
</script>

<template>
	<div @click="store.inc()">{{ store.counter }}</div>
</template>

autoUse.gif



虚拟模块

我们都知道 vite 插件里有个非常好用的虚拟文件或者虚拟模块功能

例如我们可以创建一个 plugins/foo.js 插件

// plugins/foo.js
// 虚拟模块 id
const virtualModuleId = 'msg'
// 处理之后的虚拟模块 id
const resolvedVirtualModuleId = '\0' + virtualModuleId
// 虚拟模块代码
const code = `export default 100`

export default {
	name: 'foo',
	resolveId(id) {
		if (id === virtualModuleId) {
			return resolvedVirtualModuleId
		}
	},
	load(id) {
		if (id === resolvedVirtualModuleId) {
			return code
		}
	}
}

然后我们需要注册该插件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import foo from './plugins/foo'

export default defineConfig({
	plugins: [vue(), foo]
})

最后就可以在前端里引入该虚拟模块了,例如 src/main.js

// ...
import msg from 'msg'

console.log(msg) // 将在前端控制台输出 100
// ...

virtualModule.gif




实现

同理,我们也可以创建携带 Glob 导入 实现自动注册 vue 模块的代码

首先创建 plugins/use-modules.js 插件

export default () => {
	const virtualModuleId = 'virtual:modules'
	const resolvedVirtualModuleId = '\0' + virtualModuleId

	const code = `
export const modules = import.meta.globEager(
    '/src/modules/**/*.js'
)

export const useModules = app => {
    Object.values(modules).forEach(module => {
        if (typeof module.default === 'function') {
            module.default(app)
        }
    })
}`

	return {
		name: 'vite-plugin-use-modules',
		resolveId(id) {
			if (id === virtualModuleId) {
				return resolvedVirtualModuleId
			}
		},
		load(id) {
			if (id === resolvedVirtualModuleId) {
				return code
			}
		}
	}
}

然后注册一下插件

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Modules from './plugins/use-modules'

export default defineConfig({
	plugins: [vue(), Modules()]
})

最后就可以在 main.js 中愉快的使用模块自动加载了

import App from './App.vue'
import { createApp } from 'vue'
import { useModules } from 'virtual:modules'

const app = createApp(App)

useModules(app)

app.mount('#app')

useModules.gif

频道

接下来也会在 哔哩哔哩 中分享,欢迎关注哦!!