Ember Inspector started as a Chrome-only extension, and then evolved into a browser agnostic addon. It is currently an ember-cli app that supports all browsers, even ones that don't have addons/devtools support.
Below is how we were able to achieve portability. Some points below may prove helpful in designing the new framework.
Even though both Chrome and Firefox support using HTML, CSS, and Javascript to build addons, when it comes to addon/devtools-specific API, they have completely different implementations. That's where adapters come in. All browser specific methods are extracted into the adapter layer to keep the actual code browser agnostic.
Example code:
highlightElement(viewId) {
let element = document.getElementById(viewId});
// Open the "Elements" devtools panel and highlight this element.
this.adapter.inspectElement(element);
}
Since not all target environments support the same features, we sometimes need to check if a specific method is supported to see if we show/hide a specific button:
if (this.adapter.canInspectElement) {
// browser supports inspecting elements in the "Element" tab
this.clickable = true;
}
I first considered using ember-cli's environment
variable to differentiate between different browser builds since ember-cli is already well prepared to handle environment-based config. Then I quickly realized that the target browser is actually orthogonal to the environment, as I wanted both development
and production
builds for the same browser.
As a result I added the concept of dist
that would create a browser specific build based on the EMBER_DIST
value. So just like ember-cli comes with environment specific builds:
# default ember-cli environment builds
EMBER_ENV=development ember build
# after adding the "dist" concept
EMBER_DIST=chrome EMBER_ENV=development ember build
# Using npm scripts, we end up with the following commands:
npm run build:chrome # default is development
npm run build:firefox
npm run build:chrome:production
npm run build:firefox:production
npm run build:all:production
We end up with [n] x [m] different builds where [n] is the number of environments (development, production) and [m] is the number of dists (chrome, firefox, bookmarklet...).
You can see the list of all commands in the repo's package.json.
The EMBER_DIST
value affects the build in the following ways:
- Determines the target directory for the build. i.e.
EMBER_DIST=chrome
would end up indist_chrome
,EMBER_DIST=firefox
would end up indist_firefox
. - Determines the adapter to use.
EMBER_DIST=chrome
would attach thechrome
adapter, etc. - Performs dist-specific customizations. For example, Firefox prefers to keep the js and css assets non-minified for an easier review process.
Ember Inspector currently has 4 dists. chrome
, firefox
, bookmarklet
, and websocket
- and therefore 4 adapters (in addition to the basic
adapter - the parent class that they all extend). We don't need to support all of these, but I do believe our code should be pluggable to add any custom dists.
chrome
is for both Chrome and Opera (and any blink browser I think?)firefox
is for Firefox :)bookmarklet
is for all desktop browsers that don't have addons/devtools (Safari, IE). Downside is we can't use devtool-specific functionality such as linking to the "sources" panel or highlighting DOM elements...websocket
is for all browsers including mobile browsers. Downside is that in addition to the bookmarklet downsides, it requires a server (there's an ember-cli addon for that).
- Ember Inspector uses a sophisticated build tool (ember-cli) with existing conventions. This makes it easier to have multiple builds. However other existing addon authors probably have their own build process, and may not be willing to change it.
- Ember Inspector is a devtools addon, but there are many other types of addons which may be harder to port.
I think we may end up with more than one repo:
- Adapter library that abstracts addon APIs into browser agnostic methods. It would also include a way to "check" if a specific method is supported.
- Build process that generates separate
dists
. Should this be ember-cli? Or should we support the major build tools out there (broccoli-portable-addon, ember-cli-portable-addon, grunt-portable-addon, gulp-portable-addon)? Should ember-cli be the optional happy path to encourage people to use Ember, but at the same time avoid alienating non-ember users? Needs more thought. - A way to easily build devtools addons. Setting up a devtools addon is currently a very complicated process. The hardest part is probably setting up communication between the devtools panel and the tab being debugged. Having this working out of the box may encourage the development of more devtools addons.