2 组件 Runtime
一个常规的组件库目录应该是什么样的?不论是在一个单独的组件仓库,还是在一个已有的业务项目中,其实组件的目录结构大同小异,大致如下:
components
├── component1
│ ├── README.md
│ ├── index.scss
│ └── index.tsx
├── component2
│ ├── README.md
│ ├── index.scss
│ └── index.tsx
在我们的设想中你可以在任意一个项目中启动组件开发模式,在运行 vite-comp 之后就可以看到一个专门针对组件开发的界面,在上面已经帮你解析并渲染出来了在 README.md 中编写的组件 Usage,以及在 index.tsx 定义的 interface,只需要访问不同的文件路径,即可查看对应组件的表现形态。
同时,最后可以帮你可以将这个界面上的全部内容编译打包,截图发布到 NPM 上,别人看到这个组件将会清晰看到其组件入参,用法,截图等,甚至可以打开 Demo 地址,修改组件参数来查看组件不同状态下的表现形态。
如果要实现这样的效果,则需要一套组件运行的 Runtime 进行支持,这样才可以协调 React 组件、README.md、TypeScript 类型定义串联成我们所需要的组件调试+文档一体的组件开发页面。
在这样的 Runtime 中,同样需要借助 Vite 的模块解析能力,将其 URL 为 **/*/(README|*).html 的请求,转换为一段可访问的组件 Runtime Html 返回给浏览器,从而让浏览器运行真正的组件开发页面。
http://localhost:7000/components/component1/README.html
->
/components/component1/README.html
->
/components/component1/README.md
->
Runtime Html
3 组件 Props Interface
正如我上述内容中讲到的,如果利用 Vite 添加一个对 tsx 的组件 props interface 类型解析的能力,也可以做成独立插件用于解析 .tsx.type.json 结尾的文件类型,通过 import 这种类型的文件,从而让编译器动态解析其 tsx 文件中所定义的 TypeScript 类型,并作为模块返回给前端消费。
其加载过程就可以当做是一个虚拟的模块,可以理解为你可以通过直接 import 一个虚拟的文件地址,获取到对应的 React 组件元信息:
// React Component
import Component from './component1.tsx';
// React Component Props Interface
import ComponentTypeInfo from './component1.tsx.type.json';
// or
const ComponentTypeInfoPromise = import('./component1.tsx.type.json');
由于这种解析能力并不是借助于 esbuild 进行,所以在转换性能上无法和组件主流程编译同步进行。
在请求到该文件类型时,需要考虑在 Vite 的 Serve 模式下,新开线程进行这部分内容编译,由于整个过程是异步行为,不会影响组件主流程渲染进度。当请求返回响应后,再用于渲染组件 Props 定义及侧边栏面板部分。
在热更新过程中,同样需要考虑到 tsx 文件修改范围是否涉及到 TypeScript 类型的更改,如果发现修改导致类型变化时,再触发 HMR 事件进行模块更新。
三 组件 Build
以上都是在讨论组件在 Vite 的 Serve 态(也就是开发态)下的情况,我们上文中大量借助 Vite 利用浏览器 es module 的加载能力,从而做的一些开发态的动态加载能力的扩展。
但是 Vite 在组件最终 Build 过程中是没有 Server 服务启动,当然也不会有浏览器动态加载,所以为了让别人也可以看到我们开发的组件,能够体验我们开发时调试组件的样子,就需要考虑为该组件编译产出一份可以被浏览器运行的 html。
所以在 Vite 插件开发过程中,是需要考虑在 Build 状态下的编译路径的,如果是在 Build 状态下,Vite 将使用 Rollup 的编译能力,那么就需要考虑手动提供所有组件的 rollup.input(entries)。
在插件编写过程中,一定需要遵循 Rollup 所提供的插件加载生命周期,才能保证 Build 过程和 Serve 过程的模块加载逻辑和编译逻辑保持一致。
我一开始在实现的过程中,就是没有了解透彻 Vite 和 Rollup 的关系,在模块解析过程中依赖了大量 Vite 的 Server 提供的服务端中间件能力。导致在考虑到 Build 态时,才意识到其中的问题,最后几乎重新写了之前的加载逻辑。
四 总结
我姑且把这个方案(套件)称之为 vite-comp,其大致的构成就是由 Vite + 3 Vite Pugins 构成,每个插件相互不耦合,相互职责也不相同,也就是说你可以拿到任意一个 Vite 插件去做别的用途,后续会考虑单独开源,分别是:
结合 Vite,已经实现了 Vite 模式下的 React、Rax 组件开发,它相比于之前使用 Webpack 做的组件开发,已经体现出了以下几个大优势:
预览体验:
启动
Markdown 组件文档毫秒级响应
TypeScript 类型识别
Vite 现在还是只是刚刚起步,这种全新的编译模式,已经给我带来了非常多的开发态收益,结合 Vite 的玩法未来一定还会层出不穷,比如 Midway + lambda + Vite 的前端一体化方案也是看得让人拍案叫绝,在这个欣欣向荣的前端大时代,相信不同前端产物都会和 Vite 结合出下一段传奇故事。
我是一个热爱生活的前端工程师!Yooh!
前端开发技术图谱
6 大知识点,14 个课程,680 个课时,将前端开发知识和实战经验融入图谱,包含 HTML 、CSS、JavaScript 、jQuery 、Vue 、React 、Angular 、NodeJS 等前端开发必备技能,帮你迅速提升。
创业/副业必备:
本站已持续更新1W+创业副业顶尖课程,涵盖多个领域。
点击查看详情
评论(0)