adopted-ember-addons / ember-electron

:zap: Build, test, compile and package desktop apps with Ember and Electron
https://ember-electron.js.org/
Other
805 stars 111 forks source link

RFC: ember-electron initializer pattern #329

Closed anulman closed 4 years ago

anulman commented 6 years ago

Summary

ember-electron should expose and adopt a standard mechanism with which to wrap and run "initializer" code. This will allow us to clean our growing main.js file into compartmentalized steps, and encourage community addons to use our process.env.EMBER_ELECTRON flag to customize build pipelines.

Motivation

With growing adoption of e-electron, we would like to make it easier for Ember app developers to use familiar tools while benefiting from the lower-level APIs Electron exposes. This includes:

Detailed design

This design is based on these principles:

Initializers should therefore be implemented: 1) As a set of JS object instances, which MUST expose an initialize and MAY expose a cleanup function, a before declaration, and an after declaration;

Assuming the above criteria are met, we should be able to use e-cli to 1) find any addons with the ember-electron keyword; and 2) merge their ember-electron trees into the main one we compile.

We may also be able to adopt e-cli's initializer scheduling protocol.

How We Teach This

We should call these objects initializers, as this is in line with Ember's initializer + instance-initializer concepts: short-lived scripts, run once during app boot, which help configure and orchestrate the app's dependencies.

The concept should be self-explanatory, and may even lead to easier onboarding by giving names & clear separation of concerns to what is currently included in the main.js file. For example, we may split current content into:

Drawbacks

The biggest risk seems to be with teaching proper Squirrel event handling, esp for Windows. This has always been an exception (ie that users should handle Squirrel events before anything else). Ideally it will be fast enough to run a handle-squirrel-events.js script { before: 'all' }.

It also encourages a more compartmentalized approach to the main.js file, which may not be familiar to developers starting down the NodeJS learning curve.

Alternatives

This approach is the result of several iterations of including third-party code in main proc scripts. Currently, solutions seem ad-hoc, and do not reasonably support addon authors' use cases.

Unresolved questions

anulman commented 6 years ago

An early list of addon authors we should be communicating with:

felixrieseberg commented 6 years ago

I have almost no opinion on this - it's something that I in Ghost Desktop wouldn't really need, but if anyone could benefit from it, I'm all for it.

There's definitely an issue around Ember only living in one window and if this approach brings ember-style development closer to the main process, then I'm all for it.

anulman commented 6 years ago

@felixrieseberg Yeah, that's the goal—I'd like to communicate that better in the RFC. Should I include a link to an example, or add some detail to the Design section?

ember-render-vendor is a (very purpose-specific) example of how this would work for addons:

But I think this thinking makes several broader-use scenarios possible, including:

1) Projects like ember-simple-auth could eg include and default to a fs-storage-plus-based encrypted store vs the default session-stores/localstorage when running in electron envs; 2) Offline-mode / PWA-friendly addons could detect the env and back ember-data with fs / IndexedDb / SQLite-backed store caches; and 3) A single-purpose "main app initializer" could help better define the native / web code boundary for new users, esp those looking to write multi-window apps.

CSstefan commented 6 years ago

let initializersDir = join(resolve(__dirname, '../'), 'ember-electron', 'initializers'); This would be a better way to locate the initializers directory and has been tested in a MacOS dev environment and a built package installed in a Linux environment.

CSstefan commented 6 years ago

There needs to be some way to override an initializer. So, in the case of my used of ember-render-vendor, I want to pass additional parameters to Puppeteer that do not exist in the initializer provided with ember-render-vendor. Perhaps there could be a way to put one's own initializer (eg. ember-render-vendor.js) in the e-e initializers folder and the presence of that initializer override the one bundled in the dependancy? Suggestions?

CSstefan commented 6 years ago

I tested putting the my own ember-render-vendor initializer into my ember-electron/initializers but this happens...

Build failed.
Build Canceled: Broccoli Builder ran into an error with BroccoliMergeTrees plugin. 💥
...
Pass option { overwrite: true } to mergeTrees in order to have the latter file win.
...

Maybe this will work. I'm just not sure where to pass that overwrite: true option.

anulman commented 6 years ago

@CSstefan Re your first note, I think it's an addon's responsibility to define its configuration interface, eg via e-cli-build.js, config/environment.js, or package.json files. If the Puppeteer changes solved your problem, we should move this chat to an ember-render-vendor-specific issue.

For your second, that's a problem with e-r-v code as well, though a helpful note on this issue. Were this pattern implemented in e-electron, we'd need to be sensitive to mergeTrees conflicts, and ensure userland files overwrite similarly-named files included from e-electron "plugins".

anulman commented 6 years ago

FWIW, this issue proposes making changes similar to:

bendemboski commented 4 years ago

Closing due to inactivity. If anybody wants to pick this up and move it forward, feel free to comment or re-open.