|
1 | 1 | # Build |
2 | 2 |
|
3 | | -This `Build` class in your Node.js project encapsulates the process of building, packaging, and preparing a Zotero plugin for release. Below is a brief overview of its key features and functionality: |
| 3 | +This module provides the capability to compile and package plugins, with built-in bundlers such as "copy," "replace," and "bundling" for quickly configuring your plugin's build process. |
4 | 4 |
|
5 | | -## 构建流程 |
| 5 | +It also offers a set of hooks for customizing the build process. |
6 | 6 |
|
7 | | -### 复制资产 |
| 7 | +## Information of Plugin |
8 | 8 |
|
9 | | -使用 `assets` 来定义需要复制的资产。 |
| 9 | +```ts twoslash |
| 10 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 11 | +// ---cut--- |
| 12 | +export default defineConfig({ |
| 13 | + name: "Your Plugin Name", |
| 14 | + id: "Your Plugin ID", |
| 15 | + namespace: "Your Plugin Namespace", |
| 16 | +}); |
| 17 | +``` |
10 | 18 |
|
11 | | -### 定义 |
| 19 | +## Built-in Builders |
12 | 20 |
|
13 | | -Configurable via the define option. |
| 21 | +The built-in builders run sequentially in the following order. |
14 | 22 |
|
15 | | -This feature provides a way to replace global identifiers with constant expressions. |
| 23 | +### Make Directory |
16 | 24 |
|
17 | | -替换在复制资产完成后立即发生。 |
| 25 | +This step creates a new build storage folder. |
18 | 26 |
|
19 | | -Replaces placeholders (`__PLACEHOLDER__`) in files with values defined in the build configuration. |
| 27 | +Configured via the `dist` option: |
| 28 | + |
| 29 | +```ts twoslash |
| 30 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 31 | +// ---cut--- |
| 32 | +export default defineConfig({ |
| 33 | + dist: ".scaffold/build", |
| 34 | +}); |
| 35 | +``` |
| 36 | + |
| 37 | +If the target folder already exists, it will be cleared before creating the new one. |
| 38 | + |
| 39 | +::: details The file structure of `dist` |
| 40 | + |
| 41 | +- `addon` contains the plugin code after the build process but before packaging. |
| 42 | +- `*.xpi` represents the packaged plugin files. |
| 43 | +- `update*.json` are update manifest. |
| 44 | + |
| 45 | +```text {4,10,12} |
| 46 | +. |
| 47 | +|-- .scaffold |
| 48 | +| |-- build |
| 49 | +| | |-- addon |
| 50 | +| | | |-- bootstrap.js |
| 51 | +| | | |-- content |
| 52 | +| | | |-- locale |
| 53 | +| | | |-- manifest.json |
| 54 | +| | | `-- prefs.js |
| 55 | +| | |-- linter-for-zotero.xpi |
| 56 | +| | |-- update-beta.json |
| 57 | +| | `-- update.json |
| 58 | +| `-- cache |
| 59 | +`-- zotero-plugin.config.ts |
| 60 | +``` |
| 61 | + |
| 62 | +::: |
| 63 | + |
| 64 | +### Copy Assets |
| 65 | + |
| 66 | +This step copies static assets from the source directory to the build directory. |
| 67 | + |
| 68 | +Configure the assets to be copied using `build.assets`: |
| 69 | + |
| 70 | +```ts twoslash |
| 71 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 72 | +// ---cut--- |
| 73 | +export default defineConfig({ |
| 74 | + build: { |
| 75 | + assets: ["addon"], |
| 76 | + }, |
| 77 | +}); |
| 78 | +``` |
| 79 | + |
| 80 | +This is a glob list that supports negation patterns using `!`. For more details, refer to [tinyglobby](https://github.com/SuperchupuDev/tinyglobby). |
| 81 | + |
| 82 | +### Define |
| 83 | + |
| 84 | +This feature allows you to replace global identifiers with constant expressions. |
| 85 | + |
| 86 | +Configurable via the `build.define` option: |
| 87 | + |
| 88 | +```ts twoslash |
| 89 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 90 | +// ---cut--- |
| 91 | +export default defineConfig({ |
| 92 | + build: { |
| 93 | + define: { |
| 94 | + placeholder: "placeholderValue", |
| 95 | + }, |
| 96 | + }, |
| 97 | +}); |
| 98 | +``` |
| 99 | + |
| 100 | +::: warning |
| 101 | + |
| 102 | +Replacement occurs immediately after copying assets and applies only to all assets in `config.dist` under the current state. |
| 103 | + |
| 104 | +For non-asset files such as `README.md`, use the Scaffold utility `replaceInFile` (see: [Utilities](#utils)). |
| 105 | + |
| 106 | +For JavaScript constant replacement, use `esbuild.define` (see: [Script Bundling](#script-bundling)). |
| 107 | + |
| 108 | +::: |
| 109 | + |
| 110 | +During replacement, the placeholder `placeholder` is converted into the regular expression `/__placeholder__/g` for replacement (instead of `/placeholder/g`). |
| 111 | + |
| 112 | +This option provides built-in placeholders such as `version` and `buildTime`. See `Context.templateData` for details. |
20 | 113 |
|
21 | 114 | ### Manifest Generation |
22 | 115 |
|
23 | | -Merges user-supplied manifest data with required fields (e.g., `id`, `updateURL`) to create a complete `manifest.json` (`makeManifest`). |
| 116 | +Automatically updates fields in `manifest.json`, including `version`, `id`, `update_url`, and more. |
| 117 | + |
| 118 | +This feature is enabled by default and can be disabled by setting `makeManifest` to `false`. |
| 119 | + |
| 120 | +The `version` is sourced from `package.json`, while other values can be configured in the configuration file: |
| 121 | + |
| 122 | +```ts twoslash |
| 123 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 124 | +// ---cut--- |
| 125 | +export default defineConfig({ |
| 126 | + name: "Your Plugin Name", |
| 127 | + id: "Your Plugin ID", |
| 128 | + updateURL: "Your update.json Path", |
| 129 | + build: { |
| 130 | + makeManifest: { |
| 131 | + enable: true, |
| 132 | + }, |
| 133 | + }, |
| 134 | +}); |
| 135 | +``` |
| 136 | + |
| 137 | +When `manifest.json` already exists in `dist/addon`, the values will always be deeply merged with the existing content, with priority given to the existing entries. |
24 | 138 |
|
25 | 139 | ### Locale File Handling |
26 | 140 |
|
27 | | -Processes Fluent `.ftl` files, adding a namespace prefix and ensuring HTML references (`data-l10n-id`) are consistent with Fluent messages. |
| 141 | +Handles localization files to prevent conflicts. |
| 142 | + |
| 143 | +Configured via `build.fluent`. |
| 144 | + |
| 145 | +#### Add Prefix to FTL File Names |
| 146 | + |
| 147 | +```ts twoslash |
| 148 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 149 | +// ---cut--- |
| 150 | +export default defineConfig({ |
| 151 | + namespace: "Your Plugin Namespace", |
| 152 | + build: { |
| 153 | + fluent: { |
| 154 | + prefixLocaleFiles: true, |
| 155 | + }, |
| 156 | + }, |
| 157 | +}); |
| 158 | +``` |
| 159 | + |
| 160 | +#### Add Prefix to FTL Messages |
| 161 | + |
| 162 | +Processes Fluent `.ftl` files by adding a namespace prefix and ensuring HTML references (`data-l10n-id`) align with Fluent messages. |
| 163 | + |
| 164 | +```ts twoslash |
| 165 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 166 | +// ---cut--- |
| 167 | +export default defineConfig({ |
| 168 | + namespace: "Your Plugin Namespace", |
| 169 | + build: { |
| 170 | + fluent: { |
| 171 | + prefixFluentMessages: true, |
| 172 | + }, |
| 173 | + }, |
| 174 | +}); |
| 175 | +``` |
| 176 | + |
| 177 | +#### Generate Type Definitions for FTL Messages |
| 178 | + |
| 179 | +> In development. |
28 | 180 |
|
29 | 181 | ### Preference Management |
30 | 182 |
|
| 183 | +> In development. |
| 184 | +
|
31 | 185 | - Supports prefixing preference keys in `prefs.js` with a custom namespace. |
32 | 186 | - Optionally generates TypeScript declaration files (`.d.ts`) for preferences. |
33 | 187 |
|
34 | 188 | ### Script Bundling |
35 | 189 |
|
36 | | -Uses `esbuild` to bundle JavaScript files with options defined in the configuration (`esbuild`). |
| 190 | +Uses `esbuild` to compile and bundle your JavaScript/TypeScript code. |
| 191 | + |
| 192 | +Configure it using `build.esbuild`: |
| 193 | + |
| 194 | +```ts twoslash |
| 195 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 196 | +// ---cut--- |
| 197 | +export default defineConfig({ |
| 198 | + build: { |
| 199 | + esbuildOptions: [], |
| 200 | + }, |
| 201 | +}); |
| 202 | +``` |
| 203 | + |
| 204 | +Since `esbuild` only compiles and bundles code without type checking, you need to run `tsc` manually for type checking. |
37 | 205 |
|
38 | 206 | ### Plugin Packing |
39 | 207 |
|
40 | 208 | Creates a `.xpi` archive for the plugin using `AdmZip`. |
41 | 209 |
|
| 210 | +```ts twoslash |
| 211 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 212 | +// ---cut--- |
| 213 | +export default defineConfig({ |
| 214 | + xpiName: "Your Plugin Built XPI Name", |
| 215 | +}); |
| 216 | +``` |
| 217 | + |
| 218 | +This step executes only in the `production` environment. |
| 219 | + |
42 | 220 | ### Update Manifest |
43 | 221 |
|
44 | 222 | Generates `update.json` and `update-beta.json` with versioning and compatibility information for Zotero plugin updates. |
45 | 223 |
|
46 | | -## Extensibility |
| 224 | +Configured via `build.makeUpdateJson`: |
| 225 | + |
| 226 | +```ts twoslash |
| 227 | +import { defineConfig } from "zotero-plugin-scaffold"; |
| 228 | +// ---cut--- |
| 229 | +export default defineConfig({ |
| 230 | + build: { |
| 231 | + makeUpdateJson: { |
| 232 | + updates: [ |
| 233 | + { |
| 234 | + version: "0.9.9", |
| 235 | + update_link: "https://example.com/plugin-for-older-zotero.xpi", |
| 236 | + applications: { |
| 237 | + zotero: { |
| 238 | + strict_min_version: "5.9.9", |
| 239 | + strict_max_version: "6.9.9", |
| 240 | + }, |
| 241 | + }, |
| 242 | + }, |
| 243 | + ], |
| 244 | + hash: true, |
| 245 | + }, |
| 246 | + }, |
| 247 | +}); |
| 248 | +``` |
| 249 | + |
| 250 | +This step executes only in the `production` environment. |
| 251 | + |
| 252 | +When the version number includes a `-` (pre-release), only `update-beta.json` is generated. Otherwise, both `update.json` and `update-beta.json` are generated. After installing a pre-release version, users will automatically update to the next pre-release version until the official release. Installing the next pre-release version still requires manual installation. |
| 253 | + |
| 254 | +For different plugin versions targeting different Zotero versions, specify the Zotero version and corresponding plugin version in `build.makeUpdateJson.updates`. Refer to: [Zotero 7 for developers](https://www.zotero.org/support/dev/zotero_7_for_developers#updaterdf_updatesjson). |
| 255 | + |
| 256 | +## Hooks |
| 257 | + |
| 258 | +> Documentation in progress. |
| 259 | +
|
| 260 | +## Utils |
| 261 | + |
| 262 | +Scaffold exports utilities and third-party dependencies for use. Import them from `zotero-plugin-scaffold/vendor`. |
| 263 | + |
| 264 | +### replaceInFile |
| 265 | + |
| 266 | +```ts |
| 267 | +import { replaceInFile } from "zotero-plugin-scaffold/vendor"; |
| 268 | + |
| 269 | +replaceInFile({ |
| 270 | + files: ["README.md", "**/README.md"], |
| 271 | + from: [/from/g], |
| 272 | + to: ["to"], |
| 273 | +}); |
| 274 | +``` |
| 275 | + |
| 276 | +### fs-extra |
| 277 | + |
| 278 | +> Node.js: Extra methods for the `fs` object like `copy()`, `remove()`, `mkdirs()`. |
| 279 | +
|
| 280 | +Refer to the [fs-extra documentation](https://github.com/jprichardson/node-fs-extra). |
| 281 | + |
| 282 | +```ts |
| 283 | +import { fse } from "zotero-plugin-scaffold/vendor"; |
| 284 | + |
| 285 | +fse.copy("a.txt", "b.txt"); |
| 286 | +``` |
| 287 | + |
| 288 | +### es-toolkit |
| 289 | + |
| 290 | +> es-toolkit: State-of-the-art JavaScript utility library |
| 291 | +
|
| 292 | +Refer to the [es-toolkit documentation](https://es-toolkit.slash.page/). |
| 293 | + |
| 294 | +```ts |
| 295 | +import { esToolkit } from "zotero-plugin-scaffold/vendor"; |
47 | 296 |
|
48 | | -- The use of hooks allows custom behaviors to be injected at various stages of the build process. |
| 297 | +esToolkit.isNotNil(null); |
| 298 | +``` |
0 commit comments