Skip to content

Commit 8e23461

Browse files
committed
Fixes #613, option to write out bundles config
1 parent e3d70e0 commit 8e23461

File tree

16 files changed

+1629
-2
lines changed

16 files changed

+1629
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ build/tests/lib/amdefine/built.js
77
build/tests/lib/anonUmdInteriorModules/main-built.js
88
build/tests/lib/appDirSrcOverwrite/www-built
99
build/tests/lib/arrow/main-built.js
10+
build/tests/lib/bundlesConfig/built
1011
build/tests/lib/cjsTranslate/www-built
1112
build/tests/lib/closureExterns/built
1213
build/tests/lib/comments/built.js

build/example.build.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,18 @@
638638
//set "keepBuildDir" to true.
639639
allowSourceOverwrites: false,
640640

641+
//Introduced in 2.2.0. Path to file to write out bundles config
642+
//(http://requirejs.org/docs/api.html#config-bundles) found in the module
643+
//layers built by the optimizer. The path is relative to the "dir" config's
644+
//path. Only applies to full project optimization:
645+
//http://requirejs.org/docs/optimization.html#wholeproject
646+
//Only use if the optimized layers are grouped more intricately then just
647+
//a simple optimization of main app entry points. The file path specified
648+
//should be to one that has the top level requirejs.config() call that sets
649+
//up the loader. If using "mainConfigFile", then this path likely should be
650+
//the path to that file where it is placed in the "dir" output directory.
651+
bundlesConfigOutFile: 'some/path/to/main.js',
652+
641653
//Introduced in 2.2.0. Default is true for compatibility with older
642654
//releases. If set to false, r.js will not write a build.txt file in the
643655
//"dir" directory when doing a full project optimization.

build/jslib/build.js

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,17 +564,36 @@ define(function (require) {
564564
}));
565565
}
566566
}).then(function () {
567-
var moduleName, outOrigSourceMap;
567+
var moduleName, outOrigSourceMap,
568+
bundlesConfig = {},
569+
bundlesConfigOutFile = config.bundlesConfigOutFile;
570+
568571
if (modules) {
569572
//Now move the build layers to their final position.
570573
modules.forEach(function (module) {
571-
var finalPath = module._buildPath;
574+
var entryConfig,
575+
finalPath = module._buildPath;
576+
572577
if (finalPath !== 'FUNCTION') {
573578
if (file.exists(finalPath)) {
574579
file.deleteFile(finalPath);
575580
}
576581
file.renameFile(finalPath + '-temp', finalPath);
577582

583+
//If bundles config should be written out, scan the
584+
//built file for module IDs. Favor doing this reparse
585+
//since tracking the IDs as the file is built has some
586+
//edge cases around files that had more than one ID in
587+
//them already, and likely loader plugin-written contents.
588+
if (bundlesConfigOutFile) {
589+
entryConfig = bundlesConfig[module.name] = [];
590+
var bundleContents = file.readFile(finalPath);
591+
var excludeMap = {};
592+
excludeMap[module.name] = true;
593+
var parsedIds = parse.getAllNamedDefines(bundleContents, excludeMap);
594+
entryConfig.push.apply(entryConfig, parsedIds);
595+
}
596+
578597
//And finally, if removeCombined is specified, remove
579598
//any of the files that were used in this layer.
580599
//Be sure not to remove other build layers.
@@ -601,6 +620,24 @@ define(function (require) {
601620
config.onModuleBundleComplete(module.onCompleteData);
602621
}
603622
});
623+
624+
//Write out bundles config, if it is wanted.
625+
if (bundlesConfigOutFile) {
626+
var text = file.readFile(bundlesConfigOutFile);
627+
text = transform.modifyConfig(text, function (config) {
628+
if (!config.bundles) {
629+
config.bundles = {};
630+
}
631+
632+
lang.eachProp(bundlesConfig, function (value, prop) {
633+
config.bundles[prop] = value;
634+
});
635+
636+
return config;
637+
});
638+
639+
file.saveUtf8File(bundlesConfigOutFile, text);
640+
}
604641
}
605642

606643
//If removeCombined in play, remove any empty directories that
@@ -1287,6 +1324,13 @@ define(function (require) {
12871324
config.dirBaseUrl = endsWithSlash(config.dirBaseUrl);
12881325
}
12891326

1327+
if (config.bundlesConfigOutFile) {
1328+
if (!config.dir) {
1329+
throw new Error('bundlesConfigOutFile can only be used with optimizations ' +
1330+
'that use "dir".');
1331+
}
1332+
config.bundlesConfigOutFile = build.makeAbsPath(config.bundlesConfigOutFile, config.dir);
1333+
}
12901334

12911335
//If out=stdout, write output to STDOUT instead of a file.
12921336
if (config.out && config.out === 'stdout') {

build/jslib/parse.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,33 @@ define(['./esprimaAdapter', 'lang'], function (esprima, lang) {
677677
return name;
678678
};
679679

680+
/**
681+
* Finds all the named define module IDs in a file.
682+
*/
683+
parse.getAllNamedDefines = function (fileContents, excludeMap) {
684+
var names = [];
685+
parse.recurse(esprima.parse(fileContents),
686+
function (callName, config, name, deps, node, factoryIdentifier, fnExpScope) {
687+
if (callName === 'define' && name) {
688+
if (!excludeMap.hasOwnProperty(name)) {
689+
names.push(name);
690+
}
691+
}
692+
693+
//If a UMD definition that points to a factory that is an Identifier,
694+
//indicate processing should not traverse inside the UMD definition.
695+
if (callName === 'define' && factoryIdentifier && hasProp(fnExpScope, factoryIdentifier)) {
696+
return factoryIdentifier;
697+
}
698+
699+
//If define was found, no need to dive deeper, unless
700+
//the config explicitly wants to dig deeper.
701+
return true;
702+
}, {});
703+
704+
return names;
705+
};
706+
680707
/**
681708
* Determines if define(), require({}|[]) or requirejs was called in the
682709
* file. Also finds out if define() is declared and if define.amd is called.

build/tests/builds.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2810,4 +2810,23 @@ define(['build', 'env!env/file', 'env', 'lang'], function (build, file, env, lan
28102810
}
28112811
]);
28122812
doh.run();
2813+
2814+
//Test writing bundles config.
2815+
//See https://github.com/requirejs/r.js/issues/613
2816+
doh.register("writeBundlesConfig",
2817+
[
2818+
function writeBundlesConfig(t) {
2819+
file.deleteFile("lib/bundlesConfig/built");
2820+
2821+
build(["lib/bundlesConfig/build.js"]);
2822+
2823+
t.is(nol(c("lib/bundlesConfig/expected.js")),
2824+
nol(c("lib/bundlesConfig/built/main.js")));
2825+
require._buildReset();
2826+
}
2827+
2828+
]
2829+
);
2830+
doh.run();
2831+
28132832
});

0 commit comments

Comments
 (0)