Skip to content

Instantly share code, notes, and snippets.

@teddyzeenny
Created May 23, 2015 16:55
Show Gist options
  • Save teddyzeenny/49459a483f4f690b5bed to your computer and use it in GitHub Desktop.
Save teddyzeenny/49459a483f4f690b5bed to your computer and use it in GitHub Desktop.
Ember Inspector Portability

How Ember Inspector handles portability

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.

Adapters

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;
}

Multiple "dists"

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 in dist_chrome, EMBER_DIST=firefox would end up in dist_firefox.
  • Determines the adapter to use. EMBER_DIST=chrome would attach the chrome adapter, etc.
  • Performs dist-specific customizations. For example, Firefox prefers to keep the js and css assets non-minified for an easier review process.

Types of dists

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...
  • websocketis 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).

Things to consider

  • 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment