Svelte组件库构建:从零开始打造自己的组件库
2022-03-246.3k 阅读
项目初始化
- 创建 Svelte 项目:
- 首先,确保你已经安装了
npm
(Node Package Manager),这是 JavaScript 的包管理工具。如果没有安装,可以从 Node.js 官网(https://nodejs.org/)下载并安装 Node.js,npm 会随 Node.js 一同安装。 - 使用
npm init svelte@latest
命令来初始化一个新的 Svelte 项目。执行该命令后,会提示你输入项目名称,例如my - component - library
。 - 接下来,会询问你一些关于项目模板的问题,比如是否使用 TypeScript,是否使用 ESLint 等。对于组件库项目,我们可以先选择不使用 TypeScript(后续可以再添加),也暂时不使用 ESLint(之后可以按需配置)。
- 进入项目目录:
cd my - component - library
。
- 首先,确保你已经安装了
- 安装必要依赖:
- 组件库通常需要进行打包,我们使用
rollup
来进行打包。rollup
是一个 JavaScript 模块打包器,它可以将多个小的模块打包成一个或多个大的文件,供浏览器或其他环境使用。 - 安装
rollup
及其相关插件:npm install --save - dev rollup rollup - plugin - commonjs rollup - plugin - json rollup - plugin - node - resolve rollup - plugin - svelte rollup - plugin - terser
rollup - plugin - commonjs
:用于将 CommonJS 模块转换为 ES6 模块,因为很多第三方库使用的是 CommonJS 规范,而 Svelte 项目使用 ES6 模块。rollup - plugin - json
:允许我们在项目中导入 JSON 文件。rollup - plugin - node - resolve
:帮助rollup
找到node_modules
中的模块。rollup - plugin - svelte
:用于处理 Svelte 组件,将 Svelte 组件编译为 JavaScript 代码。rollup - plugin - terser
:用于压缩打包后的代码,减小文件体积。
- 为了在开发过程中方便地预览组件,我们安装
svelte - kit
:npm install --save - dev @sveltejs/kit
- 组件库通常需要进行打包,我们使用
目录结构规划
- src 目录:
- components:这个文件夹将存放我们所有的组件。例如,我们可以创建一个
Button
组件,它的文件结构如下:src/components/Button ├── Button.svelte ├── Button.css ├── index.js
Button.svelte
是 Svelte 组件的主体文件,包含组件的 HTML、CSS 和 JavaScript 逻辑。Button.css
是组件的样式文件,采用局部作用域,只会应用到Button
组件内部。index.js
用于将Button.svelte
组件导出,方便在其他地方导入使用。例如:import Button from './Button.svelte'; export default Button;
- styles:存放全局样式文件,比如一些通用的字体设置、颜色变量等。例如,我们可以创建一个
variables.css
文件::root { --primary - color: #007BFF; --secondary - color: #6C757D; }
- utils:这个文件夹用于存放一些工具函数。比如,我们可能有一个
formatDate.js
文件,用于格式化日期:export function formatDate(date) { const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const day = date.getDate().toString().padStart(2, '0'); return `${year}-${month}-${day}`; }
- components:这个文件夹将存放我们所有的组件。例如,我们可以创建一个
- rollup.config.js:
- 在项目根目录创建
rollup.config.js
文件,这是rollup
的配置文件。内容如下:
import svelte from 'rollup - plugin - svelte'; import commonjs from 'rollup - plugin - commonjs'; import resolve from 'rollup - plugin - node - resolve'; import json from 'rollup - plugin - json'; import terser from 'rollup - plugin - terser'; const production =!process.env.ROLLUP_WATCH; export default { input:'src/index.js', output: [ { file: 'dist/my - component - library.js', format: 'umd', name:'myComponentLibrary', sourcemap: true }, { file: 'dist/my - component - library.esm.js', format: 'esm', sourcemap: true } ], plugins: [ svelte({ compilerOptions: { dev:!production } }), resolve({ browser: true, dedupe: ['svelte'] }), json(), commonjs(), production && terser() ] };
- 这里配置了
rollup
的输入文件为src/index.js
,输出两个文件,一个是 UMD 格式(适用于浏览器全局变量引入),另一个是 ESM 格式(适用于现代 JavaScript 模块系统)。同时,配置了各个插件的使用。
- 在项目根目录创建
组件开发示例 - Button 组件
- Button.svelte:
<script> import { onMount } from'svelte'; import styles from './Button.css'; let buttonText = 'Click me'; let isDisabled = false; const handleClick = () => { console.log('Button clicked'); }; onMount(() => { console.log('Button mounted'); }); </script> <button {isDisabled} class={styles.button} on:click={handleClick}> {buttonText} </button>
- 在
script
标签内,我们导入了onMount
生命周期函数,用于在组件挂载到 DOM 后执行一些操作。同时导入了本地的 CSS 样式文件Button.css
。 - 定义了
buttonText
和isDisabled
两个变量,分别用于显示按钮文本和控制按钮是否禁用。 handleClick
函数是按钮点击时执行的逻辑,这里简单地在控制台打印一条信息。- 在
button
标签上,通过{isDisabled}
绑定按钮的禁用状态,通过class={styles.button}
应用本地 CSS 样式,通过on:click={handleClick}
绑定点击事件。
- 在
- Button.css:
.button { padding: 10px 20px; background - color: var(--primary - color); color: white; border: none; border - radius: 5px; cursor: pointer; }
.button:disabled { background - color: var(--secondary - color); cursor: not - allowed; }
- 这里定义了按钮的基本样式,包括背景颜色、文字颜色、边框等。同时,定义了按钮禁用时的样式。
### 组件导出与引用
1. **在 src/index.js 中导出组件**:
- 在 `src/index.js` 文件中,我们需要将所有组件导出,以便外部使用。假设我们只有 `Button` 组件,文件内容如下:
```javascript
import Button from './components/Button/index.js';
export { Button };
- 在项目中引用组件:
- 如果我们在项目的
App.svelte
中想要使用Button
组件,可以这样做:
<script> import { Button } from './src'; </script> <main> <Button buttonText="Custom text" /> </main> <style> main { padding: 20px; } </style>
- 首先在
script
标签中导入Button
组件,然后在main
标签内使用Button
组件,并通过buttonText
属性传递自定义的按钮文本。
- 如果我们在项目的
文档编写
- 使用工具生成文档:
- 对于 Svelte 组件库,我们可以使用
svelte - docgen
来生成文档。首先安装它:npm install --save - dev svelte - docgen
- 在
package.json
中添加脚本:"scripts": { "generate:docs": "svelte - docgen src/components - o docs" }
- 上述脚本会扫描
src/components
目录下的所有 Svelte 组件,并在docs
目录生成文档。
- 对于 Svelte 组件库,我们可以使用
- 手动编写文档:
-
除了使用工具生成文档,我们也可以手动编写详细的文档。在项目根目录创建一个
docs
文件夹。 -
对于
Button
组件,可以创建一个Button.md
文件,内容如下:Button 组件
概述
Button
组件用于触发操作,是用户与界面交互的重要元素。使用方法
<script> import { Button } from './src'; </script> <Button buttonText="Custom text" />
属性
- buttonText:类型为字符串,用于设置按钮显示的文本,默认值为
'Click me'
。 - isDisabled:类型为布尔值,用于控制按钮是否禁用,默认值为
false
。
事件
- click:按钮被点击时触发,在组件内部的
handleClick
函数中定义了点击后的逻辑(当前为在控制台打印信息)。
- buttonText:类型为字符串,用于设置按钮显示的文本,默认值为
-
测试组件
- 安装测试框架:
- 对于 Svelte 组件,我们可以使用
vitest
和@testing - library/svelte
来进行测试。首先安装它们:npm install --save - dev vitest @testing - library/svelte
- 在
package.json
中添加测试脚本:"scripts": { "test": "vitest" }
- 对于 Svelte 组件,我们可以使用
- 编写测试用例 - 以 Button 组件为例:
- 在
src/components/Button
目录下创建Button.test.js
文件:
import { render, screen } from '@testing - library/svelte'; import Button from './Button.svelte'; describe('Button component', () => { it('should display the correct text', () => { render(Button, { buttonText: 'Test text' }); const buttonElement = screen.getByText('Test text'); expect(buttonElement).toBeInTheDocument(); }); it('should call the click handler', () => { const handleClick = vi.fn(); render(Button, { buttonText: 'Click me', handleClick }); const buttonElement = screen.getByText('Click me'); buttonElement.click(); expect(handleClick).toHaveBeenCalled(); }); });
- 第一个测试用例
should display the correct text
检查按钮是否显示了正确的文本。通过render
函数渲染Button
组件,并传递buttonText
属性,然后使用screen.getByText
获取按钮元素,并通过expect
断言按钮元素在文档中。 - 第二个测试用例
should call the click handler
检查按钮点击时是否调用了点击处理函数。通过vi.fn()
创建一个模拟函数handleClick
,传递给Button
组件,点击按钮后,使用expect(handleClick).toHaveBeenCalled()
断言模拟函数被调用。
- 在
发布组件库
- 准备工作:
- 确保在
package.json
中设置了正确的name
、version
、description
、main
(指向打包后的 UMD 文件路径,例如dist/my - component - library.js
)、module
(指向打包后的 ESM 文件路径,例如dist/my - component - library.esm.js
)等字段。 - 例如:
{ "name": "my - component - library", "version": "1.0.0", "description": "My custom Svelte component library", "main": "dist/my - component - library.js", "module": "dist/my - component - library.esm.js", "scripts": { "build": "rollup - c", "generate:docs": "svelte - docgen src/components - o docs", "test": "vitest" }, "keywords": [ "svelte", "components", "library" ], "author": "Your Name", "license": "MIT" }
- 确保在
- 发布到 npm:
- 首先,确保你已经在 npm 官网(https://www.npmjs.com/)注册了账号。
- 登录 npm:在终端执行
npm login
,按照提示输入用户名、密码和邮箱。 - 构建组件库:执行
npm run build
命令,生成打包后的文件。 - 发布组件库:执行
npm publish
命令,将组件库发布到 npm 仓库。发布成功后,其他开发者就可以通过npm install my - component - library
来安装和使用你的组件库了。
通过以上步骤,我们就从零开始打造了一个 Svelte 组件库,涵盖了项目初始化、组件开发、文档编写、测试以及发布等各个方面。在实际开发中,可以根据具体需求不断扩展和完善组件库的功能和组件种类。