Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix substitution variation for plugin names and folders #40

Merged
merged 1 commit into from
May 10, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 81 additions & 7 deletions conditional.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,31 @@ define(['module'], function(module) {
return Promise.resolve();
}

/**
* Returns the bundle module name for a string substitution
* @param {string} nameWithConditional The module identifier including the condition
* @param {string} variation A match of the glob pattern
* @return {string} The bundle module name
*/
function getModuleName(nameWithConditional, variation) {
var modName;
var conditionIndex = nameWithConditional.search(conditionalRegEx);

// look for any "/" after the condition
var lastSlashIndex = nameWithConditional.indexOf("/",
nameWithConditional.indexOf("}"));

// substitution of a folder name
if (lastSlashIndex !== -1) {
modName = nameWithConditional.substr(0, conditionIndex) + variation;
}
else {
modName = nameWithConditional.replace(conditionalRegEx, variation);
}

return modName;
}

loader.normalize = function(name, parentName, parentAddress, pluginNormalize) {
var loader = this;

Expand Down Expand Up @@ -71,8 +96,51 @@ define(['module'], function(module) {

var handleConditionalBuild = function() {};

/**
* Adds bundles needed to load conditional modules in production
*
* Conditional modules are loaded dynamically, these modules are
* not part of the dependency graph and steal-tools has to create
* individual bundles for each of them.
*
* ** The boolean syntax **
*
* After removing the condition from the module identifier, the
* result is the identifier of the module that could be loaded
* during runtime, e.g:
*
* With an indentifier like: `es5-shim#?conditions.needs-es5shim`,
* removing everything after the condition gives us back `es5-shim`
* which is then configured to be made its own bundle by steal-tools.
*
* ** The substitution syntax **
*
* This one is more involved, since there is no way statically to
* figure out all of the possible string substitution value. The
* following algorithm is used to detect them:
*
* 1) The condition is replaced by a placeholder in the module
* identifier; e.g: `jquery/#{browser.grade}` is turned into
* `jquery/__PLACEHOLDER__`.
*
* 2) The result of step 1 is normalised
*
* 3) The placeholder is replaced by `*` which results in a module
* name that looks like: `app@0.0.1#jquery/*`
*
* 4) The module name from step 3 is run through `locate` which
* returns the address where the variations are located.
*
* 5) The address is then turned into a glob pattern and used to
* match the files that could be loaded
*
* 6) The process is then reverted; the modules addresses are turned
* into module names which will be set to `loader.bundle` so
* bundles are created for each of them.
*/
//!steal-remove-start
handleConditionalBuild = function() {
var PLACEHOLDER = "__PLACEHOLDER__";
var setBundlesPromise = Promise.resolve();

// make sure loader.bundle is an array
Expand All @@ -85,7 +153,7 @@ define(['module'], function(module) {

// remove the conditional and the trailing slash
var nameWithoutConditional = name
.replace(conditionalRegEx, "")
.replace(conditionalRegEx, PLACEHOLDER)
.replace(/\/+$/, "");

setBundlesPromise = getGlob()
Expand All @@ -105,16 +173,19 @@ define(['module'], function(module) {
parentName, parentAddress, pluginNormalize);
})
.then(function(normalized) {
return loader.locate({ name: normalized + "/*", metadata: {} });
return loader.locate({
metadata: {},
name: normalized.replace(PLACEHOLDER, "*")
});
})
.then(function(address) {
var path = address.replace("file:", "");
var parts = path.split("/");
var pattern = parts.pop();
var cwd = path.substr(0, path.indexOf("*"));
var pattern = path.substring(path.indexOf("*"));

return new Promise(function(resolve, reject) {
var options = {
cwd: parts.join("/"),
cwd: cwd,
dot: true, nobrace: true, noglobstar: true,
noext: true, nodir: true
};
Expand Down Expand Up @@ -162,8 +233,11 @@ define(['module'], function(module) {
* for each variation when the app is built.
*/
for (var i = 0; i < variations.length; i += 1) {
var variation = variations[i].replace(".js", "");
var modName = nameWithConditional.replace(conditionalRegEx, variation);
var variation = variations[i];

// remove the extension
variation = variation.substr(0, variation.lastIndexOf("."));
var modName = getModuleName(nameWithConditional, variation);

var promise = loader.normalize.call(loader, modName,
parentName, parentAddress, pluginNormalize);
Expand Down