Aurelia CLI bundler options


#1

Hi, I’m trying to wrap my head around the aurelia cli bundler. More specifically the when/why/how of dependencies, especially with 3rd party modules. We used jspm in the past and I’d like to move away from that and use aurelia cli bundler with system.js (I think)

A lot of our components make use of jquery plugins…like bootstrap-multiselect
I figured out (through trial and error) that to get bootstrap-multiselect to load I had to add it into the dependencies section of the vendor-bundle like so:

“dependencies”: [
“jquery”,
{
“name”: “datatables.net”,
“path”: “…/node_modules/datatables.net”,
“main”: “js/jquery.dataTables”,
“deps”: [“jquery”],
“exports”: “" }, { "name": "bootstrap", "path": "../node_modules/bootstrap/dist", "main": "js/bootstrap.min", "deps": ["jquery"], "exports": "”,
“resources”: [
“css/bootstrap.css”
]
},
{
“name”: “bootstrap-multiselect”,
“path”: “…/node_modules/bootstrap-multiselect/dist”,
“main”: “js/bootstrap-multiselect”,
“deps”: [“jquery”],
“exports”: “$”,
“resources”: [
“css/bootstrap-multiselect.css”
]
}

As you can see, I also added in datatables.net, which also uses jquery. But it doesn’t seem very consistent in terms of loading w/out jquery reference issues and I don’t understand all the properties and use-cases very well (deps, exports,etc.). And I can’t seem to find an in-depth discussion about dependencies. Are these node.js topics I should be researching? The Aurelia site covers basic usage and that seems to be about it. Is there any more in-depth material or explanation about dependencies and/or using jquery plugins and how to best load them into the bundle?


#2

What you are trying to do here is called shim (wrapping legacy libs in AMD module), which could be quite frustrating if you are not familiar with AMD module.

If you follow the cli doc, using prepend is way easier than shim.

Remove the deps config for jquery/bootstrap/dataTables/multiselect, add all of them above requirejs in prepend list.

"prepend": [
  /* ... some exising prepends ... */
  "node_modules/jquery/dist/jquery.min.js",
  "node_modules/datatables.net/js/jquery.dataTables.js",
  // note bootstrap-multiselect uses bootstrap v3, not current v4.
  // you need to install current bootstrap version
  "node_modules/node_modules/bootstrap/dist/js/bootstrap.min.js",
  "node_modules/bootstrap-multiselect/dist/js/bootstrap-multiselect.js",
  "node_modules/requirejs/require.js"
],

So jQuery will be available as global variables, use $ or jQuery freely in your code.

To teach eslint about this global, edit your .eslintrc.json file.

{
  //...
  "globals": {
    "$": true,
    // if you only use "$" in code, you don't need next one.
    "jQuery": true
  }
}

Those css files can be auto traced, you don’t need any config for them.
Just do in html. Note I ignored “/dist/” part in the css path, cli bundler can smartly figure it out.

<require from="bootstrap/css/bootstrap.css"></require>
<require from="bootstrap-multiselect/css/bootstrap-multiselect.css"></require>

Furthermore, bootstrap v3 needs some font, update aurelia_project/aurelia.json.

  "bundles": [
  // ...
  ],
  "copyFiles": {
    "node_modules/bootstrap/dist/fonts/*": "bootstrap/fonts"
  }

This will copy font files to local folder bootstrap/fonts/, make sure to deploy them as well to production site.

Another better option
Use CDN for all jquery/bootstrap/dataTables/multiselect in script tags in index.html head section, so you don’t have to touch aurelia.json files, don’t have to handle fonts, also gains performance because they are cached by user browsers even when you release new version of your app.


#3

So is it fair to say the prepend section of Aurelia.json is more or less a wrapper to requireJs shims and takes the same options as described in requireJs shims? Or is it something completely outside what requireJs does and dependencies is more like a requireJs shim option that supports the same data structure as requireJs shims (I hope my question makes sense)?


#4

No. Prepended files are as they are.
As they are processed by browser before requirejs/systemjs (they are before requirejs in your prepend list), they are living in a space where no AMD loader is available (requirejs/systemjs has not kicked in yet)

This has no effect on really legacy libs (like bootstrap v3). And for some libs supporting UMD (detecting AMD and commonjs env), they will run themselves in legacy mode (creating global variables instead of creating AMD or commonjs module).