Appearance
创建项目
这个项目的包管理工作选择目前比较流行的 Pnpm 完成。选择 Pnpm ,首先是由于 Pnpm 优秀的管理机制,使得安装依赖非常迅速且节省空间。更重要的是,项目后期需要开发组 件库的周边,比如 CLI 工具等。CLI 工具以单独软件包的形式发布在 npm 仓库之中,这 样的话,一个 Repo 多个软件包的项目结构需要使用 monorepo 风格进行管理。pnpm 拥 有的 workspace 功能可以很好地完成这样的工作。
从零开始自己搭建 Vite 项目
## 初始化项目
pnpm init
## 安装vite
pnpm i vite@"3.0.7" -D
在根目录下新建 index.html、src/index.ts,代码
##index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Hello Smarty UI</h1>
<script src="./src/index.ts" type="module"></script>
</body>
</html>
## src/index.ts
const s: string = 'Hello Typescript'
console.log(s)
vite 无需任何配置就可以提供一个Typescript 的前端开发环境,支持自动热更新
。
在 package.json 添加脚本命令
"dev": "vite"
运行
pnpm run dev
开发一个 Vue 组件
## 安装 Vue3.0 软件包
pnpm i vue@"3.2.37"
编写一个简单的 Button 组件
## /src/button/index.ts
import { defineComponent, h } from "vue";
export default defineComponent({
name: "SButton",
// template:'<button>MyButton</button>'
render() {
return h("button", null, "MyButton");
},
});
在 src/index.ts 中启动 Vue 实例
import { createApp } from "vue";
import SButton from "./button";
createApp(SButton).mount("#app");
在 index.html 中添加一个容器。
<div id="app"></div>
<script src="./src/index.ts" type="module"></script>
支持 Vue 单文件 (SFC) 组件
Vue3.0 默认的包是不支持模板编译功能的,Vite 默认只能支持 TS 代码。而 Vue 的模 板需要在编译阶段转换为 Typescript 代码 (渲染函数)才可以运行
安装 Vite 的 Vue 插件
pnpm i @vitejs/plugin-vue@"3.0.3" -D
添加一个 vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
});
编写一个 SFC 单文件组件
src/button/SFCButton.vue
<template>
<button>SFC Button</button>
</template>
<script lang="ts">
export default {
name: "SFCButton",
};
</script>
引用到 index.ts 中测试一下。
import { createApp } from "vue";
import SFCButton from "./button/SFCButton.vue";
createApp(SFCButton)
.mount("#app");
在引用 .vue 模块时候,编辑器中 import 语句会有红色的警告。这是因为 Typescript 默 认是不支持 .vue 类型的模块的。可以通过添加一个模块的类型定义
来解决这个问题。
src/shims-vue.d.ts
declare module "*.vue" {
import { DefineComponent } from "vue";
const component: DefineComponent<{}, {}, any>;
export default component;
}
为避免报错,请使用 16 版本的 node,升级 node 参考文章
库文件封装
参考一下 Element 的使用指南。可以看到组件库有两种引入形态:
- 完整引入 :一次性引入全部组件,使用 Vue.use 以 Vue 插件的形式引入;
- 按需引入 :按需引入,导出单个组件,使用 Vue.component 注册。
import Vue from 'vue'
import Element from 'element-ui'
// 完整引入
Vue.use(Element)
// or
import {
Select,
Button
// ...
} from 'element-ui'
// 按需引入
Vue.component(Select.name, Select)
Vue.component(Button.name, Button)
实现一个 Vue 插件,插件中编写 install 方法,将所有组件安装到 vue 实例中:
/src/entry.ts
import { App } from "vue";
import MyButton from "./button";
import SFCButton from "./button/SFCButton.vue";
// 导出单独组件
export { MyButton,SFCButton };
// 编写一个插件,实现一个install方法
export default {
install(app: App): void {
app.component(MyButton.name, MyButton);
app.component(SFCButton.name, SFCButton);
}
};
默认 Vite 就是可以支持构建,使用 Vite 的 build 命令就可以打包输出。如果导出的是一个库文件的话,还需要配置【导出模块类型】并确定导出的文件名。配置如下:
vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
const rollupOptions = {
external: ["vue", "vue-router"],
output: {
globals: {
vue: "Vue",
},
},
};
export default defineConfig({
plugins: [
vue(), // 添加JSX插件
],
// 添加库模式配置
build: {
rollupOptions,
minify:false,
lib: {
entry: "./src/entry.ts",
name: "SmartyUI",
fileName: "smarty-ui",
// 导出模块格式
formats: ["esm", "umd","iife"],
},
},
});
添加一个 npm 运行脚本
package.json
"scripts": {
"build": "vite build"
},
测试
新增 demo 目录测试
测试加载全部组件:
// demo/esm/index.html
<h1>Demo</h1>
<div id="app"></div>
<script type="module">
import { createApp } from "vue/dist/vue.esm-bundler.js";
import SmartyUI, { SFCButton } from "../../dist/smarty-ui.esm.js";
createApp({
template: `
<SFCButton/>
`}).use(SmartyUI).mount('#app')
</script>
加载单独组件:
// demo/esm/button.html
<h1>Demo</h1>
<div id="app"></div>
<script type="module">
import { createApp } from "vue/dist/vue.esm-bundler.js";
import SmartyUI, {
SFCButton
} from "../../dist/smarty-ui.esm.js";
createApp({
template: `
<SFCButton/>
`,
})
.component(SFCButton.name, SFCButton)
.mount("#app");
</script>
项目跑起来:pnpm run dev
,打开
http://localhost:5173/demo/esm/index.html