diff --git a/lib/build/slim.js b/lib/build/slim.js index 9dc7ba0f..5b7e2b28 100644 --- a/lib/build/slim.js +++ b/lib/build/slim.js @@ -17,10 +17,10 @@ var addModuleIds = require("../stream/add_module_ids"); var addBundleIds = require("../stream/add_bundle_ids"); var filterGraph = require("../stream/filter_slim_graph"); var addPluginNames = require("../stream/add_plugin_names"); +var addAtStealShim = require("../stream/add_steal_shim"); var addAtLoaderShim = require("../stream/add_loader_shim"); var cloneBuildData = require("../stream/clone_build_data"); var loadNodeBuilder = require("../stream/load_node_builder"); -var checkSlimSupport = require("../stream/check_slim_support"); var convertSlimConfig = require("../stream/convert_slim_config"); var adjustBundlesPath = require("../stream/adjust_bundles_path"); var write = require("../bundle/write_bundles").createWriteStream; @@ -60,7 +60,7 @@ module.exports = function(cfg, opts) { graph(config, options), buildType("optimize"), filterGraph(), - checkSlimSupport(), + addAtStealShim(), addAtLoaderShim(), addModuleIds(), convertSlimConfig(), diff --git a/lib/slim/checks/steal.js b/lib/slim/checks/steal.js deleted file mode 100644 index a0294acf..00000000 --- a/lib/slim/checks/steal.js +++ /dev/null @@ -1,36 +0,0 @@ -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/stream/add_steal_shim.js b/lib/stream/add_steal_shim.js new file mode 100644 index 00000000..c7b18883 --- /dev/null +++ b/lib/stream/add_steal_shim.js @@ -0,0 +1,103 @@ +var colors = require("colors"); +var through = require("through2"); +var keys = require("lodash/keys"); +var omit = require("lodash/omit"); +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 "@steal" shim + * @param {Object} data - The slim stream data object + * @return {Object} The mutated stream object + */ +function addAtLoaderShim(data) { + var graph = omit(data.graph, data.loader.configMain); + + if (includesAtSteal(graph)) { + console.log( + colors.yellow( + `Warning: the @steal module is not fully supported in optimized builds` + ) + ); + data.graph["@steal"] = makeShimNode(data.loader.main); + } + + return data; +} + +/** + * Looks for "@steal" in the dependency graph + * @param {Object} graph - The dependency graph + * @return {boolean} true if found, false otherwise + */ +function includesAtSteal(graph) { + var found = false; + + var isAtSteal = function(name) { + return name === "@steal"; + }; + + keys(graph).forEach(function(name) { + var node = graph[name]; + + if (isPluginExcludedFromBuild(node)) { + return; + } + + if (isAtSteal(name)) { + return (found = true); + } + + defaultTo(node.dependencies, []).forEach(function(depName) { + if (isAtSteal(depName)) { + return (found = true); + } + }); + }); + + return found; +} + +/** + * Returns an @steal shim graph node + * @param {string} main - The main module name + * @return {Object} The faux "@steal" graph node + */ +function makeShimNode(main) { + return { + bundles: [main], + dependencies: ["@loader"], + deps: ["@loader"], + load: { + address: "", + metadata: { + format: "amd", + deps: ["@loader"], + dependencies: ["@loader"] + }, + name: "@steal", + source: ` + define("@steal", ["@loader"], function(atLoader) { + var steal = {}; + + steal.loader = atLoader; + steal.done = function() { + return Promise.resolve(); + }; + + return steal; + }); + ` + } + }; +} diff --git a/test/slim/at_steal/index.html b/test/slim/at_steal/index.html new file mode 100644 index 00000000..e92fe852 --- /dev/null +++ b/test/slim/at_steal/index.html @@ -0,0 +1,10 @@ + + +
+ +