5.2 KiB
5.2 KiB
| sidebar_position |
|---|
| 5 |
Create a Capacitor Electron Plugin
- Create or open a Capacitor V3 compatible plugin in your editor of choice.
- Create a folder named
electronin the root of this plugin, with a sub-folder ofsrcin it. - Create a ts file in the above
srcfolder namedindex.tsand either paste in the following example code of the@capacitor/dialogplugin and edit away, or create your own from scratch:
import { dialog } from 'electron'
import type {
DialogPlugin,
AlertOptions,
PromptOptions,
PromptResult,
ConfirmOptions,
ConfirmResult,
} from '../../src/definitions';
export class DialogElectron implements DialogPlugin {
async alert(options: AlertOptions): Promise<void> {
await dialog.showMessageBox({message: options.message + ' --- electron'});
}
async prompt(options: PromptOptions): Promise<PromptResult> {
const val = window.prompt(options.message, options.inputText || '');
return {
value: val !== null ? val : '',
cancelled: val === null,
};
}
async confirm(options: ConfirmOptions): Promise<ConfirmResult> {
const val = window.confirm(options.message);
return {
value: val,
};
}
}
- Create a
.gitignorefile in theelectronfolder with the following:
dist
- Create a
.npmignorefile in theelectronfolder with the following:
src
- Create a
rollup.config.jsfile in theelectronfolder with the following:
export default {
input: 'electron/build/electron/src/index.js',
output: [
{
file: 'electron/dist/plugin.js',
format: 'cjs',
sourcemap: true,
inlineDynamicImports: true,
},
],
external: ['@capacitor/core'],
};
- Create a
tsconfig.jsonfile in theelectronfolder with the following:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"experimentalDecorators": true,
"noEmitHelpers": true,
"importHelpers": true,
"lib": ["dom", "es2020"],
"module": "commonjs",
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"outDir": "build",
"sourceMap": true,
"strict": false,
"target": "ES2017"
},
"include": ["src/**/*"]
}
- Modify the main
package.jsonin the root directory, add a property to thecapacitorobject so it reflects the following (android and ios shown for example only):
"capacitor": {
"ios": {
"src": "ios"
},
"android": {
"src": "android"
},
"electron": {
"src": "electron"
}
},
- Add your electron implementation to the
<root>/src/index.tswhere your web implementation is registered:
const Dialog = registerPlugin<DialogPlugin>('Dialog', {
web: () => import('./web').then(m => new m.DialogWeb()),
electron: () => (window as any).CapacitorCustomPlatform.plugins.DialogElectron
});
- Modify the main
package.jsonin the root directory, add an entry into thefilesarray of the following:electron/ - Modify the main
package.jsonin the root directory, add an entry into thescriptsobject of the following:"build-electron": "tsc --project electron/tsconfig.json && rollup -c electron/rollup.config.js && rimraf ./electron/build", - Modify the main
package.jsonin the root directory, edit thebuildentry in thescriptsobject to be the following:"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.js && npm run build-electron", - Run the
buildnpm script to build your plugin. - Release it to NPM then use in your capacitor apps as any other native plugin like android or ios. (dont forget to use
npx cap sync/copy/update/open @capacitor-community/electron)
Check out the plugin-example folder in the repo for a small demo plugin.
Events
If you want to emit events from your plugin, your class has to extend the NodeJS event emitter class. This is used by Capacitor Electron to determine if it should expose the addListener & removeListener functions to the Electron runtime plugin.
import { EventEmitter } from 'events';
export default class MyPlugin extends EventEmitter {
constructor() {
setInterval(() => {
this.emit('my-event', 'You successfully listened to the 10sec event!');
}, 10_000);
}
}
In your client code you can do the following:
const id = CapacitorCustomPlatform.plugins.MyPlugin.addListener('my-event', console.log);
// SOME CODE
CapacitorCustomPlatform.plugins.MyPlugin.removeListener(id);
Config
Plugins get access to the capacitor.config.ts config object as the first argument to the constructor. E.g.:
export default class App {
private config?: Record<string, any>;
constructor(config?: Record<string, any>) {
this.config = config;
}
getLaunchUrl(): string | undefined {
const url = this.config?.server?.url;
return url ? { url } : undefined;
}
}
Keep in mind that the config could possibly be undefined.