add: build environment (dev/prod)

change: locale filename
This commit is contained in:
xiangyu 2022-12-31 12:27:01 +08:00
parent 7e993e4c55
commit 3d1cf9ded3
9 changed files with 99 additions and 57 deletions

View File

@ -13,6 +13,7 @@ This is an addon/plugin template for [Zotero](https://www.zotero.org/).
- TypeScript support;
- Build addon settings and versions 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));
- Extensive skeleton;
- 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.
- 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
- Wait for Zotero ready
@ -182,11 +187,11 @@ This section shows the directory structure of a template.
│ └─locale # locale
│ ├─en-US
│ │ overlay.dtd
│ │ addontemplate.properties
│ │ addon.properties
│ │
│ └─zh-CN
│ | overlay.dtd
│ │ addontemplate.properties
│ │ addon.properties
├─builds # build dir
│ └─.xpi

View File

@ -85,7 +85,9 @@ async function main() {
const buildDir = "builds";
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);
@ -98,6 +100,9 @@ async function main() {
await esbuild
.build({
entryPoints: ["src/index.ts"],
define: {
__env__: process.env.NODE_ENV,
},
bundle: true,
// Entry should be the same as addon/chrome/content/overlay.xul
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] Addon prepare OK");

View File

@ -11,10 +11,11 @@
},
"main": "src/index.ts",
"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",
"stop": "node stop.js",
"prerestart": "npm run build",
"prerestart": "npm run build-dev",
"restart": "node restart.js",
"release": "release-it",
"test": "echo \"Error: no test specified\" && exit 1"
@ -30,11 +31,12 @@
},
"homepage": "https://github.com/windingwind/zotero-addon-template#readme",
"dependencies": {
"zotero-plugin-toolkit": "^0.0.9"
"zotero-plugin-toolkit": "^0.0.10"
},
"devDependencies": {
"@types/node": "^18.11.17",
"compressing": "^1.6.3",
"cross-env": "^7.0.3",
"esbuild": "^0.16.10",
"release-it": "^14.14.3",
"replace-in-file": "^6.3.5",

View File

@ -4,17 +4,24 @@ import AddonViews from "./views";
import AddonLocale from "./locale";
import ZoteroToolkit from "zotero-plugin-toolkit";
import Locale from "./locale";
class Addon {
// A global Zotero instance
public Zotero!: _ZoteroConstructable;
public events: AddonEvents;
public views: AddonViews;
public prefs: AddonPrefs;
public locale: AddonLocale;
public toolkit: ZoteroToolkit;
// root path to access the resources
// Root path to access the resources
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() {
this.events = new AddonEvents(this);

View File

@ -3,10 +3,46 @@ import AddonModule from "./module";
import { config } from "../package.json";
class AddonEvents extends AddonModule {
private notifierCallback: any;
constructor(parent: Addon) {
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 (
event: 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
let notifierID = Zotero.Notifier.registerObserver(this.notifierCallback, [
let notifierID = Zotero.Notifier.registerObserver(callback, [
"tab",
"item",
"file",
@ -50,14 +78,9 @@ class AddonEvents extends AddonModule {
},
false
);
// Initialize preference window
this.initPrefs();
this._Addon.views.initViews();
}
public initPrefs() {
this._Addon.toolkit.Tool.log(this._Addon.rootURI);
private initPrefs() {
const prefOptions = {
pluginID: config.addonID,
src: this._Addon.rootURI + "chrome/content/preferences.xhtml",
@ -81,16 +104,6 @@ class AddonEvents extends AddonModule {
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;

View File

@ -1,19 +1,18 @@
import Addon from "./addon";
import AddonModule from "./module";
import { config } from "../package.json";
class AddonLocale extends AddonModule {
private stringBundle: any;
constructor(parent: Addon) {
super(parent);
this.stringBundle = Components.classes['@mozilla.org/intl/stringbundle;1']
.getService(Components.interfaces.nsIStringBundleService)
.createBundle('chrome://addontemplate/locale/addontemplate.properties');
}
private stringBundle: any;
public getString(localString: string): string {
return this.stringBundle.GetStringFromName(localString);
}
public initLocale() {
this.stringBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService)
.createBundle(`chrome://${config.addonRef}/locale/addon.properties`);
}
public getString(localString: string): string {
return this.stringBundle.GetStringFromName(localString);
}
}
export default AddonLocale;
export default AddonLocale;

View File

@ -11,7 +11,7 @@ class AddonPrefs extends AddonModule {
// This function is called when the prefs window is opened
// See addon/chrome/content/preferences.xul onpaneload
this._window = _window;
this._Addon.toolkit.Tool.log(`${config.addonName}: init preferences`);
this._Addon.toolkit.Tool.log("init preferences");
this.updatePrefsUI();
this.bindPrefEvents();
}
@ -20,7 +20,7 @@ class AddonPrefs extends AddonModule {
// You can initialize some UI elements on prefs window
// with this._window.document
// 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() {