hexo-swpp 3.3.7 → 3.4.0-alpha.110

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.
Files changed (3) hide show
  1. package/README.md +34 -30
  2. package/dist/index.js +123 -91
  3. package/package.json +6 -8
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  使用时需要同时安装 `hexo-swpp` 和 `swpp-backends`:
6
6
 
7
7
  ```bash
8
- npm install hexo-swpp swpp-backends
8
+ npm install hexo-swpp swpp-backends@3.0.0-alpha.100
9
9
  ```
10
10
 
11
11
  当 `swpp-backends` 存在版本更新时,可以直接更新 `swpp-backends` 版本,不需要更新 `hexo-swpp` 的版本。(不过 `hexo-swpp` 有更新的话最好也跟进一下。)
@@ -18,6 +18,7 @@ npm install hexo-swpp swpp-backends
18
18
  | ~3.1 | ^1.1.0 |
19
19
  | ~3.2 | ^2.0.0 |
20
20
  | ~3.3 | ^2.1.2 |
21
+ | 4.0-alpha | ^3.0.0-alpha.100 |
21
22
 
22
23
  ## 使用
23
24
 
@@ -25,15 +26,36 @@ npm install hexo-swpp swpp-backends
25
26
 
26
27
  ```yml
27
28
  swpp:
28
- # 是否启用插件
29
+ # 是否启用,默认 false
29
30
  enable: true
30
- # 是否在发布前自动执行脚本
31
- # auto_exec: true
32
- # 构建时拉取版本文件的警告等级,缺省为 1(该功能仅在 swpp-backends 版本号 >= 2.1.2 时可用)
33
- # 0 - 表示不允许出现 404 情况;1 - 表示允许服务器返回 404 状态码;2 - 表示允许任何 404(包括 DNS 解析失败等)
34
- # warn_level: 1
35
- # 检查版本的 URL,不能以 '/' 结尾
31
+ # 配置文件名称,不带拓展名
32
+ # config_name: 'swpp.config'
33
+ # 是否生成 sw
34
+ # serviceWorker: true
35
+ # 是否向所有 HTML 插入注册 sw 的代码
36
+ # auto_register: true
37
+ # 是否生成 DOM 端的 JS 文件并在 HTML 中插入 script
38
+ # gen_dom: true
39
+ # 是否在执行 hexo deploy 时自动执行 swpp 指令
40
+ # auto_exec: false
41
+ # 检查更新的网址,默认 "https://registry.npmjs.org",注意不能以斜杠结尾
36
42
  # npm_url: 'https://registry.npmmirror.com'
43
+ #
44
+ # 排序规则。
45
+ # 该配置项是为了对 hexo 中的一些变量进行排序,避免每次生成 HTML 时由于这些变量的顺序变动导致生成结果不完全相同。
46
+ # 示例:
47
+ # ```yaml
48
+ # # 下面给出的值为插件的缺省值,用户设置该项不会直接覆盖这些值,只有用户也声明 posts、pages 或 tags 时才会覆盖对应的值。
49
+ # swpp:
50
+ # sort_rules:
51
+ # posts: 'title'
52
+ # pages: 'title'
53
+ # tags: 'name'
54
+ # ```
55
+ #
56
+ # 其中 key 值为要排序的变量的名称,value 为变量排序时的依据,
57
+ # 填 false 表示禁用该项排序,填 true 表示以 value 本身为键进行排序,填字符串表示以 value[tag] 为键进行排序。
58
+ # sort_rules:
37
59
  ```
38
60
 
39
61
  插件会在生成网站时自动生成 Service Worker、注册代码、DOM 端支持代码(如果功能开启了的话),版本更新文件需要通过 `hexo swpp` 命令手动生成。
@@ -42,12 +64,11 @@ swpp:
42
64
 
43
65
  ⚠ 注意:
44
66
 
45
- + 如果你的网站启用 `swpp` 后还没有发布过,请勿将 `warn_level` 设置为 0,这会导致构建失败。
46
67
  + 尽可能在压缩网站内容前执行 `hexo swpp`,因为部分压缩插件可能会出现同样的内容连续压缩结果不一样的问题,这会导致插件错误地更新缓存。
47
68
  + 如果你的网站发布过程不使用 `hexo deploy` 指令,则不要启用 `auto_exec` 选项。
48
69
  + 将 `npm_url` 调整为非官方 URL 后检查版本时可能会出现 404 错误。
49
70
 
50
- 插件的具体配置见 [Swpp Backends 官方文档 | 山岳库博](https://kmar.top/posts/b70ec88f/)。
71
+ SWPP v3 的文档尚未完成,敬请期待。
51
72
 
52
73
  ### 指令
53
74
 
@@ -55,28 +76,11 @@ swpp:
55
76
  2. `hexo swpp -b` / `hexo swpp --build` - 构建 json 文件,同 `hexo swpp`
56
77
  3. `hexo swpp -t [URL]` / `hexo swpp --test [URL]` - 尝试拉取指定 URL,使用时将 `[URL]` 替换为有效的 HTTP/HTTPS 链接(需要附带协议头)
57
78
 
58
- ### sort
59
-
60
- `hexo-swpp` 在规则文件中添加了一个配置项——`sort`,用法如下:
61
-
62
- ```javascript
63
- module.exports.config = {
64
- sort: {
65
- posts: 'title',
66
- pages: 'title',
67
- tags: 'name'
68
- }
69
- }
70
- ```
71
-
72
- 该配置项是为了对 hexo 中的一些变量进行排序,避免每次生成 HTML 时由于这些变量的顺序变动导致生成结果不完全相同。上方代码给出的值为插件的缺省值,用户设置该项不会直接覆盖这些值,只有用户也声明 `posts`、`pages` 或 `tags` 时才会覆盖对应的值。
73
-
74
- 其中 key 值为要排序的变量的名称,value 为变量排序时的依据,填 `false` 表示禁用该项排序,填 `true` 表示以 value 本身为键进行排序,填字符串表示以 `value[tag]` 为键进行排序。
75
-
76
- ---
77
-
78
79
  ## 更新日志
79
80
 
81
+ + 3.4+
82
+ 1. 适配 `swpp-backends@3`
83
+
80
84
  + 3.3+
81
85
  1. 版本检查改为仅在执行 `hexo server` 时执行 \[3.3.0]
82
86
  2. 支持自定义版本更新检查的 URL \[3.3.0]
package/dist/index.js CHANGED
@@ -27,17 +27,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const fs = __importStar(require("fs"));
30
- const node_fetch_1 = __importDefault(require("node-fetch"));
31
- const swpp_backends_1 = __importDefault(require("swpp-backends"));
32
30
  const path_1 = __importDefault(require("path"));
31
+ const swpp_backends_1 = require("swpp-backends");
33
32
  const logger = require('hexo-log').default();
34
33
  const CONSOLE_OPTIONS = [
35
34
  { name: '-t, --test', desc: '尝试拉取指定链接' },
36
35
  { name: '-b, --build', desc: '构建 swpp,留空参数与使用该参数效果一致' }
37
36
  ];
38
- let rules;
39
- // noinspection JSUnusedGlobalSymbols
40
- function start(hexo) {
37
+ let runtimeData;
38
+ let compilationData;
39
+ const configLoadWaitList = [];
40
+ /** 等待配置加载 */
41
+ function waitUntilConfig() {
42
+ if (runtimeData)
43
+ return Promise.resolve();
44
+ return new Promise(resolve => configLoadWaitList.push(resolve));
45
+ }
46
+ /** 运行插件 */
47
+ async function start(hexo) {
48
+ // @ts-ignore
49
+ globalThis.hexo = hexo;
41
50
  const config = hexo.config;
42
51
  const pluginConfig = config['swpp'] ?? config.theme_config['swpp'];
43
52
  if (!pluginConfig?.enable)
@@ -45,13 +54,13 @@ function start(hexo) {
45
54
  if (process.argv.find(it => 'server'.startsWith(it)))
46
55
  checkVersion(pluginConfig);
47
56
  let init = false;
48
- hexo.on('generateBefore', () => {
57
+ hexo.on('generateBefore', async () => {
49
58
  if (init)
50
59
  return;
51
60
  init = true;
52
- loadRules(hexo);
53
- sort(hexo);
54
- buildServiceWorker(hexo);
61
+ buildServiceWorker(hexo, pluginConfig);
62
+ sort(hexo, pluginConfig);
63
+ await initRules(hexo, pluginConfig);
55
64
  });
56
65
  hexo.extend.console.register('swpp', 'Hexo Swpp 的相关指令', {
57
66
  options: CONSOLE_OPTIONS
@@ -64,9 +73,9 @@ function start(hexo) {
64
73
  logger.error('[SWPP][CONSOLE] --test/-t 后应跟随一个有效 URL');
65
74
  }
66
75
  else {
67
- initRules(hexo);
76
+ await initRules(hexo, pluginConfig);
68
77
  try {
69
- const response = await swpp_backends_1.default.utils.fetchFile(test);
78
+ const response = await compilationData.compilationEnv.read('FETCH_NETWORK_FILE').fetch(test);
70
79
  if ([200, 301, 302, 307, 308].includes(response.status)) {
71
80
  logger.info('[SWPP][LINK TEST] 资源拉取成功,状态码:' + response.status);
72
81
  }
@@ -84,38 +93,73 @@ function start(hexo) {
84
93
  logger.warn('[SWPP][CONSOLE] -build/-b 后方不应跟随参数');
85
94
  }
86
95
  }
87
- if (build || !test)
88
- await runSwpp(hexo, pluginConfig);
96
+ if (build || !test) {
97
+ try {
98
+ await runSwpp(hexo, pluginConfig);
99
+ }
100
+ catch (e) {
101
+ logger.error('执行 SWPP 指令时出现异常');
102
+ console.error(e);
103
+ process.exit(-1);
104
+ }
105
+ }
89
106
  });
90
107
  if (pluginConfig['auto_exec']) {
91
108
  hexo.on('deployBefore', async () => {
92
- await runSwpp(hexo, pluginConfig);
109
+ try {
110
+ await runSwpp(hexo, pluginConfig);
111
+ }
112
+ catch (e) {
113
+ logger.error('执行 SWPP 指令时出现异常');
114
+ console.error(e);
115
+ process.exit(-1);
116
+ }
93
117
  });
94
118
  }
95
119
  }
96
- function initRules(hexo) {
97
- if (!rules)
98
- rules = loadRules(hexo);
120
+ async function initRules(hexo, pluginConfig) {
121
+ if (!runtimeData) {
122
+ try {
123
+ await loadConfig(hexo, pluginConfig);
124
+ configLoadWaitList.forEach(it => it());
125
+ }
126
+ catch (e) {
127
+ logger.error("[SWPP] 加载时遇到错误。");
128
+ logger.error(e);
129
+ process.exit(0x114514);
130
+ }
131
+ }
99
132
  }
133
+ /** 运行 swpp 指令 */
100
134
  async function runSwpp(hexo, pluginConfig) {
101
135
  const config = hexo.config;
102
136
  if (!fs.existsSync(config.public_dir))
103
137
  return logger.warn(`[SWPP] 未检测到发布目录,跳过指令执行`);
104
- initRules(hexo);
105
- if (!rules.config.json)
106
- return logger.error(`[SWPP] JSON 生成功能未开启,跳过指令执行`);
107
- const url = config.url;
108
- await Promise.all([
109
- swpp_backends_1.default.loader.loadUpdateJson(url + '/update.json', pluginConfig['warn_level'] ?? 1),
110
- swpp_backends_1.default.loader.loadVersionJson(url + '/cacheList.json', pluginConfig['warn_level'] ?? 1)
138
+ await initRules(hexo, pluginConfig);
139
+ const scanner = new swpp_backends_1.ResourcesScanner(compilationData);
140
+ const versionFile = compilationData.compilationEnv.read('SWPP_JSON_FILE');
141
+ const tracker = await scanner.scanLocalFile(config.public_dir);
142
+ const jsonBuilder = await tracker.diff();
143
+ function writeFile(path, content) {
144
+ return new Promise((resolve, reject) => {
145
+ fs.writeFile(path, content, 'utf-8', (err) => {
146
+ if (err)
147
+ reject(err);
148
+ else
149
+ resolve();
150
+ });
151
+ });
152
+ }
153
+ const json = await jsonBuilder.buildJson();
154
+ return Promise.all([
155
+ writeFile(path_1.default.join(hexo.config.public_dir, versionFile.versionPath), JSON.stringify(json)),
156
+ writeFile(path_1.default.join(hexo.config.public_dir, versionFile.trackerPath), tracker.json())
111
157
  ]);
112
- await buildVersionJson(hexo);
113
- const dif = swpp_backends_1.default.builder.analyzeVersion();
114
- await buildUpdateJson(hexo, dif);
115
158
  }
159
+ /** 检查 swpp-backends 的版本 */
116
160
  function checkVersion(pluginConfig) {
117
161
  const root = pluginConfig['npm_url'] ?? 'https://registry.npmjs.org';
118
- (0, node_fetch_1.default)(`${root}/swpp-backends/${swpp_backends_1.default.version}`)
162
+ fetch(`${root}/swpp-backends/${swpp_backends_1.swppVersion}`)
119
163
  .then(response => {
120
164
  if (![200, 301, 302, 307, 308].includes(response.status))
121
165
  return Promise.reject(response.status);
@@ -124,7 +168,7 @@ function checkVersion(pluginConfig) {
124
168
  if ('error' in json)
125
169
  return Promise.reject(json.error);
126
170
  if ('deprecated' in json) {
127
- logger.warn(`[SWPP][VersionChecker] 您使用的 swpp-backends@${swpp_backends_1.default.version} 已被弃用,请更新版本!`);
171
+ logger.warn(`[SWPP][VersionChecker] 您使用的 swpp-backends@${swpp_backends_1.swppVersion} 已被弃用,请更新版本!`);
128
172
  logger.warn(`\t补充信息:${json['deprecated']}`);
129
173
  logger.warn('请注意!!!当您看到这条消息时,表明您正在使用的后台版本存在漏洞,请务必更新版本!!!');
130
174
  logger.info('可以使用 `npm update swpp-backends` 更新后台版本,或使用您自己常用的等效命令。');
@@ -139,80 +183,74 @@ function checkVersion(pluginConfig) {
139
183
  logger.warn(err);
140
184
  });
141
185
  }
142
- function loadRules(hexo) {
186
+ /** 加载配置文件 */
187
+ async function loadConfig(hexo, pluginConfig) {
143
188
  const themeName = hexo.config.theme;
144
- swpp_backends_1.default.event.addRulesMapEvent(rules => {
145
- if ('cacheList' in rules && !('cacheRules' in rules)) {
146
- rules.cacheRules = rules['cacheList'];
147
- delete rules['cacheList'];
148
- }
149
- if ('getCdnList' in rules && !('getRaceUrls' in rules)) {
150
- rules.getRaceUrls = rules['getCdnList'];
151
- delete rules['getCdnList'];
189
+ const loader = new swpp_backends_1.ConfigLoader();
190
+ loader.loadFromCode({
191
+ compilationEnv: {
192
+ DOMAIN_HOST: new URL(hexo.config.root, hexo.config.url)
152
193
  }
153
194
  });
154
- const result = swpp_backends_1.default.loader.loadRules('./', 'sw-rules', [`./themes/${themeName}/`, `./node_modules/hexo-${themeName}/`]);
155
- swpp_backends_1.default.builder.calcEjectValues(hexo);
156
- return result;
157
- }
158
- async function buildUpdateJson(hexo, dif) {
159
- const url = hexo.config.url;
160
- const json = swpp_backends_1.default.builder.buildUpdateJson(url, dif);
161
- fs.writeFileSync(`${hexo.config.public_dir}/update.json`, JSON.stringify(json), 'utf-8');
162
- logger.info('成功生成:update.json');
163
- }
164
- async function buildVersionJson(hexo) {
165
- const url = hexo.config.url;
166
- let protocol, domain;
167
- if (url.startsWith('https:')) {
168
- protocol = 'https://';
169
- }
170
- else {
171
- protocol = 'http://';
195
+ const configName = pluginConfig['config_name'] ?? 'swpp.config';
196
+ const configPaths = [configName, `./themes/${themeName}/${configName}`, `./node_modules/hexo-${themeName}/${configName}`];
197
+ const extnameList = ['ts', 'cts', 'mts', 'js', 'cjs', 'mjs'];
198
+ for (let path of configPaths) {
199
+ for (let extname of extnameList) {
200
+ const uri = `${path}.${extname}`;
201
+ if (fs.existsSync(uri)) {
202
+ await loader.load(path_1.default.resolve(uri));
203
+ break;
204
+ }
205
+ }
172
206
  }
173
- domain = url.substring(protocol.length, url.endsWith('/') ? url.length - 1 : url.length);
174
- // @ts-ignore
175
- const json = await swpp_backends_1.default.builder.buildVersionJson(protocol, domain, path_1.default.resolve('./', hexo.config.public_dir));
176
- fs.writeFileSync(`${hexo.config.public_dir}/cacheList.json`, JSON.stringify(json), 'utf-8');
177
- logger.info('成功生成:cacheList.json');
207
+ const result = loader.generate();
208
+ runtimeData = result.runtime;
209
+ compilationData = result.compilation;
178
210
  }
179
- function buildServiceWorker(hexo) {
180
- const rules = swpp_backends_1.default.cache.readRules();
181
- const pluginConfig = rules.config;
211
+ /** 注册生成器 */
212
+ function buildServiceWorker(hexo, hexoConfig) {
213
+ const { serviceWorker, auto_register, gen_dom } = hexoConfig;
182
214
  // 生成 sw
183
- if (pluginConfig.serviceWorker) {
184
- hexo.extend.generator.register('build_service_worker', () => {
185
- return {
186
- path: 'sw.js',
187
- data: swpp_backends_1.default.builder.buildServiceWorker()
188
- };
215
+ if (serviceWorker ?? true) {
216
+ hexo.extend.generator.register('build_service_worker', async () => {
217
+ await waitUntilConfig();
218
+ return ({
219
+ path: compilationData.compilationEnv.read('SERVICE_WORKER') + '.js',
220
+ data: new swpp_backends_1.SwCompiler().buildSwCode(runtimeData)
221
+ });
189
222
  });
190
223
  }
191
224
  // 生成注册 sw 的代码
192
- if (pluginConfig.register) {
193
- hexo.extend.injector.register('head_begin', () => pluginConfig.register.builder(hexo.config.url, hexo, pluginConfig));
225
+ if (auto_register ?? true) {
226
+ waitUntilConfig().then(() => {
227
+ hexo.extend.injector.register('head_begin', `<script>(${runtimeData.domConfig.read('registry')})()</script>`);
228
+ });
194
229
  }
195
230
  // 生成 sw-dom.js
196
- if (pluginConfig.dom) {
197
- // noinspection HtmlUnknownTarget
198
- hexo.extend.injector.register('head_end', `<script defer src="/sw-dom.js"></script>`);
199
- hexo.extend.generator.register('build_dom_js', () => {
231
+ if (gen_dom ?? true) {
232
+ hexo.extend.injector.register('head_end', () => {
233
+ // noinspection HtmlUnknownTarget
234
+ return `<script defer src="/sw-dom.js"></script>`;
235
+ });
236
+ hexo.extend.generator.register('build_dom_js', async () => {
237
+ await waitUntilConfig();
200
238
  return {
201
239
  path: 'sw-dom.js',
202
- data: swpp_backends_1.default.builder.buildDomJs()
240
+ data: runtimeData.domConfig.buildJsSource()
203
241
  };
204
242
  });
205
243
  }
206
244
  }
207
245
  /** 对 hexo 中的变量进行排序 */
208
- function sort(hexo) {
246
+ function sort(hexo, pluginConfig) {
209
247
  const version = hexo.version;
210
248
  let Locals;
211
249
  if (version.startsWith('7')) {
212
- Locals = require(path_1.default.resolve('./', 'node_modules/hexo/dist/hexo/locals')).prototype;
250
+ Locals = require(path_1.default.resolve('node_modules/hexo/dist/hexo/locals')).prototype;
213
251
  }
214
252
  else {
215
- Locals = require(path_1.default.resolve('./', 'node_modules/hexo/lib/hexo/locals')).prototype;
253
+ Locals = require(path_1.default.resolve('node_modules/hexo/lib/hexo/locals')).prototype;
216
254
  }
217
255
  const compare = (a, b) => {
218
256
  const result = a.length === b.length ? a < b : a.length < b.length;
@@ -269,8 +307,7 @@ function sort(hexo) {
269
307
  pages: 'title',
270
308
  tags: 'name'
271
309
  };
272
- // @ts-ignore
273
- Object.assign(list, swpp_backends_1.default.cache.readRules().config['sort'] ?? {});
310
+ Object.assign(list, pluginConfig.sort_rules ?? {});
274
311
  const getter = Locals.get;
275
312
  Locals.get = function (name) {
276
313
  const result = getter.call(this, name);
@@ -285,13 +322,8 @@ function sort(hexo) {
285
322
  return result;
286
323
  };
287
324
  }
288
- try {
289
- // noinspection TypeScriptUnresolvedReference
290
- // @ts-ignore
291
- start(hexo);
292
- }
293
- catch (e) {
294
- logger.error("[SWPP] 加载时遇到错误,可能是由于缺少规则文件。");
325
+ start(hexo).catch(e => {
326
+ logger.error("[SWPP] 加载时遇到严重错误!");
295
327
  logger.error(e);
296
- process.exit(114514);
297
- }
328
+ process.exit(0x19491001);
329
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-swpp",
3
- "version": "3.3.7",
3
+ "version": "3.4.0-alpha.110",
4
4
  "main": "dist/index.js",
5
5
  "types": "types/index.d.ts",
6
6
  "files": [
@@ -22,17 +22,15 @@
22
22
  },
23
23
  "homepage": "https://kmar.top/posts/73014407/",
24
24
  "devDependencies": {
25
- "@types/node": "^20.4.7",
26
- "@types/node-fetch": "^2.6.4",
27
- "hexo": "7.0.0",
28
- "typescript": "^5.1.6"
25
+ "@types/node": "^22.0.2",
26
+ "hexo": "^7.3.0",
27
+ "typescript": "^5.5.4"
29
28
  },
30
29
  "dependencies": {
31
- "hexo-log": "^4.1.0",
32
- "node-fetch": "^2.6.12"
30
+ "hexo-log": "^4.1.0"
33
31
  },
34
32
  "peerDependencies": {
35
- "swpp-backends": "^2.1.2"
33
+ "swpp-backends": "^3.0.0-ahpla.100"
36
34
  },
37
35
  "scripts": {}
38
36
  }