From a2b4f5113dd06687d9f532d7643f31fbc1037248 Mon Sep 17 00:00:00 2001 From: andrewblond Date: Tue, 26 May 2015 11:43:26 +0300 Subject: [PATCH] Added `requires` option --- lib/compile.js | 86 ++++++++++-------- techs/bh-bundle.js | 4 +- test/fixtures/browser--global.html | 1 + test/techs/bh-bundle/bh-bundle--node.test.js | 91 +++++++++++++++----- test/techs/bh-bundle/browser--global.test.js | 16 ++-- test/techs/bh-bundle/browser--ym.test.js | 37 ++++++-- 6 files changed, 163 insertions(+), 72 deletions(-) diff --git a/lib/compile.js b/lib/compile.js index 2ee69ef..05b0f27 100644 --- a/lib/compile.js +++ b/lib/compile.js @@ -23,7 +23,7 @@ core.contents = fs.readFileSync(core.path, 'utf-8'); * @param {Boolean} [opts.jsElem] Use `jsElem` option for bh core * @param {String} [opts.scope=template] Scope of the executing code templates * @param {String[]} [opts.mimic] Names for exports - * @param {Object} [opts.dependencies] Names for requires to `BH.lib.name` + * @param {Object} [opts.requires] Names for requires to `BH.lib.name` * @returns {String} compiled code of bh module */ function compile(sources, opts) { @@ -37,8 +37,7 @@ function compile(sources, opts) { var file = new File(opts.filename, opts.sourcemap), isTemplateScope = opts.hasOwnProperty('scope') ? opts.scope === 'template' : true, mimic = opts.mimic || [], - dependencies = opts.dependencies || {}, - depNames = Object.keys(dependencies); + requires = opts.requires || {}; // IIFE start file.writeLine('(function (global) {'); @@ -56,9 +55,9 @@ function compile(sources, opts) { '});' ].join(EOL)); - // wrap in IIFE to ignore utility variables for templates - file.writeLine('(function (global, BH) {'); - // Source Templates + // `init()` will be called after all the dependencies (bh.lib) will be provided + // wrap in function scope not to pollute templates scope + file.writeLine('var init = function (global, BH) {'); sources.forEach(function (source) { var relPath = source.relPath || source.path; @@ -69,32 +68,32 @@ function compile(sources, opts) { file.writeLine('// end: ' + relPath); isTemplateScope && file.writeLine('}());'); }); - file.writeLine('}());'); + file.writeLine('};'); // Export bh file.writeLine([ 'var defineAsGlobal = true;', // Provide to YModules 'if (typeof modules === "object") {', - compileYModule('BH', dependencies), + compileYModule('BH', requires), + ' init();', mimic.map(function (name) { return compileYModule(name); }).join(EOL), ' defineAsGlobal = false;', - // Provide libs from global scope - depNames.length ? - [ - '} else {', - depNames.map(function (name) { - return ' bh.lib.' + name + ' = ' + dependencies[name] + ';'; - }).join(EOL), - '}' - ].join(EOL) : - '}', - // Provide with CommonJS - 'if (typeof exports === "object") {', + '} else if (typeof exports === "object") {', + Object.keys(requires).map(function (name) { + var item = requires[name]; + + if (item.commonJS) { + return ' bh.lib.' + name + ' = require("' + item.commonJS + '");'; + } else if (item.globals) { + return ' bh.lib.' + name + ' = global["' + item.globals + '"];'; + } + }).join(EOL), + ' init();', mimic.map(function (name) { return ' bh["' + name + '"] = bh;'; }).join(EOL), @@ -104,6 +103,14 @@ function compile(sources, opts) { // Provide to Global Scope 'if (defineAsGlobal) {', + Object.keys(requires).map(function (name) { + var item = requires[name]; + + if (item.globals) { + return ' bh.lib.' + name + ' = global["' + item.globals + '"];'; + } + }).join(EOL), + ' init();', ' global.BH = bh;', mimic.map(function (name) { return ' global["' + name + '"] = bh;'; @@ -120,24 +127,35 @@ function compile(sources, opts) { /** * Compile code with YModule definition that exports `BH` module. * - * @param {String} name Module name - * @param {Object} [dependencies] Names for requires to `bh.lib.name`. + * @param {String} name Module name + * @param {Object} [requires] Names for requires to `bh.lib.name`. * @returns {String} */ -function compileYModule(name, dependencies) { - dependencies || (dependencies = {}); - - var libs = Object.keys(dependencies), - deps = libs.map(function (name) { - return dependencies[name]; - }); +function compileYModule(name, requires) { + var modules = [], + deps = [], + globals = {}; + + requires && Object.keys(requires).forEach(function (name) { + var item = requires[name]; + + if (item.ym) { + modules.push(item.ym); + deps.push(name); + } else if (item.globals) { + globals[name] = item.globals; + } + }); return [ - ' modules.define("' + name + '"' + (deps ? ', ' + JSON.stringify(deps) : '') + - ', function(provide' + (libs && libs.length ? ', ' + libs.join(', ') : '') + ') {', - libs.map(function (name) { - return ' bh.lib.' + name + ' = ' + dependencies[name] + ';'; - }), + ' modules.define("' + name + '"' + (modules ? ', ' + JSON.stringify(modules) : '') + + ', function(provide' + (deps && deps.length ? ', ' + deps.join(', ') : '') + ') {', + deps.map(function (name) { + return ' bh.lib.' + name + ' = ' + name + ';'; + }).join(EOL), + Object.keys(globals).map(function (name) { + return ' bh.lib.' + name + ' = global["' + globals[name] + '"];'; + }).join(EOL), ' provide(bh);', ' });' ].join(EOL); diff --git a/techs/bh-bundle.js b/techs/bh-bundle.js index 761f651..381cc83 100644 --- a/techs/bh-bundle.js +++ b/techs/bh-bundle.js @@ -47,7 +47,7 @@ var vow = require('vow'), module.exports = require('enb/lib/build-flow').create() .name('bh-bundle') .target('target', '?.bh.js') - .defineOption('dependencies', {}) + .defineOption('requires', {}) .defineOption('mimic', []) .defineOption('jsAttrName', 'data-bem') .defineOption('jsAttrScheme', 'json') @@ -82,7 +82,7 @@ module.exports = require('enb/lib/build-flow').create() escapeContent: this._escapeContent, scope: this._scope, mimic: [].concat(this._mimic), - dependencies: this._dependencies + requires: this._requires }; return compile(sources, opts); diff --git a/test/fixtures/browser--global.html b/test/fixtures/browser--global.html index c51e977..c03d0ec 100644 --- a/test/fixtures/browser--global.html +++ b/test/fixtures/browser--global.html @@ -6,6 +6,7 @@
+