52

I've created a Polymer element for rendering markdown which uses the marked.js library. I was wondering, what is the recommended way of loading in its dependencies?

Should I just use a script tag?

<script src="../marked/lib/marked.js"></script>

Or would it be better to put all of my dependencies into an html import and link to that one file. In this case I only have one dependency but I could easily have more.

<!-- in scripts.html -->
<script src="../marked/lib/marked.js"></script>
<script src="../foo/foo.js"></script>
<script src="../bar/bar.js"></script>

<!-- in mark-down.html -->
<link rel="import" href="scripts.html">

Note: These paths assume my element (and its dependencies) are being installed with bower so they should all be siblings in bower_components.

Jonathan Lin
  • 19,922
  • 7
  • 69
  • 65
robdodson
  • 6,616
  • 5
  • 28
  • 35

1 Answers1

51

Private resources should be installed in your component folder and used directly. But shared resources, those resources that other components my also want to use (like marked), should be handled as dependencies.

We suggest two conventions for handling shared dependencies:

  1. always use the canonical path which is ../<package-name> (you did this already). Polymer by convention expects a flat-dependency folder (as supported by Bower), so any resource you need must always be on this path.
  2. refer to an import for the shared resource.

In this case,

<script src="../marked/lib/marked.js">

meets the first convention. Your component can depend on marked package and expect it to exist at ../.

The second convention supports sharing. If more than one component in a project uses a script tag to load a library, the library will load multiple times. Imports, on the other hand, are de-duplicated, so you don't have this problem.

For example, if all components load marked the standard way:

<link rel="import" href="../marked-import/marked-import.html">

then you will only ever have one copy of the script loaded.

Additionally, imports allow you to indirect the actual resource. For example, normally marked-import would depend on marked and use a script tag to load the JavaScript. But in fact, any particular project author can modify the local marked-import.html to load the main code from a CDN or from any other location. By indirecting all access through the import, we create a single point of control.

Today, marked and other libraries do not include import files, so we have to fill in those gaps. Additionally, it will require coordination with other components (to have agreement on what the standard import name will be for any particular shared resource). As (and if) these conventions are adopted, such questions will lessen over time.

So, your component installed would look something like this:

/components
  /mark-down - depends on marked-import
  /marked-import - (controlled by user, can just depend on `../marked`)
  /marked
Eric Knudtson
  • 2,204
  • 2
  • 18
  • 12
Scott Miles
  • 11,025
  • 27
  • 32
  • Thanks. I assume that polymer marked-element follows the same pattern but I don't get how the reference to polymer.html works inside the marked-element.html in the root directory pointing to '../polymer/polymer.html'? I know after distributing the component everything is going to be in flattened in the bower_components directory but what about during the development of the component? Thanks – sepans Jun 24 '14 at 14:30
  • `polymer` is just a component like `marked`, `mark-down`, and `marked-import`. It should be sitting there in `/components` with the rest of them. We generally do not differentiate between development and deployment (unless you are talking about concatenating resources [vulcanizing], which is a different topic). – Scott Miles Jun 26 '14 at 21:19
  • 9
    Is this still the recommended approach nowadays for Polymer 1.0? What about ES6 modules? – Dan Dascalescu Sep 26 '16 at 22:37
  • Does this way of handling dependencies cause `marked` to be available globally? It seems so, and it's a drawback vs. ES6 modules... – Jonathan Lin Aug 12 '17 at 07:17