安装vite
你还可以通过附加的命令行选项直接指定项目名称和你想要使用的模板。例如,要构建一个 Vite + Vue + ts 项目,运行:- # npm 7+,需要添加额外的 --:
- npm create vite@latest my-vue-app -- --template vue-ts
复制代码 查看 create-vite 以获取每个模板的更多细节:vanilla,vanilla-ts, vue, vue-ts,react,react-ts,react-swc,react-swc-ts,preact,preact-ts,lit,lit-ts,svelte,svelte-ts,solid,solid-ts,qwik,qwik-ts。
你可以使用 . 作为项目名称,在当前目录中创建项目脚手架。
vite官网:https://cn.vitejs.dev/guide/
环境配置
在src中添加vue-shim.d.ts文件及内容:- /* eslint-disable */
- declare module '*.vue' {
- import { DefineComponent } from 'vue';
- const component: DefineComponent<{}, {}, any>;
- export default component;
- }
复制代码 目的是告诉TS如何处理.vue文件。
我们使用 DefineComponent 类型来注解 .vue 文件的默认导出,这是 Vue 3 中用于定义组件的类型。这个类型接受组件的 props、context 和其他选项作为泛型参数,但在这个简单的声明中,我们使用了空对象 {} 和 any 作为占位符,因为它们在这里主要是为了类型注解的完整性,并不会在运行时影响组件的行为。
SDK基础框架代码
sdk/libApp.vue:- <template>
- <p>msg:{{ msg }}</p>
- <p>appid:{{ appid }}</p>
-
- <button type="button" @click="increment">count is {{ count }}</button>
-
- </template>
复制代码 sdk/main.ts:- import { createApp } from "vue";
- import libApp from './libApp.vue';
- type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
- type VueApp = ReturnType<typeof createApp>;
- interface IMyLib {
- el: string;
- success?: (...args: any[]) => any;
- fail?: (...args: any[]) => any;
- [key: string]: any;
- }
- class MyLib {
- app: VueApp;
- el: string = '#app';
- /**
- * 构造函数
- *
- * @param appInstance VueApp 实例对象
- * @param options IMyLib 接口对象,包含可选参数 el,默认值为 '#app'
- */
- constructor(appInstance: VueApp,{el = '#app'}: IMyLib) {
- this.app = appInstance;
- this.el = el;
- this.render();
- }
- /**
- * 渲染组件
- *
- * @returns 无返回值
- */
- render() {
- this.app.mount(this.el);
- }
-
- /**
- * 为Vue应用实例添加全局配置
- *
- * @param app Vue应用实例
- * @param options 入参选项
- */
- static globalConfig(app: VueApp,options: IMyLib) {
- // 为app实例添加全局属性
- app.config.globalProperties.$options = options;
- }
- /**
- * 配置MyLib实例
- *
- * @param options IMyLib类型的配置项
- * @returns 返回Promise<MyLib>,表示MyLib实例的Promise对象
- */
- static config(options: IMyLib) {
- const opts: IMyLib = {
- success: () => {},
- fail: () => {},
- ...options
- }
- // 下面可以校验参数的合理性、参数的完整性等
- if(!opts.appid) {
- if (typeof opts.fail === 'function') {
- opts.fail('appid is required');
- return;
- }
-
- }
- const app = createApp(libApp);
- app.use({
- install(app: VueApp, opts: IMyLib) {
- MyLib.globalConfig(app, opts);
- }
- }, opts);
- const viteTest = new MyLib(app,opts);
- if (typeof opts.success === 'function') {
- opts.success(viteTest);
- }
- }
- }
- export default MyLib;
复制代码 插件安装、构建配置、编译
插件安装
安装vite-plugin-css-injected-by-js插件,其作用:打包时把CSS注入到JS中。- npm i vite-plugin-css-injected-by-js -D
复制代码 安装vite-plugin-dts插件,其作用:生成类型声明文件。
当然,也有人在 issue 中提出希望 Vite 内部支持在库模式打包时导出声明文件,但 Vite 官方表示不希望因此增加维护的负担和结构的复杂性。vite.config.ts
vite.config.ts配置如下:- import { defineConfig } from 'vite'
- import vue from '@vitejs/plugin-vue'
- import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
- import dts from "vite-plugin-dts";
- // https://vitejs.dev/config/
- export default defineConfig({
- plugins: [
- vue(),
- cssInjectedByJsPlugin(),
- dts({
- // 指定 tsconfig 文件
- tsconfigPath: 'tsconfig.build.json',
- rollupTypes: true
- })
- ],
- build: {
- lib: {
- entry: 'sdk/main.ts',
- formats: ['es'],
- name: 'myLib',
- fileName: 'my-lib',
- },
- rollupOptions: {
- // 确保外部化处理那些你不想打包进库的依赖
- external: ['vue'],
- output: {
- // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
- globals: {
- vue: 'Vue',
- },
- },
- },
- }
- })
复制代码 添加tsconfig.build.json代码:- {
- "compilerOptions": {
- "target": "ES2020",
- "useDefineForClassFields": true,
- "module": "ESNext",
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "skipLibCheck": true,
- "declaration": true,
- "declarationDir": "./dist/types",
-
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "isolatedModules": true,
- "moduleDetection": "force",
- "noEmit": true,
- "jsx": "preserve",
-
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["sdk/**/*.ts","sdk/**/*.vue"],
- }
-
复制代码 vite-plugin-dts地址:https://www.npmjs.com/package/vite-plugin-dts
库包编译
执行:在dist下存在如下构建文件:
- my-lib.d.ts(声明文件)
- my-lib.js(库文件)
生成的my-lib.d.ts文件内容如下:- import { createApp } from 'vue';
- declare interface IMyLib {
- el: string;
- success?: (...args: any[]) => any;
- fail?: (...args: any[]) => any;
- [key: string]: any;
- }
- declare class MyLib {
- app: VueApp;
- el: string;
- /**
- * 构造函数
- *
- * @param appInstance VueApp 实例对象
- * @param options IMyLib 接口对象,包含可选参数 el,默认值为 '#app'
- */
- constructor(appInstance: VueApp, { el }: IMyLib);
- /**
- * 渲染组件
- *
- * @returns 无返回值
- */
- render(): void;
- /**
- * 为Vue应用实例添加全局配置
- *
- * @param app Vue应用实例
- * @param options 入参选项
- */
- static globalConfig(app: VueApp, options: IMyLib): void;
- /**
- * 配置MyLib实例
- *
- * @param options IMyLib类型的配置项
- * @returns 返回Promise<MyLib>,表示MyLib实例的Promise对象
- */
- static config(options: IMyLib): void;
- }
- export default MyLib;
- declare type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
- declare type VueApp = ReturnType<typeof createApp>;
- export { }
复制代码 验证插件包
由于是在本地构建生成的文件在本地,没有上传到npm,把本地生成的声明文件可以拷贝到src下或者types目录下。
我们把my-lib.js文件也拷贝到src目录下进行验证,我们调整src/App.vue下代码如下:- <template>
-
-
-
- <img src="https://www.cnblogs.com/vite.svg" alt="Vite logo" />
-
-
- <img src="https://www.cnblogs.com/./assets/vue.svg" alt="Vue logo" />
-
-
- <HelloWorld msg="Vite + Vue" />
- </template>
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |