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