From dd89738d46f5c5bea1237e53c9e29eed199960d6 Mon Sep 17 00:00:00 2001 From: Manuel Mujica Date: Mon, 10 Jul 2017 11:56:52 -0600 Subject: [PATCH 1/2] Add partial support for @loader module Closes #721 --- lib/build/slim.js | 2 + lib/graph/make_graph.js | 16 ++-- lib/graph/make_graph_with_bundles.js | 10 ++- lib/node/is_plugin_excluded.js | 10 +++ lib/node/make_node.js | 2 +- lib/slim/checks/production_env_config.js | 17 ---- lib/slim/checks/steal.js | 36 ++++++++ lib/slim/checks/steal_and_loader.js | 47 ---------- lib/stream/add_loader_shim.js | 106 +++++++++++++++++++++++ lib/stream/check_slim_support.js | 6 +- lib/trace.js | 8 ++ test/slim/at_loader/index.html | 10 +++ test/slim/at_loader/main.js | 5 ++ test/slim/at_loader/stealconfig.js | 11 +++ test/slim/config/foo.js | 0 test/slim/config/main.js | 3 - test/slim/config/stealconfig.js | 11 --- test/slim/progressive/baz-size.snap | 2 +- test/slim_build_test.js | 49 ++++++----- test/slim_support_checks_test.js | 83 ++---------------- 20 files changed, 241 insertions(+), 193 deletions(-) create mode 100644 lib/node/is_plugin_excluded.js delete mode 100644 lib/slim/checks/production_env_config.js create mode 100644 lib/slim/checks/steal.js delete mode 100644 lib/slim/checks/steal_and_loader.js create mode 100644 lib/stream/add_loader_shim.js create mode 100644 test/slim/at_loader/index.html create mode 100644 test/slim/at_loader/main.js create mode 100644 test/slim/at_loader/stealconfig.js delete mode 100644 test/slim/config/foo.js delete mode 100644 test/slim/config/main.js delete mode 100644 test/slim/config/stealconfig.js diff --git a/lib/build/slim.js b/lib/build/slim.js index 1c7e2b27..58e09c62 100644 --- a/lib/build/slim.js +++ b/lib/build/slim.js @@ -13,6 +13,7 @@ var streams = { addBundleIds: require("../stream/add_bundle_ids"), filterGraph: require("../stream/filter_slim_graph"), addPluginNames: require("../stream/add_plugin_names"), + addAtLoaderShim: require("../stream/add_loader_shim"), checkSlimSupport: require("../stream/check_slim_support"), write: require("../bundle/write_bundles").createWriteStream, writeBundlesManifest: require("../stream/write_bundle_manifest"), @@ -39,6 +40,7 @@ module.exports = function(config, options) { streams.graph(config, buildOptions), streams.filterGraph(), streams.checkSlimSupport(), + streams.addAtLoaderShim(), streams.addModuleIds(), streams.loadOptimizedPlugins(), streams.transpile({ outputFormat: "slim" }), diff --git a/lib/graph/make_graph.js b/lib/graph/make_graph.js index 4185735f..2b808515 100644 --- a/lib/graph/make_graph.js +++ b/lib/graph/make_graph.js @@ -1,10 +1,12 @@ var winston = require('winston'); var trace = require("../trace"); var steal = require("steal"); -var _ = require("lodash"); -var clone = _.cloneDeep; +var omit = require("lodash/omit"); +var assign = require("lodash/assign"); +var clone = require("lodash/cloneDeep"); var addParseAMD = require("steal-parse-amd"); var makeDeferred = require("../make-deferred"); +var isUndefined = require("lodash/isUndefined"); var makePredefinedPluginDependencies = require('./make_predefined_plugin_dependencies'); var formatMap = { @@ -27,7 +29,7 @@ module.exports = function(config, options){ addParseAMD( localSteal.System ); localSteal.System.config({ env: "build-development" }); - localSteal.System.config(_.omit(config, ["meta"])); + localSteal.System.config(omit(config, ["meta"])); if(options.localStealConfig) { localSteal.System.config(options.localStealConfig); } @@ -42,7 +44,7 @@ module.exports = function(config, options){ // Special types don't work that write to AMD if we add parseAMD to this. //addParseAMD( buildSteal.System ); // It should be confured exactly like `localSteal` - buildSteal.System.config(_.omit(config, ["meta"])); + buildSteal.System.config(omit(config, ["meta"])); buildSteal.System.systemName = (buildSteal.System.systemName ||"")+ "-build"; if(options.system) { @@ -110,8 +112,8 @@ module.exports = function(config, options){ // set config one more time on startup. This is to make sure the final values // are these values. - var localConfig = _.omit(config, ["config","systemName"]); - _.assign(localConfig, ignoredMetas(config.meta, buildSteal.System.meta)); + var localConfig = omit(config, ["config","systemName"]); + assign(localConfig, ignoredMetas(config.meta, buildSteal.System.meta)); var appPromise = localSteal.startup(localConfig); startupCalledDfd.resolve(); @@ -119,7 +121,7 @@ module.exports = function(config, options){ return appPromise.then(function(){ var main = localSteal.System.main; - if (_.isUndefined(main)) { + if (isUndefined(main)) { return Promise.reject( new Error( "Attribute 'main' is required\n" + diff --git a/lib/graph/make_graph_with_bundles.js b/lib/graph/make_graph_with_bundles.js index 613e2351..d877d98f 100644 --- a/lib/graph/make_graph_with_bundles.js +++ b/lib/graph/make_graph_with_bundles.js @@ -1,5 +1,7 @@ +var clone = require("lodash/clone"); +var assign = require("lodash/assign"); +var includes = require("lodash/includes"); var dependencyGraph = require("./make_graph"); -var _ = require("lodash"); var normalizeBundle = require("../loader/normalize_bundle"); var through = require("through2"); var fs = require("fs-extra"); @@ -52,7 +54,7 @@ function mergeIntoMasterAndAddBundle(opts) { // do not track bundles of entry point modules (a.k.a mains) unless // it is its own bundle. - if (name === bundleName || !_.includes(mains, name)) { + if (name === bundleName || !includes(mains, name)) { addBundle(masterGraph[name], bundleName); } } @@ -90,7 +92,7 @@ var makeBundleGraph = module.exports = function(config, options){ // the names of everything we are going to load var bundleNames = []; - var cfg = _.clone(config, true); + var cfg = clone(config, true); if( Array.isArray(cfg.main) ) { bundleNames = slice.call(cfg.main); cfg.main = bundleNames.shift(); @@ -144,7 +146,7 @@ var makeBundleGraph = module.exports = function(config, options){ } else { var nmains; - var copy = _.assign(_.clone(cfg, true), { main: nextBundle }); + var copy = assign(clone(cfg), { main: nextBundle }); return mainsPromise .then(function(normalised) { diff --git a/lib/node/is_plugin_excluded.js b/lib/node/is_plugin_excluded.js new file mode 100644 index 00000000..281b99ee --- /dev/null +++ b/lib/node/is_plugin_excluded.js @@ -0,0 +1,10 @@ +/** + * Whether the node is a plugin that won't be included in the build + * @param {Object} node - A node from the dependency graph + * @return {boolean} + */ +module.exports = function isPluginExcludedFromBuild(node) { + return Boolean( + node.isPlugin && (!node.value.includeInBuild || node.value.pluginBuilder) + ); +}; diff --git a/lib/node/make_node.js b/lib/node/make_node.js index e464602a..06b150a3 100644 --- a/lib/node/make_node.js +++ b/lib/node/make_node.js @@ -3,7 +3,7 @@ var nodeSource = require("./source"); module.exports = function(name, source, type){ return { load: { - metadata: {format: type || global}, + metadata: {format: type || "global"}, source: source || "", name: name }, diff --git a/lib/slim/checks/production_env_config.js b/lib/slim/checks/production_env_config.js deleted file mode 100644 index 8e2fc308..00000000 --- a/lib/slim/checks/production_env_config.js +++ /dev/null @@ -1,17 +0,0 @@ -var defaultTo = require("lodash/defaultTo"); -var isEmpty = require("lodash/isEmpty"); - -/** - * Checks whether there is "window-production" specific config - * @param {Object} steal - The steal instance on the stream buildResult object - * @throws if "window-production" config is set to steal - */ -module.exports = function checkProductionEnvConfig(steal) { - var envs = defaultTo(steal.config("envs"), {}); - - if (!isEmpty(envs["window-production"])) { - throw new Error( - `Cannot create slim build. "window-production" config is not supported` - ); - } -}; diff --git a/lib/slim/checks/steal.js b/lib/slim/checks/steal.js new file mode 100644 index 00000000..a0294acf --- /dev/null +++ b/lib/slim/checks/steal.js @@ -0,0 +1,36 @@ +var keys = require("lodash/keys"); +var isPluginExcludedFromBuild = require("../../node/is_plugin_excluded"); + +/** + * Checks whether the @steal node is in the graph + * @param {string} configMain - The configMain module name + * @throws if @steal is found in the graph + */ +module.exports = function(configMain, graph) { + keys(graph).forEach(function(name) { + var node = graph[name]; + + // the configMain node does depend on @steal/@loader but it won't be + // included in the slim build, we can skip it. Same for plugins that + // will be only be used during the build process. + if (name === configMain || isPluginExcludedFromBuild(node)) { + return; + } + + isAtSteal(name); + node.dependencies.forEach(isAtSteal); + }); +}; + +/** + * Checks whether the module name is @steal + * @param {string} name - The module name to be checked + * @throws if the name is @steal + */ +function isAtSteal(name) { + if (name === "@steal") { + throw new Error( + `Cannot create slim build. "@steal" module is not supported` + ); + } +} diff --git a/lib/slim/checks/steal_and_loader.js b/lib/slim/checks/steal_and_loader.js deleted file mode 100644 index ab1869ce..00000000 --- a/lib/slim/checks/steal_and_loader.js +++ /dev/null @@ -1,47 +0,0 @@ -var keys = require("lodash/keys"); -var includes = require("lodash/includes"); - -/** - * Checks whether @steal or @loader nodes are in the graph - * @param {string} configMain - The configMain module name - * @throws if @steal or @loader are found in the graph - */ -module.exports = function(configMain, graph) { - keys(graph).forEach(function(name) { - var node = graph[name]; - - // the configMain node does depend on @steal/@loader but it won't be - // included in the slim build, we can skip it. Same for plugins that - // will be only be used during the build process. - if (name === configMain || isPluginExcludedFromBuild(node)) { - return; - } - - isLoaderOrSteal(name); - node.dependencies.forEach(isLoaderOrSteal); - }); -}; - -/** - * Whether the node is a plugin that won't be included in the build - * @param {Object} node - A node from the dependency graph - * @return {boolean} - */ -function isPluginExcludedFromBuild(node) { - return Boolean( - node.isPlugin && (!node.value.includeInBuild || node.value.pluginBuilder) - ); -} - -/** - * Checks whether the module name is either @loader or @steal - * @param {string} name - The module name to be checked - * @throws if the name is either @loader or @steal - */ -function isLoaderOrSteal(name) { - if (includes(["@loader", "@steal"], name)) { - throw new Error( - `Cannot create slim build. "${name}" module is not supported` - ); - } -} diff --git a/lib/stream/add_loader_shim.js b/lib/stream/add_loader_shim.js new file mode 100644 index 00000000..fbc0f2c2 --- /dev/null +++ b/lib/stream/add_loader_shim.js @@ -0,0 +1,106 @@ +var colors = require("colors"); +var through = require("through2"); +var keys = require("lodash/keys"); +var omit = require("lodash/omit"); +var assign = require("lodash/assign"); +var clone = require("lodash/cloneDeep"); +var defaultTo = require("lodash/defaultTo"); +var isPluginExcludedFromBuild = require("../node/is_plugin_excluded"); + +module.exports = function() { + return through.obj(function(data, enc, next) { + try { + next(null, addAtLoaderShim(data)); + } catch (err) { + next(err); + } + }); +}; + +/** + * Adds a node to the graph with an "@loader" shim + * The "@loader" shim contains the loader configuration properties + * @param {Object} data - The slim stream data object + * @return {Object} The mutated stream object + */ +function addAtLoaderShim(data) { + if (includesAtLoader(omit(data.graph, data.loader.configMain))) { + console.log( + colors.yellow( + `Warning: the @loader module is not fully supported in optimized builds` + ) + ); + + var config = clone( + omit(data.loader.__loaderConfig, ["paths", "stealPath"]) + ); + + // make sure the "window-production" config overrides previous values + assign(config, defaultTo(config.envs, {})["window-production"]); + + data.graph["@loader"] = makeShimNode(data.loader.main, config); + } + + return data; +} + +/** + * Looks for "@loader" in the dependency graph + * @param {Object} graph - The dependency graph + * @return {boolean} true if found, false otherwise + */ +function includesAtLoader(graph) { + var found = false; + + var isAtLoader = function(name) { + return name === "@loader"; + }; + + keys(graph).forEach(function(name) { + var node = graph[name]; + + if (isPluginExcludedFromBuild(node)) { + return; + } + + if (isAtLoader(name)) { + return (found = true); + } + + defaultTo(node.dependencies, []).forEach(function(depName) { + if (isAtLoader(depName)) { + return (found = true); + } + }); + }); + + return found; +} + +/** + * Returns an @loader node with the source code returning the config object + * @param {string} main - The main module name + * @param {Object} config - The config object exposed by "@loader" + * @return {Object} The faux "@loader" graph node + */ +function makeShimNode(main, config) { + return { + bundles: [main], + dependencies: [], + deps: [], + load: { + address: "", + metadata: { + deps: [], + format: "amd", + dependencies: [] + }, + name: "@loader", + source: ` + define("@loader", function() { + return ${JSON.stringify(config)}; + }); + ` + } + }; +} diff --git a/lib/stream/check_slim_support.js b/lib/stream/check_slim_support.js index 833c40b2..e5c74a49 100644 --- a/lib/stream/check_slim_support.js +++ b/lib/stream/check_slim_support.js @@ -1,9 +1,8 @@ var through = require("through2"); // individual checks/rules for slim builds -var checkStealAndLoader = require("../slim/checks/steal_and_loader"); +var checkAtSteal = require("../slim/checks/steal"); var checkStealConditional = require("../slim/checks/steal_conditional"); -var checkProductionEnvConfig = require("../slim/checks/production_env_config"); module.exports = function() { return through.obj(function(data, enc, done) { @@ -18,9 +17,8 @@ module.exports = function() { function checkSupport(data) { var configMain = data.loader.configMain || "package.json!npm"; - checkStealAndLoader(configMain, data.graph); + checkAtSteal(configMain, data.graph); checkStealConditional(data.graph[configMain]); - checkProductionEnvConfig(data.steal); return data; } diff --git a/lib/trace.js b/lib/trace.js index 782f4a5c..9bba3797 100644 --- a/lib/trace.js +++ b/lib/trace.js @@ -6,6 +6,14 @@ var trace = function(System, BuildSystem, startupCalledPromise, onFulfilled){ System.pluginLoader = BuildSystem; BuildSystem.localLoader = System; + // override System.config to keep track of the configuration properties set + var systemConfig = System.config; + System.config = function(cfg) { + System.__loaderConfig = System.__loaderConfig || {}; + assign(System.__loaderConfig, cfg); + systemConfig.apply(System, arguments); + }; + // The BuildSystem loader will execute modules, but wait for the value to come through var buildInstantiate = BuildSystem.instantiate; BuildSystem.instantiate = function(load){ diff --git a/test/slim/at_loader/index.html b/test/slim/at_loader/index.html new file mode 100644 index 00000000..e92fe852 --- /dev/null +++ b/test/slim/at_loader/index.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/test/slim/at_loader/main.js b/test/slim/at_loader/main.js new file mode 100644 index 00000000..2ffcc291 --- /dev/null +++ b/test/slim/at_loader/main.js @@ -0,0 +1,5 @@ +var loader = require("@loader"); + +window.serviceBaseUrl = loader.serviceBaseURL; +window.stealPath = loader.stealPath; +window.paths = loader.paths; diff --git a/test/slim/at_loader/stealconfig.js b/test/slim/at_loader/stealconfig.js new file mode 100644 index 00000000..5277578b --- /dev/null +++ b/test/slim/at_loader/stealconfig.js @@ -0,0 +1,11 @@ +steal.config({ + main: "main", + paths: { + "foo": "bar" + }, + envs: { + "window-production": { + serviceBaseURL: "/api/production" + } + } +}); diff --git a/test/slim/config/foo.js b/test/slim/config/foo.js deleted file mode 100644 index e69de29b..00000000 diff --git a/test/slim/config/main.js b/test/slim/config/main.js deleted file mode 100644 index 12830456..00000000 --- a/test/slim/config/main.js +++ /dev/null @@ -1,3 +0,0 @@ -"format cjs"; - -console.log("main"); diff --git a/test/slim/config/stealconfig.js b/test/slim/config/stealconfig.js deleted file mode 100644 index 72109b84..00000000 --- a/test/slim/config/stealconfig.js +++ /dev/null @@ -1,11 +0,0 @@ -steal.config({ - main: "main", - - envs: { - "window-production": { - paths: { - main: "foo" - } - } - } -}); diff --git a/test/slim/progressive/baz-size.snap b/test/slim/progressive/baz-size.snap index 953af214..f5633723 100644 --- a/test/slim/progressive/baz-size.snap +++ b/test/slim/progressive/baz-size.snap @@ -1 +1 @@ -module.exports = 158; \ No newline at end of file +module.exports = 157; \ No newline at end of file diff --git a/test/slim_build_test.js b/test/slim_build_test.js index 81e3d092..16ebf497 100644 --- a/test/slim_build_test.js +++ b/test/slim_build_test.js @@ -15,6 +15,9 @@ describe("slim builds", function() { var open = testHelpers.popen; var find = testHelpers.pfind; + // allow `find` to reject before mocha timeout kicks in + this.timeout(3000); + it("basics + cjs source", function() { var base = path.join(__dirname, "slim", "basics"); var config = { config: path.join(base, "stealconfig.js") }; @@ -210,23 +213,6 @@ describe("slim builds", function() { }); }); - it("errors out with apps using window-production config", function(done) { - var base = path.join(__dirname, "slim", "config"); - var config = { config: path.join(base, "stealconfig.js") }; - - rmdir(path.join(base, "dist")) - .then(function() { - return optimize(config, { minify: false, quiet: true }); - }) - .then(function() { - done(new Error("should not build the app")); - }) - .catch(function(err) { - assert(/"window-production" config is not supported/.test(err)); - done(); - }); - }); - it("loader code can be put in its own bundle", function() { this.timeout(1000); @@ -422,9 +408,6 @@ describe("slim builds", function() { var base = path.join(__dirname, "slim", "esm_named_imports"); var config = { config: path.join(base, "stealconfig.js") }; - // allow `find` to reject before mocha timeout kicks in - this.timeout(3000); - return rmdir(path.join(base, "dist")) .then(function() { return optimize(config, { minify: false, quiet: true }); @@ -442,4 +425,30 @@ describe("slim builds", function() { data[0](); // close(); }); }); + + it("has partial support for @loader usage", function() { + var base = path.join(__dirname, "slim", "at_loader"); + var config = { config: path.join(base, "stealconfig.js") }; + + return rmdir(path.join(base, "dist")) + .then(function() { + return optimize(config, { minify: false, quiet: true }); + }) + .then(function() { + return open( + path.join("test", "slim", "at_loader", "index.html") + ); + }) + .then(function(args) { + return Promise.all([args.close, find(args.browser, "window")]); + }) + .then(function(data) { + var w = data[1]; + var close = data[0]; + assert.ok(w.paths == null, "should be filtered out"); + assert.ok(w.stealPath == null, "should be filtered out"); + assert.equal(w.serviceBaseUrl, "/api/production", "should work"); + close(); + }); + }); }); diff --git a/test/slim_support_checks_test.js b/test/slim_support_checks_test.js index f4305fad..741cded1 100644 --- a/test/slim_support_checks_test.js +++ b/test/slim_support_checks_test.js @@ -1,86 +1,13 @@ var assert = require("assert"); describe("slim support checks", function() { - describe("checkProductionEnvConfig", function() { - var checkProductionConfig = require("../lib/slim/checks/production_env_config"); - - it("throws if 'window-production' config found", function() { - assert.throws( - function() { - checkProductionConfig({ - config: function(prop) { - if (prop === "envs") { - return { - "window-production": { - paths: { - foo: "bar" - } - } - }; - } - } - }); - }, - function(err) { - return /"window-production" config is not supported/.test( - err.message - ); - } - ); - }); - - it("does not throw if config found but empty", function() { - assert.equal( - checkProductionConfig({ - config: function(prop) { - if (prop === "envs") { - return { - "window-production": {} - }; - } - } - }), - undefined - ); - }); - - it("does not throw if config missing at all", function() { - assert.equal( - checkProductionConfig({ - config: function(prop) { - if (prop === "envs") { - return; - } - } - }), - undefined - ); - }); - }); - - describe("checkStealAndLoader", function() { - var checkStealAndLoader = require("../lib/slim/checks/steal_and_loader"); - - it("throws if @loader is in the graph", function() { - assert.throws( - function() { - checkStealAndLoader("stealconfig.js", { - main: { - dependencies: ["@loader"] - }, - "stealconfig.js": {} - }); - }, - function(err) { - return /"@loader" module is not supported/.test(err.message); - } - ); - }); + describe("checkSteal", function() { + var checkSteal = require("../lib/slim/checks/steal"); it("throws if @steal is in the graph", function() { assert.throws( function() { - checkStealAndLoader("stealconfig.js", { + checkSteal("stealconfig.js", { main: { dependencies: ["@steal"] }, @@ -93,8 +20,8 @@ describe("slim support checks", function() { ); }); - it("does not throw if @loader/@steal missing from graph", function() { - assert.equal(checkStealAndLoader({}), undefined); + it("does not throw if @steal missing from graph", function() { + assert.equal(checkSteal({}), undefined); }); }); From af722c0e70d25ef06d5367cbcb238dc018653ae4 Mon Sep 17 00:00:00 2001 From: Manuel Mujica Date: Mon, 10 Jul 2017 16:29:35 -0600 Subject: [PATCH 2/2] Use non-normalize bundles names in slim config Closes #759 --- doc/guides/optimized_builds.md | 26 ++++++---------------- lib/node/make_slim_config_node.js | 6 +++--- lib/stream/slim.js | 36 ++++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/doc/guides/optimized_builds.md b/doc/guides/optimized_builds.md index 7650cd8e..db2b403e 100644 --- a/doc/guides/optimized_builds.md +++ b/doc/guides/optimized_builds.md @@ -8,7 +8,7 @@ as the default way of creating a build of a module and all of its dependencies; Unlike regular [builds](steal-tools.build), optimized builds don't need to load or bundle StealJS at all; a thin wrapper is added instead to the main bundle so the browser can load and execute the modules correctly. -> The **optimize** API is still a work in progress, some StealJS features are still not supported. +> The **optimize** API is a work in progress, some StealJS features are not supported yet. In this guide, we'll go through the steps required to create and use an optimized build. We'll be using the `myhub` application created in the [Progressive Loading](./StealJS.guides.progressive_loading) guide. @@ -38,7 +38,7 @@ Run the following command: ### Install dependencies As mentioned before, the **optimize** API is still in its early days, for that reason -we need to use the pre-release packages of `steal-tools` and `steal-css`. +we need to use some pre-release packages. Edit your `package.json` like: @@ -46,28 +46,12 @@ Edit your `package.json` like: "devDependencies": { ... "steal-css": "^1.3.0-pre.0", - "steal-tools": "^1.4.0-pre.1" + "steal-tools": "^1.4.0" } ``` Run `npm install` to install all the application dependencies. -### Update dynamic module identifiers - -One limitation of the optimized loader is that unlike StealJS's loader it does not normalize -module identifiers on runtime. For static imports that's not a problem, but it's an issue for -dynamic imports (through `steal.import`), a workaround for that is to use the full module -name. - -Edit the dynamic import in `myhub.js` to: - -```js -steal.import(`myhub@1.0.0#${hash}/${hash}`).then(function(moduleOrPlugin) { -``` - -where "myhub" is the package name, the number after the "@" symbol is the package version and -the rest of the string after the "#" is the actual module identifier. - ### Make an optimize build script Currently, there is no CLI option to use the `stealTools.optimize` function, so a NodeJS script is required. @@ -90,6 +74,8 @@ Run the build script with: Now, start an http server by running `npm start` and open `http://127.0.0.1:8080/` in a web browser. You should see myhub's home page. +> One limitation of the optimized loader is that unlike StealJS' loader it does not normalize module identifiers on runtime. For static imports that's not a problem, but it's an issue for dynamic imports (through steal.import), the module identifier needs to match the name set in [config.bundle]. + ### Performance comparison For most application builds where StealJS is not included in each of the main bundles, optimized builds will @@ -119,7 +105,7 @@ Edit `index.html` to asynchronously load the bundles of the other two pages like ```html
Hello World.
- + diff --git a/lib/node/make_slim_config_node.js b/lib/node/make_slim_config_node.js index e5697e99..98285594 100644 --- a/lib/node/make_slim_config_node.js +++ b/lib/node/make_slim_config_node.js @@ -55,9 +55,9 @@ module.exports = function(options) { }); }); - options.progressiveBundles.forEach(function(bundleName) { - var node = options.graph[bundleName]; - slimMapConfig[bundleName] = node.load.uniqueId; + // [{ id : number, name : string }] + options.progressiveBundles.forEach(function(bundle) { + slimMapConfig[bundle.name] = bundle.id; }); var configSource = ` diff --git a/lib/stream/slim.js b/lib/stream/slim.js index 523ad542..4369f0fc 100644 --- a/lib/stream/slim.js +++ b/lib/stream/slim.js @@ -11,6 +11,11 @@ module.exports = function() { }); }; +/** + * Turns the bundles into their slim version (mutates stream data) + * @param {Object} data - The slim stream data object + * @return {Object} The mutated data + */ function doSlimGrap(data) { data.bundles = slimGraph({ graph: data.graph, @@ -18,16 +23,41 @@ function doSlimGrap(data) { baseUrl: data.loader.baseURL, mainModuleId: getMainModuleId(data), splitLoader: data.options.splitLoader, - progressiveBundles: data.loader.bundle, bundlesPath: data.configuration.bundlesPath, - configMain: data.loader.configMain || "package.json!npm" + configMain: data.loader.configMain || "package.json!npm", + progressiveBundles: getProgressiveBundles(data.loader, data.graph) }); return data; } - +/** + * Return the main module slim id + * @param {Object} data - The slim stream data object + * @return {number} The slim id + */ function getMainModuleId(data) { var mainName = data.mains[0]; return data.graph[mainName].load.uniqueId; } + +/** + * An array of module names/ids to be progressively loaded + * @param {Object} loader - The loader instance + * @param {Object} graph - The dependency graph + * @return {Array.} List of module names and ids + */ +function getProgressiveBundles(loader, graph) { + var config = loader.__loaderConfig || {}; + var configBundle = config.bundle || []; + + return loader.bundle.map(function(name, index) { + return { + id: graph[name].load.uniqueId, + + // use the raw module identifiers so the user won't have to use + // the full normalized names when importing a module dynamically + name: configBundle[index] || name + }; + }); +}