-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* docs: 添加文档《MorJS 使用社区组件库指南》 * docs: 添加如何编写一个多端组件库的教程
- Loading branch information
Showing
3 changed files
with
331 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
website/docs/guides/advance/learn-create-component-library.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
# 五分钟教会你如何让小程序组件库支持多端 | ||
|
||
## 背景 | ||
|
||
上文 [《MorJS 使用社区组件库指南》](https://mor.eleme.io/guides/advance/use-community-component) 我们提到了 MorJS 能够支持在业务转端的同时,将业务所引用的社区组件库一同转端,而针对很多定制属性较强的项目,大多会自行维护一套组件库提供给多个项目使用,本文教会你如何让你的小程序组件库支持多端,与上文的区别在于: | ||
|
||
- 上文是将社区组件库作为源码的一部分,通过 MorJS 编译业务代码的同时,将 node_modules 中的组件也作为源码编译的一部分,生成能够在不同端运行的产物; | ||
- 本文是将小程序组件库单独编译,生成能够分别在不同端引入使用的组件进行发包,支持不同项目自行引用 npm 包,组件库与业务、框架解耦; | ||
|
||
## 已有组件库快速上手 | ||
|
||
组件库转端需要使用 MorJS 提供的一码多端能力,总体流程为: | ||
|
||
项目接入 MorJS => 添加多端编译配置 => 配置脚本 => 编译构建生成产物 => 发包 | ||
|
||
### 接入 MorJS | ||
|
||
在组件库项目中添加必要的依赖: | ||
|
||
```shell | ||
$ npm i @morjs/cli -D && npm i @morjs/core --save | ||
``` | ||
|
||
### 添加配置文件 | ||
|
||
在项目根目录下增加文件 mor.config.ts,修改需要编译的配置 | ||
|
||
```typescript | ||
import { defineConfig, UserConfig } from '@morjs/cli' | ||
|
||
// 公共配置 | ||
const CommonConfig: UserConfig = { | ||
sourceType: 'wechat', // 源码类型: 微信 DSL | ||
srcPath: './src/components', // 源码目录,指定组件库源代码所在的目录 | ||
compileMode: 'default', // 编译模式,由于组件库不是完整项目,需使用转换模式编译 | ||
autoInjectRuntime: { | ||
// 运行时自动注入配置 | ||
api: 'minimal' // API 运行时抹平注入,使用最小替换将仅替换函数调用 | ||
}, | ||
compilerOptions: { | ||
// ts 编译配置 | ||
esModuleInterop: false, // 开启 ES 模块互操作性,针对 ES Module 提供 Commonjs 兼容 | ||
declaration: true, // 生成 (.d.ts) 文件 | ||
target: 'ES5', // 输出的 ES 版本 | ||
module: 'CommonJS' // 模块输出类型 | ||
} | ||
} | ||
|
||
export default defineConfig([ | ||
// 第一套配置: 微信 DSL 编译 | ||
{ | ||
...CommonConfig, | ||
name: 'wx', | ||
target: 'wechat', // 编译目标: 微信 | ||
outputPath: './miniprogram_dist/lib' // 输出产物目录 | ||
}, | ||
// 第二套配置: 微信转支付宝 | ||
{ | ||
...CommonConfig, | ||
name: 'ali', | ||
target: 'alipay', // 编译目标: 支付宝 | ||
outputPath: './alipay/lib' // 输出产物目录 | ||
}, | ||
// 第三套配置: 微信转抖音 | ||
{ | ||
...CommonConfig, | ||
name: 'dy', | ||
target: 'bytedance', // 编译目标: 抖音 | ||
outputPath: './bytedance/lib' // 输出产物目录 | ||
}, | ||
// 第四套配置: 微信转 Web | ||
{ | ||
...CommonConfig, | ||
name: 'web', | ||
target: 'web', // 编译目标: Web | ||
outputPath: './lib' // 输出产物目录 | ||
} | ||
]) | ||
``` | ||
|
||
### 编译调试 | ||
|
||
在项目目录终端下执行编译命令启动项目,即可构建生成对应的多端产物,分别用对应平台的 IDE 打开即可开发预览。 | ||
|
||
你也可以针对不同端,在 package.json 中添加单端的编译命令和相关配置,在终端执行对应的编译命令生成单端的编译产物进行开发调试。 | ||
|
||
相关文档可参考:[《MorJS 基础用法 - 命令行》](https://mor.eleme.io/guides/basic/cli) | ||
|
||
```json | ||
{ | ||
"name": "my-component", | ||
"version": "1.0.0", | ||
"scripts": { | ||
"build": "mor compile --production", // 开启生产环境构建所有端 | ||
"dev:wx": "mor compile --name wx", // 编译构建配置名为 wx 的产物 | ||
"dev:ali": "mor compile --name ali --production", // 编译构建配置名为 ali 的产物 | ||
"dev:dy": "mor compile --name dy --production" // 编译构建配置名为 dy 的产物 | ||
} | ||
} | ||
``` | ||
|
||
### 构建发包 | ||
|
||
在项目目录终端执行打包构建命令编译项目,生成对应的多端产物,产物目录取决与配置文件各端的 outputPath 配置,该目录需要和 package.json 中多端适配输出目录一致。 | ||
|
||
相关文档可参考:[《MorJS - 多端组件库规范》](https://mor.eleme.io/specifications/component) | ||
|
||
```json | ||
{ | ||
"name": "my-component", | ||
"version": "1.0.0", | ||
// 缺省目录设置,未指定端的小程序组件文件会从该目录下获取, | ||
"main": "lib", | ||
// 微信小程序的入口配置 | ||
"miniprogram": "miniprogram_dist", | ||
// 支付宝小程序的入口配置 | ||
"alipay": "alipay", | ||
// 字节小程序的入口配置 | ||
"bytedance": "bytedance", | ||
// 建议配置只输出组件内容目录 | ||
"files": ["lib", "miniprogram_dist", "alipay", "bytedance"] | ||
} | ||
``` | ||
|
||
修改 package.json 的包名 name 和版本号 version,运行 `npm publish` 进行发包。 | ||
|
||
## 开始一个新组件库项目 | ||
|
||
如果你还没有开始写组件库,想要重新开始一个新的多端组件库项目,欢迎你使用官方脚手架工具来创建新项目: | ||
|
||
1. 选定项目目录,并在目录终端执行以下任一命令: | ||
|
||
```shell | ||
$ npm init mor # npm 创建项目 | ||
$ yarn create mor # yarn 创建项目 | ||
$ pnpm create mor # pnpm 创建项目 | ||
``` | ||
|
||
2. 选择工程类型 MorJS 多端组件库,按照提示完成初始化操作 | ||
|
||
```shell | ||
✔ 请选择工程类型 › MorJS 多端组件库 | ||
✔ 请选择源码类型 › 微信小程序 DSL | ||
✔ 请输入 小程序 的名称 … my-components | ||
✔ 请输入 小程序 的描述 … my first components | ||
✔ 用户名 … yourUserName | ||
✔ 邮箱 … [email protected] | ||
✔ 请输入 Git 仓库地址 … https://github.com/yourUserName/myapp | ||
✔ 请选择 npm 客户端 › npm / pnpm / yarn | ||
… | ||
``` | ||
|
||
3. 编译与调试,在终端运行 `tnpm run dev`,将生成的产物用各端对应的 IDE 打开进行预览调试 | ||
|
||
4. 构建与发包,在终端运行 `tnpm run build`,生成对应各端的小程序产物,修改 package.json 的包名 name 和版本号 version,运行 `npm publish` 进行发包 | ||
|
||
## Q&A | ||
|
||
- Q: 转端过程中,发现小程序的 JSAPI 转端后不兼容怎么办? | ||
- A: 修改 mor.config.ts 中的 autoInjectRuntime.api 配置,默认 minimal 时只做最小替换,设置为 true 或 enhanced 时,MorJS 会接管 JSAPI 调用并提供接口兼容支持 | ||
|
||
- Q: 个别情况下,组件转端表现不一致该怎么办? | ||
- A: 各个小程序平台的兼容性问题,超出多端编译覆盖范围的,需要自行处理,可考虑使用条件编译进行分端兼容 | ||
|
||
- Q: 组件库中使用的字体资源文件会被一同编译吗? | ||
- A: 会,Mor 编译时,针对业务的静态资源会全部拷过去,不依赖构建关系 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
# MorJS 使用社区组件库指南 | ||
|
||
## 背景 | ||
|
||
距离 MorJS 开源已经有一段时间了,随着使用人数的上升,较多开发者将现有小程序项目接入 MorJS 框架都会提出一个疑问,项目中除了开发同学写的原生业务代码外,很多项目还用到了第三方的组件库,这些社区组件库能够被一同转成其他小程序端么? | ||
|
||
答案是:可以,只要是(微信/支付宝)小程序原生开发的组件,理论上是可以一并转换的,使用方式上,需按照对应平台 npm 组件的规范 来使用,本次我们将分别对使用到社群中提及频率较高的 [Vant Weapp](https://github.com/youzan/vant-weapp)、[TDesign](https://github.com/Tencent/tdesign-miniprogram)、[Wux Weapp](https://github.com/wux-weapp/wux-weapp/) 的项目进行转端(如果你的项目选用的是其他组件库,也可以参考以下流程) | ||
|
||
## 一. 项目接入 MorJS | ||
|
||
使用 MorJS 提供的一码多端能力,自然需要用到 MorJS 本身,我们针对不同业务场景,提供了两种接入方式: | ||
|
||
- 新项目使用 create-mor 创建项目,文档参考:[《MorJS - 快速上手》](https://mor.eleme.io/guides/introduction/getting-started) | ||
- 已有项目添加必要依赖进行接入,文档参考:[《MorJS - 原生小程序接入》](https://mor.eleme.io/guides/migrate-from-original-miniprogram-to-mor) | ||
|
||
完成以上接入后,可在项目目录终端下执行编译命令启动项目 npm run dev,多端产物已构建在 dist 目录下,分别用对应平台的 IDE 打开即可开发预览。 | ||
|
||
``` | ||
. | ||
├── dist // 产物目录,可在 mor.config.* 中通过 outputPath 配置进行修改 | ||
│ ├── alipay // 支付宝端产物,可在用支付宝 IDE 进行预览调试 | ||
│ ├── wechat // 微信端产物,可在用微信 IDE 进行预览调试 | ||
│ └── web // 转 web 产物,可在浏览器中进行预览调试 | ||
├── node_modules // 安装 node 后用来存放用包管理工具下载安装的包的文件夹 | ||
├── src // 源码目录,可在 mor.config.* 中通过 srcPath 配置进行修改 | ||
├── mor.config.ts // MorJS 配置文件,用于提供多套编译配置 | ||
└── package.json // 项目的基础配置文件 | ||
``` | ||
|
||
## 二. 项目接入社区组件库 | ||
|
||
根据对应的社区组件库文档进行接入,如果你的项目选用的是其他组件库,也可以参考以下流程进行接入。 | ||
|
||
请注意,项目所使用的组件库和项目的小程序 DSL 需要为同一套源码,例如选择使用微信 DSL 写的项目,引入的组件库需要是 for 微信小程序的组件库,支付宝 DSL 亦然。 | ||
|
||
### 接入 [Vant Weapp](https://github.com/youzan/vant-weapp) 流程 | ||
|
||
1. 安装:通过 npm 安装组件库 `npm i @vant/weapp -S --production` | ||
2. 配置:MorJS 工程默认配置下,可直接跳过这步 | ||
|
||
- app.json 配置:小程序新版组件库与 [Vant Weapp](https://github.com/youzan/vant-weapp) 可能存在一定样式冲突问题,请根据业务需求及项目表现,自行决定是否需要去除新版基础组件样式,如需去除删除 app.json 文件的 `"style": "v2"` 配置项即可 | ||
- project.config.json 配置:MorJS 默认的 bundle 模式无需修改此项配置 | ||
- 构建 npm 包:MorJS 默认的 bundle 模式无需构建此项 | ||
- typescript 支持:MorJS 本身支持 typescript,无需配置此项 | ||
|
||
3. 使用:在对应的 json 文件中配置所用组件对应的路径,在 xml 中直接使用组件即可 | ||
|
||
> 配置组件路径有两种方式:可以按照 组件库规范 来引用组件,或按照实际路径引用组件 | ||
```json | ||
{ | ||
"usingComponents": { | ||
"van-button": "@vant/weapp/button/index", // 按照规范引用 button 组件 | ||
"van-popup": "@vant/weapp/lib/popup/index" // 按照实际路径引用 popup 组件 | ||
} | ||
} | ||
``` | ||
|
||
### 接入 [TDesign](https://github.com/Tencent/tdesign-miniprogram) 流程 | ||
|
||
1. 安装:通过 npm 安装组件库 `npm i tdesign-miniprogram -S --production` | ||
2. 配置:MorJS 工程默认配置下,可直接跳过这步 | ||
|
||
- app.json 配置:小程序新版组件库与 [TDesign](https://github.com/Tencent/tdesign-miniprogram) 可能存在一定样式冲突问题,请根据业务需求及项目表现,自行决定是否需要去除新版基础组件样式,如需去除删除 app.json 文件的 `"style": "v2"` 配置项即可 | ||
- 构建 npm 包:MorJS 默认的 bundle 模式无需构建此项 | ||
- typescript 支持:MorJS 本身支持 typescript,无需配置此项 | ||
|
||
3. 使用:在对应的 json 文件中配置所用组件对应的路径,在 xml 中直接使用组件即可 | ||
|
||
> 配置组件路径有两种方式:可以按照 组件库规范 来引用组件,或按照实际路径引用组件 | ||
```json | ||
{ | ||
"usingComponents": { | ||
"van-button": "tdesign-miniprogram/button/button", // 按照规范引用 button 组件 | ||
"van-popup": "tdesign-miniprogram/miniprogram_dist/popup/popup" // 按照实际路径引用 popup 组件 | ||
} | ||
} | ||
``` | ||
|
||
### 接入 [Wux Weapp](https://github.com/wux-weapp/wux-weapp/) 流程 | ||
|
||
1. 安装:通过 npm 安装组件库 `npm i wux-weapp -S --production` | ||
2. 配置:MorJS 工程默认配置下,无需进行 npm 构建或单独拷贝组件产物 | ||
3. 使用:在对应的 json 文件中配置所用组件对应的路径,在 xml 中直接使用组件即可 | ||
|
||
> 配置组件路径有两种方式:可以按照 组件库规范 来引用组件,或按照实际路径引用组件 | ||
```json | ||
{ | ||
"usingComponents": { | ||
"van-button": "wux-weapp/button/index", // 按照规范引用 button 组件 | ||
"van-popup": "wux-weapp/packages/lib/popup/index" // 按照实际路径引用 popup 组件 | ||
} | ||
} | ||
``` | ||
|
||
## 三. 添加组件库转端配置 | ||
|
||
接入社区组件库后,执行编译命令 npm run dev 启动项目会发现,仅本端的编译是正常执行的,转为其他端的编译会报类似 Can't resolve 'xxx' in 'xxx' 的错误,这是因为 MorJS 默认是不会在编译环节动态编译处理 node_modules 的 NPM 组件的,所以导致引入使用的组件无法载入,需要通过添加 mor.config.ts 中的 processNodeModules 配置,让编译环节处理 node_modules 中的组件 | ||
|
||
相关文档可参考:[《MorJS 基础用法 - 配置 processNodeModules》](https://mor.eleme.io/guides/basic/config/#processnodemodules---%E6%98%AF%E5%90%A6%E5%A4%84%E7%90%86-node_modules) | ||
|
||
```typescript | ||
import { defineConfig } from '@morjs/cli' | ||
|
||
export default defineConfig([ | ||
{ | ||
name: 'ali', | ||
sourceType: 'wechat', // 源码类型: 微信 DSL | ||
target: 'alipay', // 编译目标: 支付宝小程序 | ||
processNodeModules: { | ||
include: [ | ||
/@vant\/weapp/, // 添加处理 @vant/weapp 组件 | ||
/tdesign\-miniprogram/, // 添加处理 tdesign-miniprogram 组件 | ||
/wux\-weapp/ // 添加处理符合 wux-weapp 组件 | ||
] | ||
} | ||
} | ||
]) | ||
``` | ||
|
||
> 之所以 MorJS 编译默认不处理 node_modules 的 NPM 组件,原因大致有以下几点: | ||
- 动态编译性能差:node_modules 里面文件繁多,需要所有文件都去判断是否需要进行编译处理,效率较低,会一定程度上影响编译效率; | ||
- 排查问题困难:动态转换会变成黑箱,使用方无法直接感知到转换过程中所做的处理; | ||
- 无法直接给原生小程序复用:组件在满足一定条件下,是可以同时给非 MorJS 的小程序工程使用的,如果采用动态编译就能且只能给 MorJS 工程使用; | ||
- 降低了组件提供方的自测责任:在 NPM 组件 输出时直接提供了编译后产物,能够要求 NPM 组件 做好对应测试,而不是依赖于 MorJS 动态编译来确保可用性; | ||
- … | ||
|
||
## 四. 编译调试 | ||
|
||
在项目目录终端下执行编译命令启动项目,即可构建生成对应的多端产物,默认是放在项目 dist 目录下,分别用对应平台的 IDE 打开即可开发预览。 | ||
|
||
你也可以针对不同端,在 package.json 中添加单端的编译命令和相关配置,在终端执行对应的编译命令生成单端的编译产物进行开发调试。 | ||
|
||
相关文档可参考:[《MorJS 基础用法 - 命令行》](https://mor.eleme.io/guides/basic/cli) | ||
|
||
```json | ||
{ | ||
"scripts": { | ||
"dev": "mor compile -w", // 编译构建所有端并开启文件变更监听 | ||
"dev:ali": "mor compile --name ali", // 编译构建配置名为 ali 的产物 | ||
"dev:wx": "mor compile --name wx", // 编译构建配置名为 wx 的产物 | ||
"dev:dy": "mor compile --name dy", // 编译构建配置名为 dy 的产物 | ||
"build": "mor compile --production" // 开启生产环境构建所有端 | ||
} | ||
} | ||
``` | ||
|
||
## Q&A | ||
|
||
- Q: 为什么 MorJS 接入组件库不需要执行 IDE 构建 npm 包? | ||
- A: 默认的 bundle 打包模式下,MorJS 会生成闭包并基于规则合并 js 文件,同时将小程序多端组件自动提取到产物对应的 npm_components 目录,但如果 compileMode 配置的是 transform 模式,会因为该编译模式下并不处理 node_modules 和多端组件,所以得走常规的微信构建 npm | ||
|
||
- Q: 为什么我按照规范(xxx/button/index)引用组件转其他端会报 Can't resolve 'xxx' in 'xxx' 的错误? | ||
- A: MorJS 是通过目录结构结合 package.json 的 [目录指向字段配置](https://mor.eleme.io/specifications/component#%E7%9B%AE%E5%BD%95%E5%AD%97%E6%AE%B5%E9%85%8D%E7%BD%AE) 来实现的,若转端读取的字段入口对应目录下没有组件产物,编译引入组件时将报上述错误,可以把使用路径改为组件实际路径,或联系组件开发者补充 main 入口字段 | ||
|
||
- Q: 社区组件库中使用的字体资源文件会被一同编译吗? | ||
- A: 不会,针对 node_modules 中的非预期文件类型不会进行处理,请把资源文件改为引用 cdn 资源 |