Skip to content

Commit

Permalink
Use bem-xjst in Node.js without bundling via browserify (#407 and #408
Browse files Browse the repository at this point in the history
…fixed)
  • Loading branch information
miripiruni authored Feb 1, 2017
1 parent 53f0da9 commit 687969f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 76 deletions.
14 changes: 4 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
var fs = require('fs');
var Compiler = require('./lib/compiler').Compiler;
var Compiler = require('./lib/compiler');
var _cache = {};

function getEngine(engineName) {
if (_cache[engineName]) return _cache[engineName];
var engine = _cache[engineName];

var runtime = require('./lib/' + engineName);
var pathToBundle = require.resolve('./lib/' + engineName + '/bundle');
var sourceBundle = fs.readFileSync(pathToBundle, 'utf8');

runtime.source = sourceBundle;
return engine || (engine = new Compiler(engineName));
};

return _cache[engineName] = new Compiler(runtime);
}

module.exports = {
get bemtree() { return getEngine('bemtree'); },
Expand Down
33 changes: 18 additions & 15 deletions lib/bemxjst/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,15 @@ BEMXJST.prototype.compile = function compile(code) {
this.oninit = out.oninit;
};

BEMXJST.prototype.recompileInput = function recompileInput(code) {
var args = BEMXJST.prototype.locals;
var out = code.toString();

// Strip the function
out = out.replace(/^function[^{]+{|}$/g, '');
BEMXJST.prototype.getTemplate = function(code, options) {
this.compile(code, options);

// And recompile it with right arguments
out = new Function(args.join(', '), out);
return this.exportApply();
};

return out;
BEMXJST.prototype.recompileInput = function recompileInput(code) {
return new Function(BEMXJST.prototype.locals.join(', '),
utils.fnToString(code));
};

BEMXJST.prototype.groupEntities = function groupEntities(tree) {
Expand Down Expand Up @@ -513,23 +511,28 @@ BEMXJST.prototype.applyMode = function applyMode(mode, changes) {

BEMXJST.prototype.exportApply = function exportApply(exports) {
var self = this;
exports.apply = function apply(context) {
var ret = exports || {};

ret.apply = function apply(context) {
return self.run(context);
};

// Add templates at run time
exports.compile = function compile(templates) {
return self.compile(templates);
ret.compile = function compile(templates) {
self.compile(templates);
return ret;
};

var sharedContext = {};

exports.BEMContext = this.contextConstructor;
sharedContext.BEMContext = exports.BEMContext;
ret.BEMContext = this.contextConstructor;
sharedContext.BEMContext = ret.BEMContext;

for (var i = 0; i < this.oninit.length; i++) {
var oninit = this.oninit[i];

oninit(exports, sharedContext);
oninit(ret, sharedContext);
}

return ret;
};
79 changes: 29 additions & 50 deletions lib/compiler.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,56 @@
var vm = require('vm');
var BEMXJSTError = require('./bemxjst/error').BEMXJSTError;
var fnToString = require('./bemxjst/utils').fnToString;
var engines = {
bemhtml: require('./bemhtml'),
bemtree: require('./bemtree')
};

function Compiler(runtime) {
this.runtime = runtime;
function Compiler(engineName) {
this.engineName = engineName;
}

exports.Compiler = Compiler;
function getCode(code, isRuntimeLint) {
return isRuntimeLint ?
(fnToString(code) + ';' + fnToString(require('../runtime-lint')))
: fnToString(code);
}

Compiler.prototype.generate = function generate(code, options) {
Compiler.prototype.compile = function compile(code, options) {
if (!options) options = {};
var api = new engines[this.engineName](options);
return api.getTemplate(getCode(code, options.runtimeLint), options);
};

Compiler.prototype.generate = function generate(code, options) {
if (!options) options = {};
code = fnToString(code);

var exportName = options.exportName || 'BEMHTML';
var engine = options.engine || 'BEMHTML';

var locals = this.runtime.prototype.locals;

if (options.runtimeLint)
code = code + ';' + require('fs')
.readFileSync('./runtime-lint/index.js', 'utf8');
var exportName = this.engineName.toUpperCase();

var source = [
'/// -------------------------------------',
'/// --------- BEM-XJST Runtime Start ----',
'/// -------------------------------------',
'var ' + exportName + ' = function(module, exports) {',
this.runtime.source + ';',
require('fs').readFileSync(
require.resolve('./' + this.engineName + '/bundle'),
'utf8'
),
';',
' return module.exports ||',
' exports.' + exportName + ';',
'}({}, {});',
'/// -------------------------------------',
'/// --------- BEM-XJST Runtime End ------',
'/// -------------------------------------',
'',
'var api = new ' + engine + '(' + JSON.stringify(options) + ');',
'var api = new ' + exportName + '(' + JSON.stringify(options) + ');',
'/// -------------------------------------',
'/// ------ BEM-XJST User-code Start -----',
'/// -------------------------------------',
'api.compile(function(' + locals.join(', ') + ') {',
code + ';',
'api.compile(function(',
require('./bemxjst').prototype.locals.join(', '),
') {',
getCode(code, options.runtimeLint) + ';',
'});',
'api.exportApply(exports);',
'/// -------------------------------------',
Expand All @@ -51,35 +61,4 @@ Compiler.prototype.generate = function generate(code, options) {
return source;
};

var _compile = function _compile(fn, exports) {
try {
fn(exports, console);
} catch (e) {
if (e instanceof BEMXJSTError)
throw new BEMXJSTError(e.message);
else
throw e;
}

return exports;
};

Compiler.prototype.compile = function compile(code, options) {
if (!options) options = {};

var out = this.generate(code, options);

out = '(function(exports, console) {' + out + '})';
var exports = {};

var fn = options.context === 'this' ?
vm.runInThisContext(out) :
vm.runInNewContext(out, {
console: console,
Error: Error,
BEMXJSTError: BEMXJSTError });

_compile(fn, exports);

return exports;
};
module.exports = Compiler;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"test": "npm run make && npm run test:lint && npm run test:coverage && npm run size",
"test:lint": "jscs `ls lib/*.js lib/**/*.js test/*.js | grep -v bundle` && jshint `ls lib/*.js lib/**/*.js test/*.js | grep -v bundle`",
"test:mocha": "mocha --reporter=spec test/*-test.js",
"test:coverage": "./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- -u bdd -R spec test/*-test.js",
"test:coverage": "./node_modules/.bin/istanbul cover -x '**/runtime-lint/**' ./node_modules/mocha/bin/_mocha -- -u bdd -R spec test/*-test.js",
"size": "npm run size:bemhtml && npm run size:bemtree",
"size:bemhtml": "ls -ola ./lib/bemhtml/bundle.js | awk '{print \"BEMHTML Bundle Size:\", $4\" B\"}'",
"size:bemtree": "ls -ola ./lib/bemtree/bundle.js | awk '{print \"BEMTREE Bundle Size:\", $4\" B\"}'"
Expand Down
3 changes: 3 additions & 0 deletions runtime-lint/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module.exports = function(match, block, elem, mod, elemMod, oninit, xjstOptions, wrap, replace, extend, mode, def, content, appendContent, prependContent, attrs, addAttrs, js, addJs, mix, addMix, mods, addMods, addElemMods, elemMods, tag, cls, bem, local, applyCtx, applyNext, apply) {
var collectMixes = function collectMixes(item, res, context) {
res = res || [];
if (!item)
Expand Down Expand Up @@ -320,3 +321,5 @@ block('*')(
return applyNext();
})
);

};

0 comments on commit 687969f

Please sign in to comment.