Preserving jQuery dependency for highcharts with r

2019-07-27 12:30发布

问题:

I'm testing out requireJS and am trying to make a simple project using highcharts. I've started with the requireJS multipage example project as a starting point.

My dir structure looks the same as the base structure, with highstock.js added in the lib directory.

  • page1.html: page 1 of the app.
  • page2.html: page 2 of the app.
  • js
    • app: the directory to store app-specific modules.
    • lib: the directory to hold third party modules, like jQuery.
    • common.js: contains the requirejs config, and it will be the build target for the set of common modules.
    • page1.js: used for the data-main for page1.html. Loads the common module, then loads app/main1, the main module for page 1.
    • page2.js: used for the data-main for page2.html. Loads the common module, then loads app/main2, the main module for page 2.

common.js holds the configuration and I've added a shim for highstock there:

requirejs.config({
    baseUrl: 'js/lib',
    paths: {
        app: '../app'
    },
    shim: {
        "highstock": {
            "exports": "Highcharts",
            "deps": [ "jquery"] 
        },
    } // end Shim Configuration
  } );

I also am using the base build file, with the addition of a line to set common.js as the config file and another to disable minifying.

optimize: "none",
mainConfigFile: '../www/js/common.js',

In apps/main1.js I've added a var HighCharts= require('highstock'); and I then try to use it.

When I run this in the normal build everything works fine. All the dependencies hold and everything loads.

When I attempt to optimize my build, highcharts doesn't receive the jQuery dependency. I think I see why its happening, but I'm not sure how to fix it.

My build creates 3 files, common.js, page1.js, and page2.js.

The relevant parts of the build output:

js/lib/../common.js
----------------
js/lib/../common.js
js/lib/jquery.js
...

js/lib/../page1.js
----------------
js/lib/../page1.js
js/lib/highstock.js
js/app/main1.js
...

My page then references the built page1. When it attempts to load the highstock module it errors out since jQuery has not yet been loaded/isn't accessible.

When I see the built page1 I can see why.

require(['./common'], function (common) {
    require(['app/main1']); //highcharts is in main1 in the non-optimized version
});

define("../page1", function(){});
//a few more defines

(function () { // start highcharts module definition HERE

So instead of being defined in the callback after common (including jQuery) has been loaded, its loaded after making the request, but before the callback executes.

My question is, why is this happening there instead of inside the callback (which is where it is loaded in the non-optimized version). I've tried multiple options in the build.js file and config file and I seem to be missing some key concept or small error.

Sorry for the super long question but I felt all the info was necessary. If more info is needed I can post it, or get rid of something superfluous.

回答1:

Please take look at very simple example which use require js http://jsfiddle.net/wAM3h/

    require({
    paths: {
        jquery: "//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min",
        hchart: [
            "http://code.highcharts.com/highcharts",
            "http://code.highcharts.com/highcharts-more",
            "http://code.highcharts.com/modules/exporting"
        ]
    }
},
['jquery', 'hchart'], function($, hc) {

    window.chart = new Highcharts.Chart(options);
    });


回答2:

Not sure you're still involved with the project or not:

I see that you've not defined the path to the highcharts library in the code above. I could not see it even in the repo you mentioned.

And, again, highcharts prevents re-declaration of this namespace, so you must use a different name - Hence, you must use a different name while shim-ming it

Note: Libraries like highcharts can be safely used in an amd module without using a shim (unless you need explicit access to the object exported by it).

So, your Config File should look like this:

requirejs.config({
    baseUrl: 'js/lib',
    paths: {
        app: '../app',
        'highstock-custom-name': 'path/to/highcharts.js'
    },
    shim: {
        "highstock-custom-name": {
          ... //as is, although not necessary
        }
    }
});