Skip to content

Instantly share code, notes, and snippets.

@foxnewsnetwork
Created January 5, 2017 21:25
Show Gist options
  • Save foxnewsnetwork/276eca2274a328b085ee54926e609cdb to your computer and use it in GitHub Desktop.
Save foxnewsnetwork/276eca2274a328b085ee54926e609cdb to your computer and use it in GitHub Desktop.
How to shim commonjs files in addons with ember-cli without using ember-browserify

The Problem

Say you're building an ember addon that has a commonjs dependency, what do you do?

That is, you have a commonjs file dependency that looks something like:

module.exports = {
  whatever: function() { ... }
}

app.import('your-file.js', { using: [{ transformation: 'amd' }] }); won't work because the file is commonjs and not AMD

ember-browserify will work, but due to a problem with ember-cli, you will only be able to use:

import whatever from 'npm:your-file';

from within the app/ directory, but in many cases you need to put code into the addon directory.

The Solution

Use webpack to pre-process your commonjs file.

npm install --save broccoli-webpack

Here's an example of doing exactly this with the normalizr.js library:

/* jshint node: true */
'use strict';
const Funnel = require('broccoli-funnel');
const mergeTrees = require('broccoli-merge-trees');
const Webpack = require('broccoli-webpack');
const normalizr = new Funnel('node_modules/normalizr/dist', {
  destDir: 'normalizr',
  files: ['index.js']
});

const PackOpts = {
  entry: 'normalizr/dist/index.js',
  output: {
    filename: 'normalizr/index.js',
    library: 'normalizr',
    libraryTarget: 'umd'
  }
};

const packedNormalizr = new Webpack([normalizr], PackOpts);

const transformAMD = (name) => ({
  using: [{ transformation: 'amd', as: name }]
});

module.exports = {
  name: 'ember-normalizr-shim',

  included(app) {
    this._super.included.apply(this, arguments);

    // see: https://github.com/ember-cli/ember-cli/issues/3718
    while (typeof app.import !== 'function' && app.app) {
      app = app.app;
    }

    this.app = app;

    const vendor = this.treePaths.vendor;
    // requires ember-cli 2.9+
    // https://github.com/ember-cli/ember-cli/pull/5976
    app.import(vendor + '/normalizr/index.js', transformAMD('normalizr'));

    return app;
  },

  treeForVendor(vendorTree) {
    const trees = [packedNormalizr];

    if (vendorTree) {
      trees.push(vendorTree);
    }

    return mergeTrees(trees);
  }
};

Check out the entire code here: https://github.com/foxnewsnetwork/ember-normalizr-shim

@foxnewsnetwork
Copy link
Author

Update: with the new ember-cli builds 2.18 and above (and probably some below), we can just @rwjblue's ember-cli-cjs-transform to achieve what this does

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment