0

If I want to create an add-on for Ember.js, let's call it ember-awesome for the purpose of this question, that is a wrapper around a library awesome-lib.js and its extensions. How do I create a shim around that library and any extensions I want to bundle with it?

Assume for a moment that awesome-lib.js can have plugins or extensions to its funcitonality, e.g. awesome-ext-foo.js, awesome-ext-bar.js, etc. What is the best way to write a shim for and add-on that provides awesome-lib, awesome-ext-foo, and awesome-ext-bar to the component?

I thought I might be able to define a single shim, e.g. vendor/shims/awesome-lib-shim.js as such:

// ember-awesome/vendor/shims/awesome-lib-shim.js
define("awesome-lib", [
  "awesome-lib",
  "awesome-ext-foo",
  "awesome-ext-bar"], function(awesomeLib, extFoo, extBar) {
  return {
    "default": awesomeLib,
    "foo": extFoo,
    "bar": extBar
  };
})

And use it in my ember-awesome/index.js as such:

// ember-awesome/index.js
module.exports = {
  name: "ember-awesome",

  included: function(app) {
    ...
    this.app.import("vendor/shims/awesome-lib-shim.js", {
      type: "vendor",
      exports: {
        "awesome-lib": ["default"],
        "awesome-ext-foo": ["foo"],
        "awesome-ext-bar": ["bar"],
      }
    });
    ...
  }
  ...
};

This doesn't seem to work though. I can always create different shims, sure, but thought it would make the most sense to bundle like-components together in the same shim.

A good, real world, example of the type library and extension complexity I'm looking to write an add-on around is the markdown-it and its extensions

Sean Quinn
  • 2,131
  • 1
  • 18
  • 48

1 Answers1

0

Okay, it seems like you need to understand a few concepts first. Every call to define just defines one modul.

The second argument is an array of dependencies. So lets look at your example:

define("awesome-lib", [
  "awesome-lib",
  "awesome-ext-foo",
  "awesome-ext-bar"], ...)

This actually defines an model called awesome-lib that depends on three modules: awesome-lib, awesome-ext-foo, awesome-ext-bar.

So this can't work. Especially it would mean that there are already three modules defined: awesome-lib, awesome-ext-foo and awesome-ext-bar. If however awesome-lib is already defined, why redefine it?

So generally you don't need a vendor-shim if something is already available as module. You use a vendor shim to make something global exported available as a module because you don't want to use the global everywhere, and maybe hope that in the future your dependency will be available as a module.

However, for this reason its absolutely possible to define multiple modules in one vendor shim with something like that:

define("awesome-lib", [], () => {
  return window.AwesomeLib;
})

define("awesome-ext-foo", ["awesome-lib"], awesomeLib => {
  return window.AwesomeLib.use(window.AwesomeExtFoo)
})

Next, the definition of exports during app.import is not doing anything.

For your example however I don't see any reason to write an addon for that! You should install it from npm and then import it with ember-browserify, That way it should also work for the extensions.

But if you want to write an addon to provide additional templates I also would rely on ember-browserify to install the dependency whenever possible.

Lux
  • 17,835
  • 5
  • 43
  • 73
  • I should have clarified in the example above was a library, and extensions to said library, that were not modularized in the sense of AMD, CommonJS, etc. Thanks for your answer. – Sean Quinn Jul 11 '16 at 01:38