打包 Blocklet
简介#
我们只有需要知道应用的启动入口在哪,才能启动这个 blocklet
。
1. 打包是什么?#
打包的本质就是将现有项目结构转化为另一种项目结构。
blocklet 打包成功后,系统将会在项目根目录下生成一个 .blocklet
目录,目录结构如下:
.blocklet
├── bundle
│ ├── LICENSE
│ ├── README.md
│ ├── api
│ ├── blocklet.js
│ ├── blocklet.md
│ ├── blocklet.yml
│ ├── blocklet.zip
│ ├── dist
│ ├── logo.png
│ ├── media
│ ├── package.json
│ └── screenshots
└── release
├── blocklet.json
└── demo1-0.1.0.tgz
2. 为什么要打包?#
你需要打包你的 blocklet(就像苹果开发者打包苹果应用一样),才能将 blocklet 发布到 blocklet store
(就像发布苹果应用到 app store 一样) 和 部署到 blocklet server
(就像将苹果应用安装到苹果手机一样)。
准备工作#
1. 应用的入口(必要)#
定义应用的入口文件#
你需要在 blocklet.yml
文件中定义 main
字段,以声明应用的入口,例如:
main: api/index.js
定义应用运行所需的文件#
你需要在 blocklet.yml
文件中定义 files
字段,以声明应用运行所需的文件,例如:
files:
- dist
上面的配置意味着,在打包的时候,会把 dist 目录复制到 .blocklet/bundle
目录下。
你也可以定义如下的模式来匹配部分文件:
files:
- migration/*.js
打包结果中会包含 migration
目录下的所有文件。
你也可以定义如下的否定模式来把部分文件排除在外:
files:
- "!server/ignored.js"
应用打包时会强制包含的文件包括:
- blocklet.yml
- blocklet.md 或 README.md
- CHANGELOG.md
- LICENSE
应用打包时默认忽略的文件参考:https://docs.npmjs.com/cli/v9/configuring-npm/package-json#files
2. Logo(必要)#
一个设计精美的 logo 可以提高应用的辨识度,而对于每一个被 bundle
的 blocklet 而言,logo 文件同样是必要的。
先决条件#
- logo 的宽高必须相同
- logo 的像素不能小于 256px \* 256px(svg 文件除外)
- logo 的文件大小不得超过 100KB
- logo 的格式必须是主流的图片格式(支持 svg, jpg, png 等)
定义 logo 字段#
你可以在 blocklet.yml
文件中定义 logo 文件存放的路径。
logo: logo.png
3. 使用文档(必要)#
先决条件#
每个 blocklet 都应该有自己的使用文档,简单易上手的使用文档更能吸引用户去使用它。
与 markdown 一样,我们可以在使用文档上放置文字,图片,视频等。
编写使用文档#
现在,你只需要使用 markdown 语法在项目根目录下创建一个 blocklet.md
文件,无需在 blocklet.yml
声明这个文件,打包的时候会系统会自动识别这个文件。
# My Blocklet
Welcome to my blocklet
另外,如果项目根目录下不存在 blocklet.md
文件,系统会有序地在项目根目录下继续匹配 blocklet.en.md
,README.md
文件。
如果系统最终查找失败,会在打包时抛出错误并中断当前的打包行为。
4. 截图(可选)#
在向用户介绍 blocklet 时,只有文字可能还是不够的。
为了更好的呈现产品运行的效果,这时候你还可以使用屏幕截图向用户展示你的 blocklet。
定义 screenshots 字段#
你可以在 blocklet.yml
文件中定义 screenshots 字段:
screenshots:
- screenshot-0.png
- screenshot-1.png
- screenshot-2.png
- screenshot-3.png
打包发布到 blocklet store
之后,你可以在 blocklet 详情页(查看示例)面看到你的屏幕截图,默认是按照文件名的字典序升序,以轮播图的方式展示的。
5. Change log(可选)#
每次更新 blocklet 的时候,我们可能需要记录变更的日志。
对于开发者而言,通常是通过更新 CHANGELOG.md
文件来记录项目的变更,在 blocklet store
的展示效果如下图所示:
编写 CHANGELOG.md
#
你可以在项目根目录下创建 CHANGELOG.md
文件,例如:
# 0.7.10 (October 18, 2022)
- chore: update deps to latest
# 0.7.9 (October 17, 2022)
- chore: update @nft-store/react lib and change the primary-color / logo
打包发布到 blocklet store
之后,你可以在 blocklet 详情页(查看示例)面看到你的变更记录。
打包应用#
默认的打包模式#
如果 blocklet 是通过 blocklet create
或 create-blocklet
创建的,那么可以在终端执行内置的打包命令:
yarn bundle
打包命令执行成功后,应该可以在项目根目录下看到生成的 .blocklet/bundle
目录。
打包单个应用(自定义)#
1. 基于 compact 打包(推荐)#
通过 compact 模式打包,会从应用入口开始分析应用的依赖,并将依赖打包到单个文件 blocklet-compact.js
中, 这种打包方式体积更小, 应用的安装速度更快。
blocklet bundle --compact --create-release
上面的命令主要做了 2 件事:
- 分析 require 或 import, 编译整个项目, 所以应避免使用动态路径的
require
语句,而应使用静态路径的require
或import
语句 - 以 compact 模式打包 blocklet,在项目根目录下生成
.blocklet/bundle
目录 - 将打包后的文件放在项目根目录下
.blocklet/release
目录
如果我们的应用有二进制依赖的包, 我们可以使用 --external <items>
描述, 这类包会在应用安装时, 根据对应的平台进行安装, 例如:
blocklet bundle --compact --external sqlite3,sharp --create-release
不必要的 --external 会降低应用的安装速度, 为了您的应用的使用体验, 请确保 --external 只包含有二进制依赖的包。
source-map:
为打包后的 Blocklet 创建 source map,仅适用于紧凑模式:
blocklet bundle --compact --source-map --external sqlite3,sharp --create-release
为防止生产环境泄漏源码,我们可以使用只保留行号的 source map。 创建不包含源码内容的 source map,仅适用于紧凑模式:
blocklet bundle --compact --nosources-source-map --external sqlite3,sharp --create-release
2. 基于 zip 打包#
与 compact 的打包方式不同的是,zip 打包模式不会将项目打包成单个文件,而是会从应用入口开始分析应用的依赖,并将全部依赖按照原有的项目接口压缩到一个 zip 文件中。
blocklet bundle --zip --create-release
上面的命令主要做了 2 件事:
- 以 zip 模式打包 blocklet,在项目根目录下生成
.blocklet/bundle
目录,并会生成一个blocklet.zip
文件 - 将打包后的文件放在项目根目录下
.blocklet/release
目录
打包 monorepo 应用(自定义)#
blocklet bundle --create-release --monorepo
上面的命令主要做了 2 件事:
- 以 monorepo 模式打包 blocklet,在项目根目录下生成
.blocklet/bundle
目录 - 将打包后的文件放在项目根目录下
.blocklet/release
目录
至此,我们已经顺利地打包好了我们的 blocklet。
接下来,你可以将打包好的 blocklet 发布到 blocklet store
或者部署到 blocklet server
。
打包时动态设置组件的 Source Store#
你的 blocklet 正式发布前,你可以先将 blocklet 发布到测试商店, 测试完成后再发布到正式商店.
如果你希望测试商店中的 blocklet 依赖测试商店中的组件,正式商店 中的 blocklet 依赖正式商店中的组件,你可以在 blocklet.yml 中不填写 source store, 在打包时动态传入.
components:
- name: component-a
mountPoint: /component-a
source:
name: component-a
version: latest
- name: component-b
mountPoint: /component-b
source:
store: https://store.blocklet.dev # 声明了 source store 后,打包时不会被覆盖
name: component-b
version: latest
执行 blocklet bundle --store-url "https://your-test-store.com"
, 打包后的 blocklet.yml 为
components:
- name: component-a
mountPoint: /component-a
source:
store: https://your-test-store.com
name: component-a
version: latest
- name: component-b
mountPoint: /component-b
source:
store: https://store.blocklet.dev
name: component-b
version: latest
执行 blocklet bundle --store-url "https://your-prod-store.com"
, 打包后的 blocklet.yml 为
components:
- name: component-a
mountPoint: /component-a
source:
store: https://your-prod-store.com
name: component-a
version: latest
- name: component-b
mountPoint: /component-b
source:
store: https://store.blocklet.dev
name: component-b
version: latest
你也可以通过环境变量设置 source store: COMPONENT_STORE_URL=https://your-prod-store.com blocklet bundle