安装vite
npm create vite@latest
你还可以通过附加的命令行选项直接指定项目名称和你想要使用的模板。例如,要构建一个 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:
msg:{{ msg }}
appid:{{ appid }}
sdk/main.ts:
import { createApp } from "vue";
import libApp from './libApp.vue';
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
type VueApp = ReturnType;
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实例的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 官方表示不希望因此增加维护的负担和结构的复杂性。
npm i vite-plugin-dts -D
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
库包编译
执行:
npm run build
在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实例的Promise对象
*/
static config(options: IMyLib): void;
}
export default MyLib;
declare type ReturnType any> = T extends (...args: any) => infer R ? R : any;
declare type VueApp = ReturnType;
export { }
验证插件包
由于是在本地构建生成的文件在本地,没有上传到npm,把本地生成的声明文件可以拷贝到src下或者types目录下。
我们把my-lib.js文件也拷贝到src目录下进行验证,我们调整src/App.vue下代码如下:
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容