Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixes #241, allows for a plugin to have an onLayerEnd hook

The diff for build.js is larger than it really is because of jslint changes for a more recent jslint. I meant to commit those separately but forgot.
  • Loading branch information...
commit 1997efc398c930facc17709e5c9e6c220f68c3ec 1 parent f0dac2a
@jrburke authored
View
2  .gitignore
@@ -45,6 +45,8 @@ build/tests/lib/pluginBuilder/main-built.js
build/tests/lib/pluginShimDep/main-built.js
build/tests/lib/plugins/main-built.js
build/tests/lib/plugins/main-builtPluginFirst.js
+build/tests/lib/plugins/onLayerEnd/built
+build/tests/lib/plugins/onLayerEnd/main-built.js
build/tests/lib/plugins/optimizeAllPluginResources/www-built
build/tests/lib/pragmas/override/built
build/tests/lib/pristineSrc/built
View
113 build/jslib/build.js
@@ -10,8 +10,7 @@
define([ 'lang', 'logger', 'env!env/file', 'parse', 'optimize', 'pragma',
'transform', 'env!env/load', 'requirePatch', 'env!env/quit',
- 'commonJs'],
-function (lang, logger, file, parse, optimize, pragma,
+ 'commonJs'], function (lang, logger, file, parse, optimize, pragma,
transform, load, requirePatch, quit,
commonJs) {
'use strict';
@@ -20,21 +19,21 @@ function (lang, logger, file, parse, optimize, pragma,
endsWithSemiColonRegExp = /;\s*$/;
buildBaseConfig = {
- appDir: "",
- pragmas: {},
- paths: {},
- optimize: "uglify",
- optimizeCss: "standard.keepLines",
- inlineText: true,
- isBuild: true,
- optimizeAllPluginResources: false,
- findNestedDependencies: false,
- preserveLicenseComments: true,
- //By default, all files/directories are copied, unless
- //they match this regexp, by default just excludes .folders
- dirExclusionRegExp: file.dirExclusionRegExp,
- _buildPathToModuleIndex: {}
- };
+ appDir: "",
+ pragmas: {},
+ paths: {},
+ optimize: "uglify",
+ optimizeCss: "standard.keepLines",
+ inlineText: true,
+ isBuild: true,
+ optimizeAllPluginResources: false,
+ findNestedDependencies: false,
+ preserveLicenseComments: true,
+ //By default, all files/directories are copied, unless
+ //they match this regexp, by default just excludes .folders
+ dirExclusionRegExp: file.dirExclusionRegExp,
+ _buildPathToModuleIndex: {}
+ };
/**
* Some JS may not be valid if concatenated with other JS, in particular
@@ -89,10 +88,10 @@ function (lang, logger, file, parse, optimize, pragma,
* there is a problem completing the build.
*/
build = function (args) {
- var stackRegExp = /( {4}at[^\n]+)\n/,
- standardIndent = ' ',
- buildFile, cmdConfig, errorMsg, errorStack, stackMatch, errorTree,
- i, j, errorMod;
+ var buildFile, cmdConfig, errorMsg, errorStack, stackMatch, errorTree,
+ i, j, errorMod,
+ stackRegExp = /( {4}at[^\n]+)\n/,
+ standardIndent = ' ';
try {
if (!args || lang.isArray(args)) {
@@ -169,14 +168,15 @@ function (lang, logger, file, parse, optimize, pragma,
};
build._run = function (cmdConfig) {
- var buildFileContents = "",
- pluginCollector = {},
- buildPaths, fileName, fileNames,
+ var buildPaths, fileName, fileNames,
prop, paths, i,
baseConfig, config,
modules, builtModule, srcPath, buildContext,
destPath, moduleName, moduleMap, parentModuleMap, context,
- resources, resource, pluginProcessed = {}, plugin, fileContents;
+ resources, resource, plugin, fileContents,
+ pluginProcessed = {},
+ buildFileContents = "",
+ pluginCollector = {};
//Can now run the patches to require.js to allow it to be used for
//build generation. Do it here instead of at the top of the module
@@ -274,7 +274,7 @@ function (lang, logger, file, parse, optimize, pragma,
//as indicated by a true "create" property on the module, and
//it is not a plugin-loaded resource, then throw an error.
if (!file.exists(module._sourcePath) && !module.create &&
- module.name.indexOf('!') === -1) {
+ module.name.indexOf('!') === -1) {
throw new Error("ERROR: module path does not exist: " +
module._sourcePath + " for module named: " + module.name +
". Path is relative to: " + file.absPath('.'));
@@ -400,8 +400,8 @@ function (lang, logger, file, parse, optimize, pragma,
if (config.removeCombined) {
module.layer.buildFilePaths.forEach(function (path) {
if (file.exists(path) && !modules.some(function (mod) {
- return mod._buildPath === path;
- })) {
+ return mod._buildPath === path;
+ })) {
file.deleteFile(path);
}
});
@@ -727,8 +727,8 @@ function (lang, logger, file, parse, optimize, pragma,
//allow a one-level-deep mixing of it.
value = source[prop];
if (typeof value === 'object' && value &&
- !lang.isArray(value) && !lang.isFunction(value) &&
- !lang.isRegExp(value)) {
+ !lang.isArray(value) && !lang.isFunction(value) &&
+ !lang.isRegExp(value)) {
target[prop] = lang.mixin({}, target[prop], value, true);
} else {
target[prop] = value;
@@ -1144,10 +1144,10 @@ function (lang, logger, file, parse, optimize, pragma,
if (errIds.length || failedPluginIds.length) {
if (failedPluginIds.length) {
errMessage += 'Loader plugin' +
- (failedPluginIds.length === 1 ? '' : 's') +
- ' did not call ' +
- 'the load callback in the build: ' +
- failedPluginIds.join(', ') + '\n';
+ (failedPluginIds.length === 1 ? '' : 's') +
+ ' did not call ' +
+ 'the load callback in the build: ' +
+ failedPluginIds.join(', ') + '\n';
}
errMessage += 'Module loading did not complete for: ' + errIds.join(', ');
@@ -1191,14 +1191,16 @@ function (lang, logger, file, parse, optimize, pragma,
lang.mixin(config, module.override, true);
}
- var buildFileContents = "",
+ var path, reqIndex, fileContents, currContents,
+ i, moduleName, shim, packageConfig,
+ parts, builder, writeApi,
+ context = layer.context,
+ buildFileContents = "",
namespace = config.namespace || '',
namespaceWithDot = namespace ? namespace + '.' : '',
stubModulesByName = (config.stubModules && config.stubModules._byName) || {},
- context = layer.context,
- path, reqIndex, fileContents, currContents,
- i, moduleName, shim, packageConfig,
- parts, builder, writeApi;
+ onLayerEnds = [],
+ onLayerEndAdded = {};
//Start build output for the module.
buildFileContents += "\n" +
@@ -1233,6 +1235,11 @@ function (lang, logger, file, parse, optimize, pragma,
parts = context.makeModuleMap(moduleName);
builder = parts.prefix && context.defined[parts.prefix];
if (builder) {
+ if (builder.onLayerEnd && !onLayerEndAdded[parts.prefix]) {
+ onLayerEnds.push(builder);
+ onLayerEndAdded[parts.prefix] = true;
+ }
+
if (builder.write) {
writeApi = function (input) {
fileContents += "\n" + addSemiColon(input);
@@ -1242,10 +1249,9 @@ function (lang, logger, file, parse, optimize, pragma,
};
writeApi.asModule = function (moduleName, input) {
fileContents += "\n" +
- addSemiColon(
- build.toTransport(namespace, moduleName, path, input, layer, {
- useSourceUrl: layer.context.config.useSourceUrl
- }));
+ addSemiColon(build.toTransport(namespace, moduleName, path, input, layer, {
+ useSourceUrl: layer.context.config.useSourceUrl
+ }));
if (config.onBuildWrite) {
fileContents = config.onBuildWrite(moduleName, path, fileContents);
}
@@ -1281,8 +1287,8 @@ function (lang, logger, file, parse, optimize, pragma,
}
currContents = build.toTransport(namespace, moduleName, path, currContents, layer, {
- useSourceUrl: config.useSourceUrl
- });
+ useSourceUrl: config.useSourceUrl
+ });
if (packageConfig) {
currContents = addSemiColon(currContents) + '\n';
@@ -1319,6 +1325,23 @@ function (lang, logger, file, parse, optimize, pragma,
}
}
+ if (onLayerEnds.length) {
+ onLayerEnds.forEach(function (builder) {
+ var path;
+ if (typeof module.out === 'string') {
+ path = module.out;
+ } else if (typeof module._buildPath === 'string') {
+ path = module._buildPath;
+ }
+ builder.onLayerEnd(function (input) {
+ fileContents += "\n" + addSemiColon(input);
+ }, {
+ name: module.name,
+ path: path
+ });
+ });
+ }
+
//Add a require at the end to kick start module execution, if that
//was desired. Usually this is only specified when using small shim
//loaders like almond.
View
39 build/tests/builds.js
@@ -1561,4 +1561,43 @@ define(['build', 'env!env/file'], function (build, file) {
);
doh.run();
+ //Test onLayerEnd for loader plugins
+ //https://github.com/jrburke/r.js/pull/241
+ doh.register("pluginsOnLayerEnd",
+ [
+ function pluginsOnLayerEnd(t) {
+ file.deleteFile("lib/plugins/onLayerEnd/main-built.js");
+
+ build(["lib/plugins/onLayerEnd/build.js"]);
+
+ t.is(nol(c("lib/plugins/onLayerEnd/expected.js")),
+ nol(c("lib/plugins/onLayerEnd/main-built.js")));
+
+ require._buildReset();
+ }
+
+ ]
+ );
+ doh.run();
+
+ doh.register("pluginsOnLayerEndMulti",
+ [
+ function pluginsOnLayerEndMulti(t) {
+ file.deleteFile("lib/plugins/onLayerEnd/built");
+
+ build(["lib/plugins/onLayerEnd/buildMulti.js"]);
+
+ t.is(nol(c("lib/plugins/onLayerEnd/expectedMultiMain.js")),
+ nol(c("lib/plugins/onLayerEnd/built/main.js")));
+ t.is(nol(c("lib/plugins/onLayerEnd/expectedMultiSecondary.js")),
+ nol(c("lib/plugins/onLayerEnd/built/secondary.js")));
+
+ require._buildReset();
+ }
+
+ ]
+ );
+ doh.run();
+
+
});
View
6 build/tests/lib/plugins/onLayerEnd/build.js
@@ -0,0 +1,6 @@
+{
+ baseUrl: 'src',
+ name: 'main',
+ out: 'main-built.js',
+ optimize: 'none'
+}
View
13 build/tests/lib/plugins/onLayerEnd/buildMulti.js
@@ -0,0 +1,13 @@
+{
+ baseUrl: 'src',
+ dir: 'built',
+ optimize: 'none',
+ modules: [
+ {
+ name: 'main'
+ },
+ {
+ name: 'secondary'
+ }
+ ]
+}
View
47 build/tests/lib/plugins/onLayerEnd/expected.js
@@ -0,0 +1,47 @@
+
+define('plug',[],function () {
+ var buildMap = {},
+ injectPreamble = true,
+ preamble = "'USE PREAMBLE';";
+
+ return {
+ version: '1',
+ load: function (name, require, onLoad, config) {
+ var converted = name.toUpperCase();
+ buildMap[name] = converted;
+ onLoad(converted);
+ },
+
+ write: function (pluginName, moduleName, write, config) {
+ if (buildMap.hasOwnProperty(moduleName)) {
+ if (injectPreamble) {
+ write(preamble);
+ injectPreamble = false;
+ }
+ var content = buildMap[moduleName];
+ write("define('" + pluginName + "!" + moduleName +
+ "', function () { return '" + content + "';});\n");
+ }
+ },
+
+ onLayerEnd: function (write, data) {
+ injectPreamble = true;
+ write("'USE POSTAMBLE';");
+ }
+ };
+});
+
+'USE PREAMBLE';
+define('plug!foo', function () { return 'FOO';});
+
+define('plug!bar', function () { return 'BAR';});
+
+require(['plug!foo', 'plug!bar'],
+function (foo, bar) {
+ console.log(foo);
+ console.log(bar);
+});
+
+define("main", function(){});
+
+'USE POSTAMBLE';
View
47 build/tests/lib/plugins/onLayerEnd/expectedMultiMain.js
@@ -0,0 +1,47 @@
+
+define('plug',[],function () {
+ var buildMap = {},
+ injectPreamble = true,
+ preamble = "'USE PREAMBLE';";
+
+ return {
+ version: '1',
+ load: function (name, require, onLoad, config) {
+ var converted = name.toUpperCase();
+ buildMap[name] = converted;
+ onLoad(converted);
+ },
+
+ write: function (pluginName, moduleName, write, config) {
+ if (buildMap.hasOwnProperty(moduleName)) {
+ if (injectPreamble) {
+ write(preamble);
+ injectPreamble = false;
+ }
+ var content = buildMap[moduleName];
+ write("define('" + pluginName + "!" + moduleName +
+ "', function () { return '" + content + "';});\n");
+ }
+ },
+
+ onLayerEnd: function (write, data) {
+ injectPreamble = true;
+ write("'USE POSTAMBLE';");
+ }
+ };
+});
+
+'USE PREAMBLE';
+define('plug!foo', function () { return 'FOO';});
+
+define('plug!bar', function () { return 'BAR';});
+
+require(['plug!foo', 'plug!bar'],
+function (foo, bar) {
+ console.log(foo);
+ console.log(bar);
+});
+
+define("main", function(){});
+
+'USE POSTAMBLE';
View
47 build/tests/lib/plugins/onLayerEnd/expectedMultiSecondary.js
@@ -0,0 +1,47 @@
+
+define('plug',[],function () {
+ var buildMap = {},
+ injectPreamble = true,
+ preamble = "'USE PREAMBLE';";
+
+ return {
+ version: '1',
+ load: function (name, require, onLoad, config) {
+ var converted = name.toUpperCase();
+ buildMap[name] = converted;
+ onLoad(converted);
+ },
+
+ write: function (pluginName, moduleName, write, config) {
+ if (buildMap.hasOwnProperty(moduleName)) {
+ if (injectPreamble) {
+ write(preamble);
+ injectPreamble = false;
+ }
+ var content = buildMap[moduleName];
+ write("define('" + pluginName + "!" + moduleName +
+ "', function () { return '" + content + "';});\n");
+ }
+ },
+
+ onLayerEnd: function (write, data) {
+ injectPreamble = true;
+ write("'USE POSTAMBLE';");
+ }
+ };
+});
+
+'USE PREAMBLE';
+define('plug!meep', function () { return 'MEEP';});
+
+define('plug!moop', function () { return 'MOOP';});
+
+require(['plug!meep', 'plug!moop'],
+function (meep, moop) {
+ console.log(meep);
+ console.log(moop);
+});
+
+define("secondary", function(){});
+
+'USE POSTAMBLE';
View
5 build/tests/lib/plugins/onLayerEnd/src/main.js
@@ -0,0 +1,5 @@
+require(['plug!foo', 'plug!bar'],
+function (foo, bar) {
+ console.log(foo);
+ console.log(bar);
+});
View
31 build/tests/lib/plugins/onLayerEnd/src/plug.js
@@ -0,0 +1,31 @@
+define(function () {
+ var buildMap = {},
+ injectPreamble = true,
+ preamble = "'USE PREAMBLE';";
+
+ return {
+ version: '1',
+ load: function (name, require, onLoad, config) {
+ var converted = name.toUpperCase();
+ buildMap[name] = converted;
+ onLoad(converted);
+ },
+
+ write: function (pluginName, moduleName, write, config) {
+ if (buildMap.hasOwnProperty(moduleName)) {
+ if (injectPreamble) {
+ write(preamble);
+ injectPreamble = false;
+ }
+ var content = buildMap[moduleName];
+ write("define('" + pluginName + "!" + moduleName +
+ "', function () { return '" + content + "';});\n");
+ }
+ },
+
+ onLayerEnd: function (write, data) {
+ injectPreamble = true;
+ write("'USE POSTAMBLE';");
+ }
+ };
+});
View
5 build/tests/lib/plugins/onLayerEnd/src/secondary.js
@@ -0,0 +1,5 @@
+require(['plug!meep', 'plug!moop'],
+function (meep, moop) {
+ console.log(meep);
+ console.log(moop);
+});
Please sign in to comment.
Something went wrong with that request. Please try again.