In 2019 and Beyond, How To Properly Integrate Bootstrap 4 Theme and External JS Lib Files?

Hey All! I know that earlier forms of this topic exist in this forum, however, their answers are rather dated, and unhelpful so far (no offense intended). So, I am rehashing the age-old issue of Bootstrap Themes in Meteor that require a variety of specialty JS modules, many with evolving versions that we’ll need to update over time.

Here’s what we’ve done. I hope someone can lend a hand and shed a little light on the matter.

  1. We bought/downloaded the sources for Black Dashboard PRO from themes.getbootstrap.com (Link points to docs).
  2. We copied all the assets (js, css, scss, etc) into a /imports/lib/blackpro/ directory inside our Meteor project.
  3. We added import '../imports/lib/blackpro/js/plugins/<pluginNam>.js' for almost every required plugin (see the link above in #1 for the full list) to the /client/main.js file so that all the dependencies load, omitting jQuery and Bootstrap and Moment because those were installed via meteor npm install --save .... No import errors so far…
  4. We installed fourseven:scss in our app.
  5. We linked ../imports/lib/blackpro/scss/black-dashboard.scss in /client/main.scss, which works.
  6. We put a basic HTML template in place to see the output in body.html.
  7. We started the app and have no access to any of the expected globals in the client using the Chrome Dev Tools JS Console. Seriously, none of the globals from the imported files in /client/main.js are in scope save those of jQuery.

EDIT 1: Here’s what we could do (according to other posts):

  1. Put all the bootstrap lib files in the /public folder.
  2. Reference the public static files directly in script tags just before the </body> tag in our body.html template.
  3. HODL while the scripts load globally and manually.
  4. Assume that the script globals will be available to template specific JS code.

EDIT 2: Here’s what we could also do, I am realizing:

  1. Leave the ui code inside imports/lib.
  2. Build the individual templates meticulously, one component at a time (e.g. nav, header, chart1, chart2, etc).
  3. Include those reusable individual templates in various “master” or “top-level” templates.
  4. Use specific import statements within the JS code on a per-template basis, importing the top-level export objects as-needed and using them in the proper event and rendered ui code.
  5. Write a book on how this is done for large-scale Meteor UI engineering and sell the idea to Manning Publications.

I feel like we are missing a very important and not-so-obvious fact about this here. Based on the Docs, I imagine that I could control load order in Meteor at a global level using import statements written in /client/main.js and all the resulting vars would load magically.

I also realize that there are some ES2017 standards at work here and I may be lacking in my understanding of how the files required for the bootstrap theme need to be included in the project altogether.

My ultimate goal is to be able to use Blaze to develop reusable components that leverage the files included in the Bootstrap theme and extend additional capabilities using other independent Bootstrap libraries to improve upon the theme we have.

Will someone help illuminate this more completely for me? Generally, how do we include external UI libraries for use in our Meteor client code?

Thank you for you help, everyone.

I asked the same question last week and no response. I guess it’s not achievable without getting a meteor library. If the library does not exist in atmosphere or npm, then you can’t use it.

I don’t think that is 100% correct. We were always able to use libraries by adding them into the /client/compatibility folder, which automatically includes them in the client build.

I tried compatibility folder approach but it didn’t work. So it depends at least

In an old project of mine (upgraded to 1.8.1) I have 17 libraries in /client/compatibility and no problem with any of them.

Does this also cover external css?

Ok, so…

  1. I put the Charts JS library in /client/compatibility.
  2. In body.js, I define:
Template.body.onRendered(function(){
  console.log("This is Charts JS", Chart);
})

The output in the client is:

ReferenceError: Chart is not defined
    at Blaze.TemplateInstance.<anonymous> (body.js:7)
    at blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3398
    at Function.Template._withTemplateInstanceFunc (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3769)
    at fireCallbacks (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3394)
    at Blaze.View.<anonymous> (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3487)
    at blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:1845
    at Object.Blaze._withCurrentView (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:2271)
    at blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:1844
    at Object.Tracker._runFlush (tracker.js:511)
    at onGlobalMessage (meteor.js?hash=857dafb4b9dff17e29ed8498a22ea5b1a3d6b41d:515)

This indicates that the compatibility approach is not working as expected.

Any ideas?

You can add external css in the client/css folder so it will be bundled automatically (no import)

Where did you get the Carts JS library from?

I also tried the latest Chart.min.js from GitHub to no avail: https://github.com/chartjs/Chart.js/releases/tag/v2.8.0

Thank you. Do you have any suggestions for integration of cdn version of js css?

SO, after playing a little more and trying EDIT 2 in the OP, I came to this and it works.

// body.js
import { Chart } from '../lib/blackpro/js/plugins/Chart.min.js'
import './body.html'
Template.body.onRendered(function(){
  console.log("This is charts", Chart)
})

Console output is:

This is charts ƒ (t,e){return this.construct(t,e),this}

SO, in conclusion thusfar, it means that we can import the entire custom theme SCSS into main.scss, but we cannot include the JS this way. Instead, we must rely on individual template JS files to include only the parts that we need in order to make the templates handle events as we intend in the UI.

NOW, there is the question of how to include these files in a CDN so the whole thing runs exceptionally fast?

ALSO, how do we include files from an external CDN, as @htchd7 points out?

I’m ever curious about all this as I am trying to fail fast with this and bail on Meteor for more hyped mainstream frameworks OR succeed and make Meteor our extended UI infrastructure.