/dist/ because they mess with things like jqueryReturn proper error messages for parse errors when using the middleware
Etag:
add cache clean
--compare: compares the trees from using the detective strategy vs the default strategyBetter externals handling: Sometimes you want to have granular control over what external modules are included in your build. The following options let you do that:
--external <name>: specifies that that module should not be bundled but instead looked up from the global context. For example, --external underscore specifies that the underscore module should not be included in the build result. Any references to underscore will be ignored.
--remap <name>=<expression>: specifies that require(name) should return whatever the value of the expression is. This is useful for remapping external modules. For example you might want to load jQuery externally from window.$ using --remap jquery=window.$.
--no-externals: this option prevents any modules from under node_modules from being included.
--include-external <name>: this option adds an external back after --no-externals (whitelist approach).
--only-externals: this option only bundles modules under node_modules.
Switching between development and production modes:
Example:
if (development) {
app.use();
} else {
glue.package();
app.use(express.static(outDir));
}
Interoperability with libraries that export globals.
Two options:
--remap and remap the global, include two files instead of one filemodule.exports = global, using command:--shim { file: "", name: "", global: "", deps: "" }.
This wraps the file in a way that the global variable is available as require(name).
-> this is basically --remap name=require(file) --no-parse file --append-text file "module.exports = global;"
Mocking out dependencies for testing: This is probably more useful when used via the Express middleware, but --remap name=path allows specific externals to be replaced, which can be used for testing:
// example
Might be nice to make this even easier to use from tests... via REST API?
--dedupe-force modulename should force only a single instance of a module, in spite of conflicting package.json dataSubstituting a module. To replace a module with a different module in gluejs, use the remap option:
remap: { "underscore": "require('lodash')" }
via the command line, this would be written as --remap underscore="require('lodash')".
Substituting a file. The browser field in package.json is a new addition which allows CommonJS bundlers to replace files which are not compatible with the browser with alternatives provided by the module. You can use this to replace files in your build, and it can also be used by 3rd party modules which support both the browser and Node.
You can replace the whole package with a specific file:
"browser": "dist/browser.js"
or you can override individual modules and files in package.json:
"browser": {
"fs": "level-fs",
"./lib/filters.js": "./lib/filters-client.js"
},
This will replace ./lib/filters.js with ./lib/filters-client.js in the build result.
Cleaner separation between Map and Reduce phases.
During the Map phase, a number of tasks are applied to each file.
The tasks take one input, run it through transforms, and write a file into cache. If nothing needs to be done, then a simple direct-read tuple is created.
The Map phase uses a shared queue which supports incremental task queueing.
During the reduce phase, the list of metadata tuples is converted into a set of packages using package inference. Then, the underlying data for each metadata tuple is read in serial order and written to the final output. On read, the final wrapping is done, utilizing the inferred packages.
If any tasks require the package metadata, then they must be performed during the reduce phase. In theory one could add another map phase after packages have been inferred.
-- check for full build match --
Transform queue (transforms/index.js):
[ Initialize queue ]
[ Add new file ]
[ Check that file has not been processed ]
[ Check for cached results, and return if done ]
[ Apply user and other exclusions ]
[ Queue task ]
[ Task run]
[ Match tasks ]
[ If no tasks, just run the parse-result-and-update-deps ]
[ Push deps to queue when done ]
[ If transformations, append parse-result-and-update-deps task ]
[ Run transforms ]
[ Push deps to queue when done ]
[ Start running the queue ]
[ Once done ]
[ Check queue for more, assign if under parallelism limit ]
{ filename: path-to-file, content: path-to-file, deps: [ "str", "str2" ] }
{ filename: "original-path-to-file", content: path-to-result-file, deps: [ "str", "str2" ] }
-- generate joinable list --
Queue tasks:
in a generic way by defining a bunch of callbacks, rather than doing these each in ugly and ad-hoc ways.
--shim:
--no-externals:
{
expr: '*'
type: 'package-filter',
task: function() {
return false;
}
}
--only-externals:
{
expr: base + '/**',
phase: 'file-filter',
task: function() {
return false;
}
}
--ignore:
argv.ignore.toExpr()
{
expr: file paths,
phase: 'file-filter',
task: function() {
// no need to parse the file since it's always an empty file
self.addResult(filename, self.ignoreFile, [], [], []);
// queue has been updated, finish this task
self.emit('miss', filename);
return false;
}
}
{
expr: packages,
phase: 'package-filter',
task: function() {
return false;
}
}
TODO:
Package generator queue (commonjs2/index.js):
[ Infer packages ]
[ Infer package deps ]
- for --parse: just collect
- for --no-parse: guess (e.g. modules in folders at higher levels, and one-level-removed child node_modules)
[ Update reporter size during read ]
[ Wrap file during read (w/ full meta?) ]
{
id: ..,
main: "original-name",
basepath: ...,
files: [ ... ],
deps: { "name": "target" }
}
[ Join files ]
-- generate full build --
TODO:
Steps:
Test cases:
TODO
--cache-clean: Clears the global cache folder by deleting it. This is always done before processing anything else.
There is a builtin Mocha test server task, which takes a set of tests as input and creates a server specifically for running one or more tests.
If you're not using Mocha, you can still use the API to create a package and serve it (with test-framework wrapping).