前言
在之前介绍了 Web Component 组件库有什么优势,这篇讲一下如何使用 Stencil 搭建 web component 组件库
Stencil 是一个开源的编译器,用于构建可复用、可扩展的 Web Component 组件库,是由 Ionic 团队开源的,方面我们以一种简单高效的方式来创建和管理 Web Component 组件库。
为什么选择Stencil
选择 Stencil 的原因在于它的跨框架兼容性、性能优化以及对标准 Web Components 的支持
Stencil的优势和特点
- 性能优化:自动懒加载、异步渲染等特性使得组件加载更快。
- 跨框架:生成的组件可以在多个框架中使用,如Vue、Angular、React等。
- JSX 支持:可以使用类似于 React 的方式来编写组件。
- TypeScript持:使用强类型语言来编写组件,提高了代码的可读性和可维护性
- 测试工具:提供了一套完整的测试工具,可以方便地进行单元测试和端到端测试。
- 社区支持:由Ionic团队维护,社区活跃,资源丰富。
Stencil 搭建开发环境
使用 Stencil 提供的脚手架安装项目,进入 packages
目录,执行创建命令
1 | shell复制代码# npm |
执行完后出现交互性的界面,有三种模式,构建组件库选择第一个 component
- component:是构建一个可以用到任何地方的 Web Components 组件库
- app:是用来构建一个静态网站或者一个应用,支持路由
- ionic-pwa:构建一个 pwa 应用
选择“component”选项将提示您输入项目的名称。
1 | css复制代码✔ Pick a starter › component |
成功创建我们的项目之后,CLI将向控制台输出如下内容
安装依赖,执行 npm start
启动项目
目录结构
初始化目录结构,最外层的目录结构
- dist、loader:默认的输出目录,编译后的文件
- src:源文件目录,包含了组件的代码、样式和测试
- tsconfig.json 是用来配置 ts 的一些 config 配置。
- www :启动本地开发环境后,经过 stencil 编译后 src 的 js 文件和
index.html
会被执行复制过移动到 www 文件夹中去,而启动的热服务器(live server)访问就会被映射到此文件夹,从而进行渲染和调试。
1 | lua复制代码├── dist |
组件和配置目录结构
创建组件
在新建项目后,package.json
默认添加了如下脚本命令,其中 stencil generate
是创建组件的命令
1 | json复制代码{ |
运行 pnpm generate
,提示创建的组件是否要添加 样式、单元测试、端对端测试文件
输入组件名称 my-button
,直接回车在 components
目录下创建一个 my-button
组件目录
Stencil 使用 tsx
进行开发,类似 react ,提供完整的声明周期函数和装饰器等功能,查看 my-component.tsx
文件
- @Component() 声明一个新的 Web 组件
- @Prop() 声明一个公开的属性/属性
1 | jsx复制代码import { Component, Prop, h } from '@stencil/core'; |
使用组件像普通 html
标签一样使用,传入 first
、last
会被 @Prop
声明的属性接收,修改它们的值,组件内部会响应式的更新渲染视图
1 | jsx复制代码<my-component first="Stencil" last="'Don't call me a framework' JS"></my-component> |
stencil 工作原理
入口文件
src/index.html
是用来启动本地 dev 环境时候的一个入口文件,在初始化过程中,它会默认添加需要的 js 产物的路径,如下:
1 | html复制代码 <head> |
在启动后,根据 stencil.config.ts
命名空间字段设置如 namespace: 'editor'
,会将编译 js 文件生成在 dist/editor
目录下,同时会拷贝一份到 www/build
文件夹提供给服务器访问,src/index.html
也会一并被复制过去
可以看到在启动后服务器访问的 js 目录 www/build
和 dist/editor
文件是一样的
www 本地调式目录
在启动本地命令 stencil build --dev --watch --serve
后,改动下组件的内容后会发现,www
文件夹内的资源文件也随之更新,浏览器相应界面的也发生变化,执行逻辑
所以 www
文件夹存放的是开发调试所包含资源文件,build
文件夹是编译的产物;host.config.json
会存放一些本地热更新服务器的配置,比如缓存的配置等;而 index.html
则是经过压缩的 src/index.html
文件。
stencil.config.ts 配置
stencil.config.ts
文件是 stencil 工具的配置文件,可以在此个性化的配置打包功能,比如:
- globalScript:全局脚本入口文件,可以用来实现在初始化组件,进行挂载的时候进行一些逻辑的处理
- globalStyle: 全局的样式路径,如设置
var
函数的主题变量 - plugins 插件: 配置一些编译过程中的额外功能,比如
sass
插件可以用来适配scss
文件的编译,postcss
可以用来压缩、增加一些兼容性的代码来适配各种浏览器等等,官方还提供了以下插件:@stencil/less
、@stencil/postcss
、@stencil/sass
、@stencil/stylus
- outputTargets:根据配置 target 进行打包
dist / loader 打包产物
执行 pnpm run build
命令进行打包,最终生成编译产物如下,包括 dist
和 loader
两个目录
通过观察 stencil
默认生成的 package.json
文件中 files
自动的配置也能知道,最终输出的文件资源 dist
和 loader
发布到 npm 上
1 | json复制代码"files": [ |
那么这两个文件夹有什么关系呢,我们先看下 loader 文件夹 package.json
的内容和其他文件的内容
loader 目录
1 | json复制代码{ |
可以看出,loader 文件夹是兼容 ESModule
和 Common.js
模块规范,根据当前的使用环境,分别引入 dist 的不同的文件夹产物内,比如 cjs 的引入类型会加载 ../dist/cjs/loader.cjs.js
;es6+ 的引入会加载 polyfills
文件和 esm 模式的资源文件 ../dist/esm/loader.js
。
dist 目录
在默认的 stencil.config.ts 配置下,打包结果为
1 | 复制代码├── cjs |
其中 cjs 和 esm 的逻辑几乎相同,esm 只是多了一些兼容性的代码,它们都是为了适配不同的环境所构造的不同产物
stencil 初始化配置里面默认包含了 dist-custom-elements
,意思就是可以单独打包出符合 web components 规范的组件 class
打包的组件单独引入会进行自动注册
1 | js复制代码import { HelloWorld } from 'my-library/dist/components/hello-world'; |
打包的文件夹的内容与 www/build
文件内容相同,因为 stencil 也默认开启了 www 编译的 outTarget,所以也会编译出一份可以直接用于本地环境的文件
1 | json复制代码outputTargets: [ |
如果能对新技术开发组件库感兴趣,也欢迎加入stencil-component-ui,给个 star 鼓励一下 👏👏
本文转载自: 掘金