vite-plugin-siyuan 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- package/dist/artifact/verify.js +2 -3
- package/dist/config.d.ts +2 -2
- package/dist/config.js +2 -4
- package/dist/index.d.ts +7 -3
- package/dist/index.js +6 -3
- package/dist/siyuan/kinds.d.ts +1 -1
- package/dist/siyuan/kinds.js +2 -2
- package/dist/siyuan/manifest.js +4 -3
- package/package.json +60 -60
package/README.md
CHANGED
|
@@ -18,7 +18,8 @@ import { defineConfig } from 'vite';
|
|
|
18
18
|
import siyuan from 'vite-plugin-siyuan';
|
|
19
19
|
|
|
20
20
|
export default defineConfig({
|
|
21
|
-
|
|
21
|
+
// entry 必填:主题指向 CSS,插件指向 TS/JS
|
|
22
|
+
plugins: [siyuan({ entry: 'src/main.css' })],
|
|
22
23
|
});
|
|
23
24
|
```
|
|
24
25
|
|
|
@@ -32,9 +33,12 @@ pnpm vite build --watch
|
|
|
32
33
|
|
|
33
34
|
| 选项 | 说明 |
|
|
34
35
|
|---|---|
|
|
35
|
-
| `
|
|
36
|
+
| `entry` | **必填**。构建入口,相对项目根。主题指向 CSS,插件指向 TS/JS |
|
|
37
|
+
| `kind` | `'theme'` / `'plugin'`;缺省时在 `public/`、项目根依次查找 `theme.json` / `plugin.json` 推断 |
|
|
36
38
|
| `outDir` | 产物目录;缺省 `./dev`(watch)/ `./dist`(生产) |
|
|
37
|
-
|
|
39
|
+
|
|
40
|
+
> `entry` 必填是因为产物名是固定契约(主题 `theme.css`、插件 `index.js`)。
|
|
41
|
+
> 入口猜错不会报错,只会静默产出思源加载不到的东西——所以宁可要求显式指定。
|
|
38
42
|
|
|
39
43
|
## 做什么
|
|
40
44
|
|
|
@@ -42,8 +46,8 @@ pnpm vite build --watch
|
|
|
42
46
|
|
|
43
47
|
### watch(`vite build --watch`)
|
|
44
48
|
|
|
45
|
-
1. **注入构建配置**:主题产出 `theme.css
|
|
46
|
-
2. **链接产物**:把 `dev/` 链接到
|
|
49
|
+
1. **注入构建配置**:主题产出 `theme.css`;插件走 `lib` CJS 单文件产出 `index.js`。`base: './'` 保证宿主下资源不 404。用 `mergeConfig` 合并,**用户已写的值优先**。
|
|
50
|
+
2. **链接产物**:把 `dev/` 链接到 `{workspace}/data/themes|plugins/{name}`。插件目录必须是真 symlink(思源 Go 运行时按 `ModeSymlink` 判定),主题可用 junction 兜底。
|
|
47
51
|
3. **激活**:主题调 `setAppearance` 选中它;插件调 `setPetalEnabled` 启用。
|
|
48
52
|
4. **热重载**:产物变化后合并 250ms 广播 `reloadUI`,思源整页刷新。
|
|
49
53
|
|
|
@@ -74,8 +78,8 @@ watch 模式首次就绪后还会打印桌面端 / 移动端两个稳定预览
|
|
|
74
78
|
| 变量 | 说明 |
|
|
75
79
|
|---|---|
|
|
76
80
|
| `SIYUAN_PORT` | kernel 端口;缺省用 kernel 进程 PID 匹配 `port.json`,再探测记录端口与 6806–6809 |
|
|
77
|
-
| `SIYUAN_THEME_DIR` |
|
|
78
|
-
| `SIYUAN_PLUGIN_DIR` |
|
|
81
|
+
| `SIYUAN_THEME_DIR` | 主题安装父目录(`{workspace}/data/themes`),实际装到 `{该目录}/{name}` |
|
|
82
|
+
| `SIYUAN_PLUGIN_DIR` | 插件安装父目录(`{workspace}/data/plugins`),同上 |
|
|
79
83
|
| `SIYUAN_TOKEN` | 开了 API token 时使用 |
|
|
80
84
|
| `SIYUAN_NO_ELEVATION=1` | 不弹 UAC 提权(CI 环境自动不弹) |
|
|
81
85
|
| `SIYUAN_DEBUG=1` | 输出 debug 级日志 |
|
package/dist/artifact/verify.js
CHANGED
|
@@ -29,10 +29,9 @@ function findDoubleWrappedColors(css) {
|
|
|
29
29
|
export function verifyTarget(kind, { root, outDir }) {
|
|
30
30
|
const spec = kindSpec(kind);
|
|
31
31
|
const issues = [];
|
|
32
|
-
const declaredOutDir = isAbsolute(outDir) ? outDir : join(root, outDir);
|
|
33
32
|
// 只校验本次构建的产物目录。不做「产物目录不存在就改扫项目根」的兜底:
|
|
34
33
|
// 插件永远在真实构建之后校验,那种兜底只会把 node_modules 当成产物扫进来。
|
|
35
|
-
const absOutDir =
|
|
34
|
+
const absOutDir = isAbsolute(outDir) ? outDir : join(root, outDir);
|
|
36
35
|
const walked = walkFiles(absOutDir);
|
|
37
36
|
const files = walked.map((file) => file.name);
|
|
38
37
|
const byName = new Map(walked.map((file) => [file.name, file.path]));
|
|
@@ -46,7 +45,7 @@ export function verifyTarget(kind, { root, outDir }) {
|
|
|
46
45
|
// ---- 通用:清单存在与形状 ----
|
|
47
46
|
if (!manifest) {
|
|
48
47
|
issues.push({
|
|
49
|
-
message: `读不到清单:${spec.manifestName}(找过 public
|
|
48
|
+
message: `读不到清单:${spec.manifestName}(找过 public/、项目根与产物目录)`,
|
|
50
49
|
hint: '思源按清单识别主题/插件,缺了它不会出现在列表里。',
|
|
51
50
|
});
|
|
52
51
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import type { Kind } from './siyuan/kinds.ts';
|
|
|
4
4
|
export interface BuildSpecInput {
|
|
5
5
|
kind: Kind;
|
|
6
6
|
watch: boolean;
|
|
7
|
-
/**
|
|
8
|
-
entry: string
|
|
7
|
+
/** 入口文件绝对路径。必填:产物名是固定契约,入口不能靠猜。 */
|
|
8
|
+
entry: string;
|
|
9
9
|
/** 插件选项里显式给的产物目录。 */
|
|
10
10
|
outDir: string | null;
|
|
11
11
|
}
|
package/dist/config.js
CHANGED
|
@@ -35,9 +35,7 @@ function optionsKey(userConfig) {
|
|
|
35
35
|
export function buildSpecFor(input) {
|
|
36
36
|
const spec = kindSpec(input.kind);
|
|
37
37
|
const outDir = input.outDir ?? (input.watch ? './dev' : './dist');
|
|
38
|
-
const options = {};
|
|
39
|
-
if (input.entry)
|
|
40
|
-
options.input = input.entry;
|
|
38
|
+
const options = { input: input.entry };
|
|
41
39
|
if (input.kind === 'plugin') {
|
|
42
40
|
options.external = ['siyuan', 'process'];
|
|
43
41
|
options.output = {
|
|
@@ -55,7 +53,7 @@ export function buildSpecFor(input) {
|
|
|
55
53
|
// watch 不压缩(便于直接看落盘产物),生产用默认压缩器。
|
|
56
54
|
minify: !input.watch,
|
|
57
55
|
};
|
|
58
|
-
if (input.
|
|
56
|
+
if (input.kind === 'plugin') {
|
|
59
57
|
// 插件入口是 `export default class ...`,必须走 lib:lib cjs 产出
|
|
60
58
|
// `module.exports = 类`;普通 input 只得到 `exports.default`,思源报
|
|
61
59
|
// "plugin xxx has no export"。
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
2
|
import type { Kind } from './siyuan/kinds.ts';
|
|
3
3
|
export interface SiYuanOptions {
|
|
4
|
+
/**
|
|
5
|
+
* 构建入口,相对项目根。必填:主题要产出固定名 `theme.css`、插件要产出
|
|
6
|
+
* CJS 单文件 `index.js`,产物名是思源加载机制决定的契约,入口不能靠猜——
|
|
7
|
+
* 猜错不会报错,只会静默产出思源加载不到的东西。
|
|
8
|
+
*/
|
|
9
|
+
entry: string;
|
|
4
10
|
/** 被测类型(theme / plugin);缺省从清单推断。 */
|
|
5
11
|
kind?: Kind | null;
|
|
6
12
|
/** 产物目录;缺省 `./dev`(watch)/ `./dist`(生产)。 */
|
|
7
13
|
outDir?: string | null;
|
|
8
|
-
/** 构建入口,相对项目根;缺省保留项目自己写的 input/lib。 */
|
|
9
|
-
entry?: string | null;
|
|
10
14
|
}
|
|
11
|
-
export default function siyuan(options
|
|
15
|
+
export default function siyuan(options: SiYuanOptions): Plugin;
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* closeBundle 校验 + 打包 + 汇报 + 构建完成日志
|
|
17
17
|
* closeWatcher 释放定时器
|
|
18
18
|
*/
|
|
19
|
+
import { existsSync } from 'node:fs';
|
|
19
20
|
import { resolve } from 'node:path';
|
|
20
21
|
import { applyBuildConfig } from './config.js';
|
|
21
22
|
import { detectKind } from './siyuan/kinds.js';
|
|
@@ -23,7 +24,7 @@ import { createTaggedLogger } from './output/log.js';
|
|
|
23
24
|
import { createBuildSession } from './session.js';
|
|
24
25
|
import { describeError, UserError } from './support/errors.js';
|
|
25
26
|
const NAME = 'vite-plugin-siyuan';
|
|
26
|
-
export default function siyuan(options
|
|
27
|
+
export default function siyuan(options) {
|
|
27
28
|
const log = createTaggedLogger(NAME);
|
|
28
29
|
let session = null;
|
|
29
30
|
let kind = options.kind ?? null;
|
|
@@ -32,6 +33,10 @@ export default function siyuan(options = {}) {
|
|
|
32
33
|
apply: 'build',
|
|
33
34
|
config(userConfig) {
|
|
34
35
|
const root = typeof userConfig.root === 'string' ? resolve(userConfig.root) : process.cwd();
|
|
36
|
+
const entry = resolve(root, options.entry);
|
|
37
|
+
if (!existsSync(entry)) {
|
|
38
|
+
throw new UserError(`entry 指向的文件不存在:${entry}(选项值:${options.entry})`);
|
|
39
|
+
}
|
|
35
40
|
try {
|
|
36
41
|
kind ??= detectKind(root);
|
|
37
42
|
}
|
|
@@ -41,7 +46,6 @@ export default function siyuan(options = {}) {
|
|
|
41
46
|
return undefined;
|
|
42
47
|
}
|
|
43
48
|
const watch = Boolean(userConfig.build?.watch);
|
|
44
|
-
const entry = options.entry ? resolve(root, options.entry) : null;
|
|
45
49
|
return applyBuildConfig(userConfig, { kind, watch, entry, outDir: options.outDir ?? null });
|
|
46
50
|
},
|
|
47
51
|
configResolved(resolvedConfig) {
|
|
@@ -49,7 +53,6 @@ export default function siyuan(options = {}) {
|
|
|
49
53
|
const outDir = resolvedConfig.build.outDir;
|
|
50
54
|
const publicDir = resolvedConfig.publicDir;
|
|
51
55
|
const watch = resolvedConfig.command === 'build' && Boolean(resolvedConfig.build.watch);
|
|
52
|
-
kind ??= options.kind ?? null;
|
|
53
56
|
if (!kind) {
|
|
54
57
|
log('识别不到被测类型,跳过链接与校验', 'warn');
|
|
55
58
|
return;
|
package/dist/siyuan/kinds.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface KindSpec {
|
|
|
17
17
|
}
|
|
18
18
|
export declare function kindSpec(kind: Kind): KindSpec;
|
|
19
19
|
/**
|
|
20
|
-
* 从项目目录推断类型:看 public
|
|
20
|
+
* 从项目目录推断类型:看 public/ 或项目根存在哪份清单。
|
|
21
21
|
* 同时存在多种时必须让人指定——装错类型的产物名会静默加载不到。
|
|
22
22
|
*/
|
|
23
23
|
export declare function detectKind(root: string): Kind;
|
package/dist/siyuan/kinds.js
CHANGED
|
@@ -33,7 +33,7 @@ export function kindSpec(kind) {
|
|
|
33
33
|
}
|
|
34
34
|
const KIND_NAMES = ['theme', 'plugin'];
|
|
35
35
|
/**
|
|
36
|
-
* 从项目目录推断类型:看 public
|
|
36
|
+
* 从项目目录推断类型:看 public/ 或项目根存在哪份清单。
|
|
37
37
|
* 同时存在多种时必须让人指定——装错类型的产物名会静默加载不到。
|
|
38
38
|
*/
|
|
39
39
|
export function detectKind(root) {
|
|
@@ -42,7 +42,7 @@ export function detectKind(root) {
|
|
|
42
42
|
if (matches.length === 1 && only !== undefined)
|
|
43
43
|
return only;
|
|
44
44
|
throw new UserError(matches.length === 0
|
|
45
|
-
? `在 ${root} 的 public
|
|
45
|
+
? `在 ${root} 的 public/ 或项目根下找不到 theme.json / plugin.json;请用 kind 选项显式指定类型`
|
|
46
46
|
: `同时匹配到多种类型:${matches.join('、')};请用 kind 选项显式指定`);
|
|
47
47
|
}
|
|
48
48
|
/** 读被测对象的名字;读不到抛可读错误,不猜默认值。 */
|
package/dist/siyuan/manifest.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 清单文件的读取。
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* 清单可能出现在两处:`public/`(源码)或项目根(官方 sample 的布局)。
|
|
5
|
+
* 构建产物里的清单由调用方通过 `extraDirs` 显式传入,不作为默认候选——
|
|
6
|
+
* 否则上一次构建留下的 `dist/theme.json` 会盖住源码里的新清单。
|
|
6
7
|
*/
|
|
7
8
|
import { join } from 'node:path';
|
|
8
9
|
import { readJsonFile } from '../support/fs.js';
|
|
9
10
|
import { isRecord } from '../support/guards.js';
|
|
10
11
|
/** 清单候选路径,按优先级排列。 */
|
|
11
12
|
export function manifestCandidates(root, manifest, extraDirs = []) {
|
|
12
|
-
const dirs = [join(root, 'public'),
|
|
13
|
+
const dirs = [join(root, 'public'), root, ...extraDirs];
|
|
13
14
|
return dirs.map((dir) => join(dir, manifest));
|
|
14
15
|
}
|
|
15
16
|
/** 读一份清单与其路径;都读不到返回 null。 */
|
package/package.json
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "vite-plugin-siyuan",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Vite plugin for SiYuan theme/plugin development: config injection, link to workspace, hot reload, verify and package",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"siyuan",
|
|
7
|
-
"siyuan-theme",
|
|
8
|
-
"siyuan-plugin",
|
|
9
|
-
"vite-plugin",
|
|
10
|
-
"hot-reload"
|
|
11
|
-
],
|
|
12
|
-
"type": "module",
|
|
13
|
-
"license": "MIT",
|
|
14
|
-
"engines": {
|
|
15
|
-
"node": ">=22.18.0"
|
|
16
|
-
},
|
|
17
|
-
"exports": {
|
|
18
|
-
".": {
|
|
19
|
-
"types": "./dist/index.d.ts",
|
|
20
|
-
"default": "./dist/index.js"
|
|
21
|
-
},
|
|
22
|
-
"./package.json": "./package.json"
|
|
23
|
-
},
|
|
24
|
-
"files": [
|
|
25
|
-
"dist"
|
|
26
|
-
],
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
},
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
},
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-plugin-siyuan",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Vite plugin for SiYuan theme/plugin development: config injection, link to workspace, hot reload, verify and package",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"siyuan",
|
|
7
|
+
"siyuan-theme",
|
|
8
|
+
"siyuan-plugin",
|
|
9
|
+
"vite-plugin",
|
|
10
|
+
"hot-reload"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=22.18.0"
|
|
16
|
+
},
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"consola": "^3.4.2",
|
|
29
|
+
"fflate": "^0.8.3",
|
|
30
|
+
"ps-list": "^9.0.0",
|
|
31
|
+
"semver": "^7.8.6",
|
|
32
|
+
"zod": "^4.6.7"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"vite": ">=6"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^22.20.5",
|
|
39
|
+
"@types/semver": "^7.8.0",
|
|
40
|
+
"typescript": "^7.0.2",
|
|
41
|
+
"vite": "^8.3.5",
|
|
42
|
+
"vitest": "^5.0.5"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/svchord/vite-plugin-siyuan.git"
|
|
47
|
+
},
|
|
48
|
+
"author": "svchord",
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public",
|
|
51
|
+
"registry": "https://registry.npmjs.org/"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"clean": "node --input-type=module -e \"import fs from 'node:fs'; fs.rmSync('dist',{recursive:true,force:true})\"",
|
|
55
|
+
"build": "pnpm run clean && tsc -p tsconfig.build.json",
|
|
56
|
+
"type-check": "tsc -p tsconfig.json --noEmit",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"check": "pnpm run type-check && pnpm run test"
|
|
59
|
+
}
|
|
60
|
+
}
|