0

I have a module that requires underscore:

import _ from "underscore"

var numbers = [1, 4, 6, 7, 9, 3, 22, 11, 54, 99, 100];
var evens = _.filter(numbers, x => x % 2 === 0);

document.getElementById('output').innerText = evens;

This works fine in my gulp task:

gulp.task('process-scripts', function(cb) {
    var builder = new Builder('Scripts', 'Scripts/config.js');
    builder.buildStatic('main.js', 'app/main.min.js', { minify: true });
    cb();
});

And with this script tag:

<script src="/app/main.min.js"></script>

The problem is, I want to pull underscore out into it's own script. So I changed my gulp task to:

gulp.task('process-scripts', function(cb) {
    var builder = new Builder('Scripts', 'Scripts/config.js');
    builder.buildStatic('underscore', 'app/vendor.min.js', { minify: true });
    builder.buildStatic('main.js - underscore', 'app/main.min.js', { minify: true, globalDeps: {underscore: '_'} });
    cb();
});

Doing so, I get underscore pulled out of the main bundle and put into the vendor bundle. At the bottom of main.min.js, the bundle creates this code:

(function(factory) {
  factory(_);
});

And I get the error: "Uncaught ReferenceError: _ is not defined"

I tried this same thing using jQuery in place of underscore, and it worked just fine. What I noticed while stepping through the code is that when the code at the bottom of main is called, $ was found on the window object, and so there was no error.

How can I get the main module to recognize underscore in the vendor script?

M Falanga
  • 1,897
  • 17
  • 21
  • do you include app/vendor.min.js before app/main.min.js? does the app/vendor.min.js alone declares _ as a global variable? – Oleksii Rudenko Oct 07 '15 at 19:07
  • Yes, the app/vendor.min.js script tag comes before app/main.min.js The vendor.min.js file is only underscore, which was installed with `jspm install underscore` It's in the map object of config.js as: ..., map: { "underscore": "npm:underscore@1.8.3" }, ... – M Falanga Oct 07 '15 at 20:14

1 Answers1

0

If you create a self-executing bundle for npm:underscore the _ is not added to the window object. Therefore your main module can not access it neither by import _ from 'underscore' nor via window._.

If you want to bundle your app in separate modules your should rather create just bundles using builder.bundle() in favor of self-executing bundles. This way you have to use system.js to load your scripts but you will be able to access the underscore bundle in you app module.

For example:

System.import('app/vendor').then(() => {
   System.import('app/main');
});
brass monkey
  • 5,841
  • 10
  • 36
  • 61
  • Any idea why `_` wouldn't get added to the window object? jQuery's `$` seems to get added just fine. Does it have something to do with the way jQuery is packaged compared to underscore? – M Falanga Oct 15 '15 at 17:42
  • Yes. When you look at the source you see that jquery is added to window when loaded in a browser environment: `if ( typeof noGlobal === strundefined ) { window.jQuery = window.$ = jQuery; }` There is also a discussion why jquery is doing this (https://github.com/jquery/jquery/pull/557). underscore just exports `_`. So it has to be imported explicitly. – brass monkey Oct 15 '15 at 19:48