@ithinkdt/vite
v4.0.8
Published
iThinkDT Vite Plugin
Readme
@ithinkdt/vite
许可证
MIT
安装
npm i -D @ithinkdt/vite需要您自行安装 peer 依赖
vite@>=8、vue@>=3.5、vue-router@>=5。如果使用 Iconify、SVG 优化或 PostCSS 工具,需要额外安装@iconify/json@>=2.2、svgo@>=3.3、postcss@>=8.5。
介绍
@ithinkdt/vite 提供 iThinkDT 前端项目常用 Vite 插件与构建工具,包括:
- Vue、Vue JSX、文件系统路由、组件自动导入、依赖自动导入预设
- SVG 文件转 Vue 组件
- 生产 chunk 命名优化
- Iconify 图标集构建期复制与运行期加载
- 子应用联邦构建入口
- 低代码渲染器构建入口
- 部署用 Koa 静态服务脚本生成
- legacy polyfill、gzip 压缩、构建分析工具转出
ithinkdt-ui组件自动导入 resolver- PostCSS 选择器替换插件
快速开始
/// <reference types="node" />
import path from 'node:path'
import { compression, deploy, federate, iconify, polyfill, presets, visualizer } from '@ithinkdt/vite'
import { IthinkdtUiResolver } from '@ithinkdt/vite/resolvers'
import unocss from 'unocss/vite'
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(async ({ command, mode }) => {
const { BASE_URL, VITE_DEBUG } = loadEnv(mode, '.', '')
const debug = command === 'serve' || VITE_DEBUG === 'true'
return {
base: BASE_URL,
envPrefix: ['DT_'],
resolve: {
alias: [
{ find: '@', replacement: path.resolve('./src') },
],
},
build: {
sourcemap: debug,
reportCompressedSize: debug,
},
plugins: [
presets({
components: {
resolvers: [
IthinkdtUiResolver(),
],
},
}),
unocss(),
iconify(),
federate({ setupEntry: './federate.ts' }),
polyfill({
modernPolyfills: true,
renderLegacyChunks: false,
}),
deploy(),
!debug && compression({ algorithms: ['gz'], threshold: 32 * 1024 }),
debug && visualizer({ emitFile: true }),
],
}
})插件预设
presets(options?)
presets 会组合常用基础插件:
vue-router/vite:文件系统路由@vitejs/plugin-vue@vitejs/plugin-vue-jsxunplugin-vue-componentsunplugin-auto-importsvgchunk
import { presets } from '@ithinkdt/vite'
export default defineConfig({
plugins: [
presets({
pages: {
routesFolder: 'src/views',
},
components: {
dirs: ['src/components'],
},
autoImport: {
imports: [
'vue',
'pinia',
],
},
svgo: true,
}),
],
})默认行为:
| 能力 | 默认值 |
|------|--------|
| 路由目录 | src/views |
| 路由扩展名 | .vue |
| 路由类型声明 | src/shims-typed-router.d.ts |
| 组件目录 | src/components |
| 组件扩展名 | vue、tsx |
| 组件类型声明 | src/shims-global-components.d.ts |
| 自动导入目录 | src/composables/**、src/utils/**、src/constants/** |
| 自动导入类型声明 | src/shims-auto-imports.d.ts |
| 自动导入内置项 | vue、pinia、vue-router |
SVG 组件
svg(options?)
导入 *.svg?component 时会把 SVG 编译成 Vue render 函数。
import { svg } from '@ithinkdt/vite'
export default defineConfig({
plugins: [
svg({ svgo: true }),
],
})import Logo from './logo.svg?component'
export default {
setup() {
return () => <Logo class="h-8 w-8" />
},
}如果需要类型声明,在项目的 src/shims-typo.d.ts 中加入:
/// <reference types="@ithinkdt/vite/client-preset" />Chunk 命名
chunk()
生产构建时,根据 src 下入口模块路径生成更可读的 chunk 文件名,例如:
import { chunk } from '@ithinkdt/vite'
export default defineConfig({
plugins: [
chunk(),
],
})默认输出格式为 assets/[src-path]-[hash].js;[、] 会分别替换为 {、},便于动态路由文件名落盘。
Iconify
iconify()
iconify 会提供虚拟模块 @ithinkdt/iconify:
- 开发环境从
/node_modules/@iconify/json/json/加载图标集 - 生产构建时复制
@iconify/json/json/*.json到dist/iconify@<version>/
import { iconify } from '@ithinkdt/vite'
export default defineConfig({
plugins: [
iconify(),
],
})import iconify, { collSet, loader } from '@ithinkdt/iconify'
const mdi = await loader('mdi')
console.log(collSet.mdi, mdi)
console.log(iconify.loader)类型声明:
/// <reference types="@ithinkdt/vite/client-icons" />FileSystemIconLoader
该工具从 @iconify/utils 转出,常用于 UnoCSS presetIcons 本地图标集。
import path from 'node:path'
import { FileSystemIconLoader } from '@ithinkdt/vite'
import { defineConfig, presetIcons } from 'unocss'
export default defineConfig({
presets: [
presetIcons({
collections: {
assets: FileSystemIconLoader(path.resolve('./src/assets/icons')),
},
}),
],
})子应用联邦
federate(options?)
federate 用于构建 iThinkDT 子应用入口:
- 将
vue、vue-router作为 import map 外部依赖 - 构建并输出
subAppSetup.js - 输出共享库到
dist/libs/ - 提供虚拟模块
@ithinkdt/federate
import { federate } from '@ithinkdt/vite'
export default defineConfig({
plugins: [
federate({ setupEntry: './federate.ts' }),
],
})federate.ts 示例:
import { useSubApp } from '@ithinkdt/app/sub'
import type { RouteRecordRaw } from 'vue-router'
import setup from '@/setup/common'
export default function subAppSetup(app: import('vue').App) {
useSubApp(app)
return setup(app)
}
export const routes: RouteRecordRaw[] = [
{
path: '/users',
component: () => import('@/views/users.vue'),
},
]
export const namespace = import.meta.env.DT_APP_NAMESPACE类型声明:
/// <reference types="@ithinkdt/vite/client-federate" />低代码渲染入口
lowcode(options?)
lowcode 用于额外输出低代码渲染入口 lowcode.js,默认入口为 ./src/lowcode.ts。
import { lowcode } from '@ithinkdt/vite'
export default defineConfig({
plugins: [
lowcode({
renderEntry: './src/modules/lowcode/components/YidaRenderer.tsx',
}),
],
})构建后会输出:
import { default as YidaRenderer } from '<render-entry-chunk>'
export { YidaRenderer, YidaRenderer as default }部署服务
deploy(options?)
deploy 会在生产构建时输出可直接运行的 Koa 静态服务:
server.mjs:静态服务入口deploy-render.mjs:Koa 运行依赖打包产物package.json:运行服务所需的最小 package 信息- 可选
deploy-plugin.mjs:项目自定义服务脚本 - 向
index.html注入window.APP_ENV
import { deploy } from '@ithinkdt/vite'
export default defineConfig({
plugins: [
deploy({
servePort: 8080,
healthCheckPath: ['/status', '/health'],
serveFileName: 'server.mjs',
envVars: {
DT_CUSTOM_API: 'CUSTOM_API',
},
script: './deploy.server.ts',
}),
],
})自定义服务脚本会接收 Koa app 实例:
export default function setup(app) {
app.use(async (ctx, next) => {
ctx.set('X-App', 'iThinkDT')
await next()
})
}运行构建产物:
cd dist
npm start运行期环境变量:
| 环境变量 | 说明 |
|----------|------|
| APP_SERVE_PORT | 覆盖服务监听端口 |
| DT_APP_CODE | 注入为 window.APP_ENV.APP_CODE |
| DT_API_CTX | 注入为 window.APP_ENV.API_CTX |
| DT_BASE_URL | 当 Vite base 为相对路径时,作为运行期 base |
| APP_PKG_NAME | 覆盖启动日志中的应用名 |
| APP_VERSION | 覆盖启动日志中的版本号 |
类型声明:
/// <reference types="@ithinkdt/vite/client-deploy" />组件 Resolver
IthinkdtUiResolver
@ithinkdt/vite/resolvers 转出 unplugin-vue-components 的内置 resolver,并提供 IthinkdtUiResolver,用于自动导入 ithinkdt-ui 的 N* 组件。
import { IthinkdtUiResolver } from '@ithinkdt/vite/resolvers'
export default defineConfig({
plugins: [
presets({
components: {
resolvers: [
IthinkdtUiResolver(),
],
},
}),
],
})匹配示例:
<template>
<NButton type="primary">保存</NButton>
<n-input />
</template>PostCSS 工具
postcssSelectorReplace
用于在 PostCSS 阶段替换选择器字符串,常见场景是把占位选择器替换成运行项目的命名空间。
import { postcssSelectorReplace } from '@ithinkdt/vite/postcss'
import { loadEnv } from 'vite'
const { DT_APP_NAMESPACE } = loadEnv('production', '.', '')
export default {
plugins: [
postcssSelectorReplace({
replace: {
'[$DT_APP_NAMESPACE]': `.${DT_APP_NAMESPACE}`,
},
}),
],
}转出工具
@ithinkdt/vite 还转出了常用官方插件,便于项目统一从一个入口导入。
| 导出 | 来源 |
|------|------|
| polyfill | @vitejs/plugin-legacy |
| compression | vite-plugin-compression2 |
| visualizer | rollup-plugin-visualizer |
| FileSystemIconLoader | @iconify/utils/lib/loader/node-loaders |
类型声明入口
建议在项目的 src/shims-typo.d.ts 中按需加入:
/// <reference types="@ithinkdt/vite/client-preset" />
/// <reference types="@ithinkdt/vite/client-federate" />
/// <reference types="@ithinkdt/vite/client-icons" />
/// <reference types="@ithinkdt/vite/client-deploy" />| 类型入口 | 提供内容 |
|----------|----------|
| client-preset | *.svg?component 模块类型 |
| client-federate | @ithinkdt/federate 虚拟模块类型 |
| client-icons | @ithinkdt/iconify 虚拟模块类型 |
| client-deploy | window.APP_ENV 类型 |
API 参考
| 导出 | 说明 |
|------|------|
| presets(options?) | 基础插件预设 |
| svg(options?) | SVG 转 Vue 组件 |
| chunk() | 生产 chunk 命名优化 |
| iconify() | Iconify 图标集加载与复制 |
| federate(options?) | 子应用联邦构建入口 |
| lowcode(options?) | 低代码渲染器入口 |
| deploy(options?) | 部署服务脚本生成 |
| polyfill | legacy polyfill 插件 |
| compression | 压缩插件 |
| visualizer | 构建分析插件 |
| FileSystemIconLoader | 本地图标加载器 |
导入路径
import { presets, svg, chunk, iconify, federate, lowcode, deploy } from '@ithinkdt/vite'
import { IthinkdtUiResolver } from '@ithinkdt/vite/resolvers'
import { postcssSelectorReplace } from '@ithinkdt/vite/postcss'