add: auto hot reload support
This commit is contained in:
parent
c4fc2c44e7
commit
3ba1f9d40e
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@ -4,6 +4,13 @@
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "StartDev",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run", "start-watch"]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
|
26
README.md
26
README.md
@ -42,6 +42,7 @@ If you are using this repo, I recommended that you put this badge ([![Using Zote
|
||||
|
||||
- Event-driven, functional programming, under extensive skeleton;
|
||||
- Simple and user-friendly, works out-of-the-box.
|
||||
- ⭐[New!]Auto hot reload! Whenever the source code is modified, automatically compile and reload. [See here→](#auto-hot-reload)
|
||||
- Abundant examples in `src/modules/examples.ts`, covering most of the commonly used APIs in plugins(using [zotero-plugin-toolkit](https://github.com/windingwind/zotero-plugin-toolkit));
|
||||
- TypeScript support:
|
||||
- Full type definition support for the whole Zotero project, which is written in JavaScript(using [zotero-types](https://github.com/windingwind/zotero-types));
|
||||
@ -50,7 +51,7 @@ If you are using this repo, I recommended that you put this badge ([);
|
||||
- ⭐[New!]Compatibilities for Zotero 6 & Zotero 7.(using [zotero-plugin-toolkit](https://github.com/windingwind/zotero-plugin-toolkit))
|
||||
- Compatibilities for Zotero 6 & Zotero 7.(using [zotero-plugin-toolkit](https://github.com/windingwind/zotero-plugin-toolkit))
|
||||
|
||||
## Examples
|
||||
|
||||
@ -211,6 +212,29 @@ vim ./scripts/zotero-cmd.json
|
||||
|
||||
11. Click "Inspect Main Process"
|
||||
|
||||
### Auto Hot Reload
|
||||
|
||||
Tired of endless restarting? Forget about it!
|
||||
|
||||
1. Run `npm run start-watch`. (If Zotero is already running, use `npm run watch`)
|
||||
2. Coding. (Yes, that's all)
|
||||
|
||||
When file changes are detected in `src` or `addon`, the plugin will do automatically compiled and reloaded.
|
||||
|
||||
|
||||
<details style="text-indent: 2em">
|
||||
<summary>💡 Steps to add this feature to an existing plugin</summary>
|
||||
|
||||
1. Add `if (reason == ADDON_DISABLE) {Services.obs.notifyObservers(null, "startupcache-invalidate", null);}` to `shutdown()` in the `addon/bootstrap.js`
|
||||
2. Copy `scripts/reload.mjs`
|
||||
3. Copy `reload`, `watch`, and `start-watch` commands in `package.json`
|
||||
4. Run `npm install --save-dev chokidar-cli`
|
||||
5. Done.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
### Debug in Zotero
|
||||
|
||||
You can also:
|
||||
|
3
addon/bootstrap.js
vendored
3
addon/bootstrap.js
vendored
@ -106,6 +106,9 @@ function shutdown({ id, version, resourceURI, rootURI }, reason) {
|
||||
if (reason === APP_SHUTDOWN) {
|
||||
return;
|
||||
}
|
||||
if (reason == ADDON_DISABLE) {
|
||||
Services.obs.notifyObservers(null, "startupcache-invalidate", null);
|
||||
}
|
||||
if (typeof Zotero === "undefined") {
|
||||
Zotero = Components.classes["@zotero.org/Zotero;1"].getService(
|
||||
Components.interfaces.nsISupports
|
||||
|
@ -17,13 +17,14 @@
|
||||
"build-prod": "cross-env NODE_ENV=production node scripts/build.mjs",
|
||||
"build": "concurrently -c auto npm:build-prod npm:tsc",
|
||||
"tsc": "tsc --noEmit",
|
||||
"start-z6": "node scripts/start.mjs --z 6",
|
||||
"start-z7": "node scripts/start.mjs --z 7",
|
||||
"start": "node scripts/start.mjs",
|
||||
"start-watch": "concurrently -c auto npm:start npm:watch",
|
||||
"stop": "node scripts/stop.mjs",
|
||||
"restart-dev": "npm run build-dev && npm run stop && npm run start",
|
||||
"restart-prod": "npm run build-prod && npm run stop && npm run start",
|
||||
"restart": "npm run restart-dev",
|
||||
"reload": "npm run build-dev && node scripts/reload.mjs",
|
||||
"watch": "chokidar \"src/*.*\" \"addon/*.*\" -c \"npm run reload\"",
|
||||
"release": "release-it",
|
||||
"lint": "prettier --write . && eslint . --ext .ts --fix",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
@ -46,6 +47,7 @@
|
||||
"@types/node": "^20.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.2",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"compressing": "^1.9.0",
|
||||
"concurrently": "^8.0.1",
|
||||
"cross-env": "^7.0.3",
|
||||
|
42
scripts/reload.mjs
Normal file
42
scripts/reload.mjs
Normal file
@ -0,0 +1,42 @@
|
||||
import { exit, argv } from "process";
|
||||
import minimist from "minimist";
|
||||
import { execSync } from "child_process";
|
||||
import details from "../package.json" assert { type: "json" };
|
||||
const { addonID, addonName } = details.config;
|
||||
const version = details.version;
|
||||
import cmd from "./zotero-cmd.json" assert { type: "json" };
|
||||
const { exec } = cmd;
|
||||
|
||||
// Run node reload.js -h for help
|
||||
const args = minimist(argv.slice(2));
|
||||
|
||||
const zoteroPath = exec[args.zotero || args.z || Object.keys(exec)[0]];
|
||||
const profile = args.profile || args.p;
|
||||
const startZotero = `${zoteroPath} --debugger --purgecaches ${
|
||||
profile ? `-p ${profile}` : ""
|
||||
}`;
|
||||
|
||||
const script = `
|
||||
(async () => {
|
||||
const { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
|
||||
const addon = await AddonManager.getAddonByID("${addonID}");
|
||||
addon.disable();
|
||||
await Zotero.Promise.delay(1000);
|
||||
addon.enable();
|
||||
const progressWindow = new Zotero.ProgressWindow({ closeOnClick: true });
|
||||
progressWindow.changeHeadline("${addonName} Hot Reload");
|
||||
progressWindow.progress = new progressWindow.ItemProgress(
|
||||
"chrome://zotero/skin/tick.png",
|
||||
"VERSION=${version}, BUILD=${new Date().toLocaleString()}. By zotero-plugin-toolkit"
|
||||
);
|
||||
progressWindow.progress.setProgress(100);
|
||||
progressWindow.show();
|
||||
progressWindow.startCloseTimer(5000);
|
||||
})()`;
|
||||
|
||||
const url = `zotero://ztoolkit-debug/?run=${encodeURIComponent(script)}`;
|
||||
|
||||
const command = `${startZotero} -url "${url}"`;
|
||||
|
||||
execSync(command);
|
||||
exit(0);
|
@ -3,33 +3,11 @@ import { execSync } from "child_process";
|
||||
import cmd from "./zotero-cmd.json" assert { type: "json" };
|
||||
const { killZoteroWindows, killZoteroUnix } = cmd;
|
||||
|
||||
const MAX_WAIT_TIME = 10000;
|
||||
|
||||
const startTime = new Date().getTime();
|
||||
|
||||
try {
|
||||
if (process.platform === "win32") {
|
||||
execSync(killZoteroWindows);
|
||||
|
||||
// wait until zotero.exe is fully stopped. maximum wait for 10 seconds
|
||||
while (new Date().getTime() - startTime <= MAX_WAIT_TIME) {
|
||||
try {
|
||||
execSync('tasklist | find /i "zotero.exe"');
|
||||
} catch (e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
execSync(killZoteroUnix);
|
||||
|
||||
// wait until zotero is fully stopped. maximum wait for 10 seconds
|
||||
while (new Date().getTime() - startTime <= MAX_WAIT_TIME) {
|
||||
try {
|
||||
execSync("ps aux | grep -i zotero");
|
||||
} catch (e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -3,7 +3,6 @@
|
||||
"killZoteroWindows": "taskkill /f /im zotero.exe",
|
||||
"killZoteroUnix": "kill -9 $(ps -x | grep zotero)",
|
||||
"exec": {
|
||||
"6": "/path/to/zotero6.exe",
|
||||
"7": "/path/to/zotero7.exe"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user