diff --git a/tasks/build.js b/tasks/build.js index 4ba42ab908..4481843b32 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -27,6 +27,10 @@ function assertValidConfig(config, callback) { callback(new Error('Config missing "exports" array')); return; } + if (config.namespace && typeof config.namespace !== 'string') { + callback(new Error('Config "namespace" must be a string')); + return; + } if (config.compile && typeof config.compile !== 'object') { callback(new Error('Config "compile" must be an object')); return; @@ -182,7 +186,7 @@ function build(config, paths, callback) { function main(config, callback) { async.waterfall([ assertValidConfig.bind(null, config), - generateExports.bind(null, config.exports), + generateExports.bind(null, config), getDependencies.bind(null, config.src), build.bind(null, config) ], callback); diff --git a/tasks/generate-exports.js b/tasks/generate-exports.js index 70d5dd2b40..e736b661e3 100644 --- a/tasks/generate-exports.js +++ b/tasks/generate-exports.js @@ -11,15 +11,14 @@ var build = path.join(__dirname, '..', 'build'); /** - * Get a list of patterns from the config file. If configPath is provided + * Get the configuration from the config file. If configPath is provided * it is assumed to be a JSON file with an 'exports' member that is a list * of symbol names or patterns. * * @param {string} configPath Path to config file. - * @param {function(Error, Array.)} callback Called with the list of - * patterns. + * @param {function(Error, Object)} callback Called with config object. */ -function getPatterns(configPath, callback) { +function getConfig(configPath, callback) { if (configPath) { fs.readFile(configPath, function(err, data) { if (err) { @@ -38,11 +37,17 @@ function getPatterns(configPath, callback) { callback(new Error('Expected an exports array, got: ' + patterns)); return; } - callback(null, patterns); + var namespace = obj.namespace; + if (namespace && typeof namespace !== 'string') { + callback(new Error('Expected an namespace string, got: ' + + namespace)); + return; + } + callback(null, obj); }); } else { process.nextTick(function() { - callback(null, ['*']); + callback(null, {exports: ['*']}); }); } } @@ -117,12 +122,15 @@ function filterSymbols(patterns, symbols, callback) { /** * Generate goog code to export a named symbol. * @param {string} name Symbol name. + * @param {string|undefined} namespace Target object for exported + * symbols. * @return {string} Export code. */ -function formatSymbolExport(name) { +function formatSymbolExport(name, namespace) { return 'goog.exportSymbol(\n' + ' \'' + name + '\',\n' + - ' ' + name + ');\n'; + ' ' + name + + (namespace ? ',\n ' + namespace : '') + ');\n'; } @@ -145,9 +153,10 @@ function formatPropertyExport(name) { /** * Generate export code given a list symbol names. * @param {Array.} symbols List of symbols. + * @param {string|undefined} namespace Target object for exported symbols. * @return {string} Export code. */ -function generateExports(symbols) { +function generateExports(symbols, namespace) { var blocks = []; var requires = {}; symbols.forEach(function(symbol) { @@ -158,7 +167,7 @@ function generateExports(symbols) { if (name.indexOf('#') > 0) { blocks.push(formatPropertyExport(name)); } else { - blocks.push(formatSymbolExport(name)); + blocks.push(formatSymbolExport(name, namespace)); } }); blocks.unshift('\n'); @@ -172,18 +181,18 @@ function generateExports(symbols) { /** * Generate the exports code. * - * @param {Array.} patterns List of symbol names or patterns. + * @param {Object} config Config object with exports and (optional) namespace. * @param {function(Error, string)} callback Called with the exports code or any * error generating it. */ -function main(patterns, callback) { +function main(config, callback) { async.waterfall([ - getSymbols.bind(null, patterns), + getSymbols.bind(null, config.exports), filterSymbols, function(symbols, done) { var code, err; try { - code = generateExports(symbols); + code = generateExports(symbols, config.namespace); } catch (e) { err = e; } @@ -212,7 +221,7 @@ if (require.main === module) { }).parse(); async.waterfall([ - getPatterns.bind(null, options.config), + getConfig.bind(null, options.config), main, fse.outputFile.bind(fse, options.output) ], function(err) { diff --git a/tasks/readme.md b/tasks/readme.md index 720b0c0459..812170ba1b 100644 --- a/tasks/readme.md +++ b/tasks/readme.md @@ -25,6 +25,8 @@ Build configuration files are JSON files that are used to determine what should * **src** - `Array.` Optional array of [path patterns](https://github.com/isaacs/minimatch/blob/master/README.md) for source files. This defaults to `["src/**/*.js"]` which will match all `.js` files in the `src` directory. To include a different set of source files, provide an array of path patterns. Note that these patterns are `/` delimited even on Windows. + * **namespace** - `string` Optional namespace for exporting the `ol` object. By default, `ol` is assigned to the global object. + * **jvm** - `Array.` Optional array of [command line options](https://code.google.com/p/closure-compiler/wiki/FAQ#What_are_the_recommended_Java_VM_command-line_options?) for the compiler. By default, the Compiler is run with `['-server', '-XX:+TieredCompilation']`. The build task generates a list of source files sorted in dependency order and passes these to the compiler. This takes the place of the `--js` options that you would use when calling the compiler directly. If you want to add additional source files, typically you would use the `src` array described above. This works with sources that have `goog.require` and/or `goog.provide` calls (which are used to sort dependencies). If you want to force the inclusion of files that don't use `goog.require` or `goog.provide`, you can use the `js` property of the `compile` object. Paths in the `js` array will be passed to the compiler **after** all other source files. @@ -62,6 +64,19 @@ To generate a build named `ol.min.js` with the `build.json`, you would run this: node tasks/build.js build.json ol.min.js +To export the `ol` symbol to somewhere else than the global namespace, a `namespace` option is available. This can e.g. be useful for creating an ol3 AMD module, by simply providing a build configuration like the following: + +```js +{ + "exports": ["*"], + "namespace": "AMD", + "compile": { + "compilation_level": "ADVANCED_OPTIMIZATIONS", + "output_wrapper": "define('ol',function(){var AMD={};%output%return AMD.ol;});" + } +} +``` + ## `generate-exports.js`