add: build environment (dev/prod)
change: locale filename
This commit is contained in:
		
							parent
							
								
									7e993e4c55
								
							
						
					
					
						commit
						3d1cf9ded3
					
				
							
								
								
									
										13
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								README.md
									
									
									
									
									
								
							@ -13,6 +13,7 @@ This is an addon/plugin template for [Zotero](https://www.zotero.org/).
 | 
				
			|||||||
- TypeScript support;
 | 
					- TypeScript support;
 | 
				
			||||||
- Build addon settings and versions automatically;
 | 
					- Build addon settings and versions automatically;
 | 
				
			||||||
- Build and reload code in Zotero automatically;
 | 
					- Build and reload code in Zotero automatically;
 | 
				
			||||||
 | 
					- Development/production build environment;
 | 
				
			||||||
- Release to GitHub automatically(using [release-it](https://github.com/release-it/release-it));
 | 
					- Release to GitHub automatically(using [release-it](https://github.com/release-it/release-it));
 | 
				
			||||||
- Extensive skeleton;
 | 
					- Extensive skeleton;
 | 
				
			||||||
- Some sample code of UI and lifecycle.
 | 
					- Some sample code of UI and lifecycle.
 | 
				
			||||||
@ -42,9 +43,13 @@ This is an addon/plugin template for [Zotero](https://www.zotero.org/).
 | 
				
			|||||||
> Be careful to set the addonID and addonRef to avoid confliction.
 | 
					> Be careful to set the addonID and addonRef to avoid confliction.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Run `npm install` to set up the plugin and install dependencies. If you don't have NodeJS installed, please download it [here](https://nodejs.org/en/);
 | 
					- Run `npm install` to set up the plugin and install dependencies. If you don't have NodeJS installed, please download it [here](https://nodejs.org/en/);
 | 
				
			||||||
- Run `npm run build` to build the plugin. The xpi for installation and the built code is under builds folder.
 | 
					- Run `npm run build` to build the plugin in production mode. Run `npm run build-dev` to build the plugin in development mode. The xpi for installation and the built code is under builds folder.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Plugin Life Cycle
 | 
					> What the difference between dev & prod?
 | 
				
			||||||
 | 
					> - This environment variable is stored in `Zotero.AddonTemplate.env`. The outputs to console is disabled in prod mode.
 | 
				
			||||||
 | 
					> - You can decide what users cannot see/use based on this variable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### About Life Cycle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. When install/enable/startup triggered from Zotero, `bootstrap.js` > `startup` is called
 | 
					1. When install/enable/startup triggered from Zotero, `bootstrap.js` > `startup` is called
 | 
				
			||||||
   - Wait for Zotero ready
 | 
					   - Wait for Zotero ready
 | 
				
			||||||
@ -182,11 +187,11 @@ This section shows the directory structure of a template.
 | 
				
			|||||||
│      └─locale     # locale
 | 
					│      └─locale     # locale
 | 
				
			||||||
│         ├─en-US
 | 
					│         ├─en-US
 | 
				
			||||||
│         │      overlay.dtd
 | 
					│         │      overlay.dtd
 | 
				
			||||||
│         │      addontemplate.properties
 | 
					│         │      addon.properties
 | 
				
			||||||
│         │
 | 
					│         │
 | 
				
			||||||
│         └─zh-CN
 | 
					│         └─zh-CN
 | 
				
			||||||
│         |      overlay.dtd
 | 
					│         |      overlay.dtd
 | 
				
			||||||
│         │      addontemplate.properties
 | 
					│         │      addon.properties
 | 
				
			||||||
│
 | 
					│
 | 
				
			||||||
├─builds            # build dir
 | 
					├─builds            # build dir
 | 
				
			||||||
│  └─.xpi
 | 
					│  └─.xpi
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										18
									
								
								build.js
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								build.js
									
									
									
									
									
								
							@ -85,7 +85,9 @@ async function main() {
 | 
				
			|||||||
  const buildDir = "builds";
 | 
					  const buildDir = "builds";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  console.log(
 | 
					  console.log(
 | 
				
			||||||
    `[Build] BUILD_DIR=${buildDir}, VERSION=${version}, BUILD_TIME=${buildTime}`
 | 
					    `[Build] BUILD_DIR=${buildDir}, VERSION=${version}, BUILD_TIME=${buildTime}, ENV=${[
 | 
				
			||||||
 | 
					      process.env.NODE_ENV,
 | 
				
			||||||
 | 
					    ]}`
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  clearFolder(buildDir);
 | 
					  clearFolder(buildDir);
 | 
				
			||||||
@ -98,6 +100,9 @@ async function main() {
 | 
				
			|||||||
  await esbuild
 | 
					  await esbuild
 | 
				
			||||||
    .build({
 | 
					    .build({
 | 
				
			||||||
      entryPoints: ["src/index.ts"],
 | 
					      entryPoints: ["src/index.ts"],
 | 
				
			||||||
 | 
					      define: {
 | 
				
			||||||
 | 
					        __env__: process.env.NODE_ENV,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      bundle: true,
 | 
					      bundle: true,
 | 
				
			||||||
      // Entry should be the same as addon/chrome/content/overlay.xul
 | 
					      // Entry should be the same as addon/chrome/content/overlay.xul
 | 
				
			||||||
      outfile: path.join(buildDir, "addon/chrome/content/scripts/index.js"),
 | 
					      outfile: path.join(buildDir, "addon/chrome/content/scripts/index.js"),
 | 
				
			||||||
@ -156,6 +161,17 @@ async function main() {
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // _ = replace.sync({
 | 
				
			||||||
 | 
					  //   files: [path.join(buildDir, "addon/chrome/content/scripts/index.js")],
 | 
				
			||||||
 | 
					  //   from: [/__env__/g]
 | 
				
			||||||
 | 
					  // });
 | 
				
			||||||
 | 
					  // console.log(
 | 
				
			||||||
 | 
					  //   "[Build] Run replace in ",
 | 
				
			||||||
 | 
					  //   _.filter((f) => f.hasChanged).map(
 | 
				
			||||||
 | 
					  //     (f) => `${f.file} : ${f.numReplacements} / ${f.numMatches}`
 | 
				
			||||||
 | 
					  //   )
 | 
				
			||||||
 | 
					  // );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  console.log("[Build] Replace OK");
 | 
					  console.log("[Build] Replace OK");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  console.log("[Build] Addon prepare OK");
 | 
					  console.log("[Build] Addon prepare OK");
 | 
				
			||||||
 | 
				
			|||||||
@ -11,10 +11,11 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "main": "src/index.ts",
 | 
					  "main": "src/index.ts",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "build": "node build.js",
 | 
					    "build-dev": "cross-env NODE_ENV=development node build.js",
 | 
				
			||||||
 | 
					    "build": "cross-env NODE_ENV=production node build.js",
 | 
				
			||||||
    "start": "node start.js",
 | 
					    "start": "node start.js",
 | 
				
			||||||
    "stop": "node stop.js",
 | 
					    "stop": "node stop.js",
 | 
				
			||||||
    "prerestart": "npm run build",
 | 
					    "prerestart": "npm run build-dev",
 | 
				
			||||||
    "restart": "node restart.js",
 | 
					    "restart": "node restart.js",
 | 
				
			||||||
    "release": "release-it",
 | 
					    "release": "release-it",
 | 
				
			||||||
    "test": "echo \"Error: no test specified\" && exit 1"
 | 
					    "test": "echo \"Error: no test specified\" && exit 1"
 | 
				
			||||||
@ -30,11 +31,12 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "homepage": "https://github.com/windingwind/zotero-addon-template#readme",
 | 
					  "homepage": "https://github.com/windingwind/zotero-addon-template#readme",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "zotero-plugin-toolkit": "^0.0.9"
 | 
					    "zotero-plugin-toolkit": "^0.0.10"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@types/node": "^18.11.17",
 | 
					    "@types/node": "^18.11.17",
 | 
				
			||||||
    "compressing": "^1.6.3",
 | 
					    "compressing": "^1.6.3",
 | 
				
			||||||
 | 
					    "cross-env": "^7.0.3",
 | 
				
			||||||
    "esbuild": "^0.16.10",
 | 
					    "esbuild": "^0.16.10",
 | 
				
			||||||
    "release-it": "^14.14.3",
 | 
					    "release-it": "^14.14.3",
 | 
				
			||||||
    "replace-in-file": "^6.3.5",
 | 
					    "replace-in-file": "^6.3.5",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/addon.ts
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/addon.ts
									
									
									
									
									
								
							@ -4,17 +4,24 @@ import AddonViews from "./views";
 | 
				
			|||||||
import AddonLocale from "./locale";
 | 
					import AddonLocale from "./locale";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ZoteroToolkit from "zotero-plugin-toolkit";
 | 
					import ZoteroToolkit from "zotero-plugin-toolkit";
 | 
				
			||||||
import Locale from "./locale";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Addon {
 | 
					class Addon {
 | 
				
			||||||
 | 
					  // A global Zotero instance
 | 
				
			||||||
  public Zotero!: _ZoteroConstructable;
 | 
					  public Zotero!: _ZoteroConstructable;
 | 
				
			||||||
  public events: AddonEvents;
 | 
					  // Root path to access the resources
 | 
				
			||||||
  public views: AddonViews;
 | 
					 | 
				
			||||||
  public prefs: AddonPrefs;
 | 
					 | 
				
			||||||
  public locale: AddonLocale;
 | 
					 | 
				
			||||||
  public toolkit: ZoteroToolkit;
 | 
					 | 
				
			||||||
  // root path to access the resources
 | 
					 | 
				
			||||||
  public rootURI!: string;
 | 
					  public rootURI!: string;
 | 
				
			||||||
 | 
					  // Env type, see build.js
 | 
				
			||||||
 | 
					  public env!: "development" | "production";
 | 
				
			||||||
 | 
					  // Lifecycle events
 | 
				
			||||||
 | 
					  public events: AddonEvents;
 | 
				
			||||||
 | 
					  // UI operations
 | 
				
			||||||
 | 
					  public views: AddonViews;
 | 
				
			||||||
 | 
					  // Scripts for prefpane window
 | 
				
			||||||
 | 
					  public prefs: AddonPrefs;
 | 
				
			||||||
 | 
					  // Runtime locale with .properties
 | 
				
			||||||
 | 
					  public locale: AddonLocale;
 | 
				
			||||||
 | 
					  // A toolkit instance. See zotero-plugin-toolkit
 | 
				
			||||||
 | 
					  public toolkit: ZoteroToolkit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
    this.events = new AddonEvents(this);
 | 
					    this.events = new AddonEvents(this);
 | 
				
			||||||
 | 
				
			|||||||
@ -3,10 +3,46 @@ import AddonModule from "./module";
 | 
				
			|||||||
import { config } from "../package.json";
 | 
					import { config } from "../package.json";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AddonEvents extends AddonModule {
 | 
					class AddonEvents extends AddonModule {
 | 
				
			||||||
  private notifierCallback: any;
 | 
					 | 
				
			||||||
  constructor(parent: Addon) {
 | 
					  constructor(parent: Addon) {
 | 
				
			||||||
    super(parent);
 | 
					    super(parent);
 | 
				
			||||||
    this.notifierCallback = {
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // This function is the setup code of the addon
 | 
				
			||||||
 | 
					  public async onInit() {
 | 
				
			||||||
 | 
					    this._Addon.Zotero = Zotero;
 | 
				
			||||||
 | 
					    // @ts-ignore
 | 
				
			||||||
 | 
					    this._Addon.rootURI = rootURI;
 | 
				
			||||||
 | 
					    const development = "development";
 | 
				
			||||||
 | 
					    const production = "production";
 | 
				
			||||||
 | 
					    // The env will be replaced after esbuild
 | 
				
			||||||
 | 
					    // @ts-ignore
 | 
				
			||||||
 | 
					    this._Addon.env = __env__;
 | 
				
			||||||
 | 
					    this._Addon.toolkit.Tool.logOptionsGlobal.prefix = `[${config.addonName}]`;
 | 
				
			||||||
 | 
					    this._Addon.toolkit.Tool.logOptionsGlobal.disableConsole =
 | 
				
			||||||
 | 
					      this._Addon.env === "production";
 | 
				
			||||||
 | 
					    this._Addon.toolkit.Tool.log("init called");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initialize locale provider
 | 
				
			||||||
 | 
					    this._Addon.locale.initLocale();
 | 
				
			||||||
 | 
					    // Initialize preference window
 | 
				
			||||||
 | 
					    this.initPrefs();
 | 
				
			||||||
 | 
					    // Initialize notifier callback
 | 
				
			||||||
 | 
					    this.initNotifier();
 | 
				
			||||||
 | 
					    // Initialize UI elements
 | 
				
			||||||
 | 
					    this._Addon.views.initViews();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public onUnInit(): void {
 | 
				
			||||||
 | 
					    this._Addon.toolkit.Tool.log("uninit called");
 | 
				
			||||||
 | 
					    this.unInitPrefs();
 | 
				
			||||||
 | 
					    //  Remove elements and do clean up
 | 
				
			||||||
 | 
					    this._Addon.views.unInitViews();
 | 
				
			||||||
 | 
					    // Remove addon object
 | 
				
			||||||
 | 
					    Zotero.AddonTemplate = undefined;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private initNotifier() {
 | 
				
			||||||
 | 
					    const callback = {
 | 
				
			||||||
      notify: async (
 | 
					      notify: async (
 | 
				
			||||||
        event: string,
 | 
					        event: string,
 | 
				
			||||||
        type: string,
 | 
					        type: string,
 | 
				
			||||||
@ -26,17 +62,9 @@ class AddonEvents extends AddonModule {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public async onInit() {
 | 
					 | 
				
			||||||
    this._Addon.Zotero = Zotero;
 | 
					 | 
				
			||||||
    // @ts-ignore
 | 
					 | 
				
			||||||
    this._Addon.rootURI = rootURI;
 | 
					 | 
				
			||||||
    // This function is the setup code of the addon
 | 
					 | 
				
			||||||
    this._Addon.toolkit.Tool.log(`${config.addonName}: init called`);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Register the callback in Zotero as an item observer
 | 
					    // Register the callback in Zotero as an item observer
 | 
				
			||||||
    let notifierID = Zotero.Notifier.registerObserver(this.notifierCallback, [
 | 
					    let notifierID = Zotero.Notifier.registerObserver(callback, [
 | 
				
			||||||
      "tab",
 | 
					      "tab",
 | 
				
			||||||
      "item",
 | 
					      "item",
 | 
				
			||||||
      "file",
 | 
					      "file",
 | 
				
			||||||
@ -50,14 +78,9 @@ class AddonEvents extends AddonModule {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      false
 | 
					      false
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Initialize preference window
 | 
					 | 
				
			||||||
    this.initPrefs();
 | 
					 | 
				
			||||||
    this._Addon.views.initViews();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public initPrefs() {
 | 
					  private initPrefs() {
 | 
				
			||||||
    this._Addon.toolkit.Tool.log(this._Addon.rootURI);
 | 
					 | 
				
			||||||
    const prefOptions = {
 | 
					    const prefOptions = {
 | 
				
			||||||
      pluginID: config.addonID,
 | 
					      pluginID: config.addonID,
 | 
				
			||||||
      src: this._Addon.rootURI + "chrome/content/preferences.xhtml",
 | 
					      src: this._Addon.rootURI + "chrome/content/preferences.xhtml",
 | 
				
			||||||
@ -81,16 +104,6 @@ class AddonEvents extends AddonModule {
 | 
				
			|||||||
      this._Addon.toolkit.Compat.unregisterPrefPane();
 | 
					      this._Addon.toolkit.Compat.unregisterPrefPane();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  public onUnInit(): void {
 | 
					 | 
				
			||||||
    const Zotero = this._Addon.Zotero;
 | 
					 | 
				
			||||||
    this._Addon.toolkit.Tool.log(`${config.addonName}: uninit called`);
 | 
					 | 
				
			||||||
    this.unInitPrefs();
 | 
					 | 
				
			||||||
    //  Remove elements and do clean up
 | 
					 | 
				
			||||||
    this._Addon.views.unInitViews();
 | 
					 | 
				
			||||||
    // Remove addon object
 | 
					 | 
				
			||||||
    Zotero.AddonTemplate = undefined;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default AddonEvents;
 | 
					export default AddonEvents;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,13 @@
 | 
				
			|||||||
import Addon from "./addon";
 | 
					 | 
				
			||||||
import AddonModule from "./module";
 | 
					import AddonModule from "./module";
 | 
				
			||||||
 | 
					import { config } from "../package.json";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AddonLocale extends AddonModule {
 | 
					class AddonLocale extends AddonModule {
 | 
				
			||||||
  private stringBundle: any;
 | 
					  private stringBundle: any;
 | 
				
			||||||
    constructor(parent: Addon) {
 | 
					
 | 
				
			||||||
        super(parent);
 | 
					  public initLocale() {
 | 
				
			||||||
        this.stringBundle = Components.classes['@mozilla.org/intl/stringbundle;1']
 | 
					    this.stringBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
 | 
				
			||||||
      .getService(Components.interfaces.nsIStringBundleService)
 | 
					      .getService(Components.interfaces.nsIStringBundleService)
 | 
				
			||||||
            .createBundle('chrome://addontemplate/locale/addontemplate.properties');
 | 
					      .createBundle(`chrome://${config.addonRef}/locale/addon.properties`);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public getString(localString: string): string {
 | 
					  public getString(localString: string): string {
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,7 @@ class AddonPrefs extends AddonModule {
 | 
				
			|||||||
    // This function is called when the prefs window is opened
 | 
					    // This function is called when the prefs window is opened
 | 
				
			||||||
    // See addon/chrome/content/preferences.xul onpaneload
 | 
					    // See addon/chrome/content/preferences.xul onpaneload
 | 
				
			||||||
    this._window = _window;
 | 
					    this._window = _window;
 | 
				
			||||||
    this._Addon.toolkit.Tool.log(`${config.addonName}: init preferences`);
 | 
					    this._Addon.toolkit.Tool.log("init preferences");
 | 
				
			||||||
    this.updatePrefsUI();
 | 
					    this.updatePrefsUI();
 | 
				
			||||||
    this.bindPrefEvents();
 | 
					    this.bindPrefEvents();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -20,7 +20,7 @@ class AddonPrefs extends AddonModule {
 | 
				
			|||||||
    // You can initialize some UI elements on prefs window
 | 
					    // You can initialize some UI elements on prefs window
 | 
				
			||||||
    // with this._window.document
 | 
					    // with this._window.document
 | 
				
			||||||
    // Or bind some events to the elements
 | 
					    // Or bind some events to the elements
 | 
				
			||||||
    this._Addon.toolkit.Tool.log(`${config.addonName}: init preferences UI`);
 | 
					    this._Addon.toolkit.Tool.log("init preferences UI");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private bindPrefEvents() {
 | 
					  private bindPrefEvents() {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user