Skip to content
This repository has been archived by the owner on Mar 25, 2018. It is now read-only.

feat: add option.exportName #98

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ bem-xjst engines accesible via properties `bemhtml` and `bemtree`:
var engine = require('gulp-bem-xjst')[engine];
```

### Plugin options
### Options

* *String* **exportName** — Engine handler's variable name. Default — `BEMHTML`.
* *String* **engine** — Engine's name. Default — `BEMHTML`.
* *String* **exportName** — Engine handler's variable name.
* *String* **extension** — extension for file. Default — `.${engine}.js`.
* *Object* **engine** — XJST [options](https://github.com/bem/bem-xjst/blob/master/docs/en/3-api.md#settings).
Copy link
Member

@qfox qfox Feb 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Могу ошибаться, но @miripiruni это выпиливал (или exportName)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не понял вопроса, судя по доке опции работают

Copy link
Collaborator

@miripiruni miripiruni Mar 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Опции engine больше нет. Есть только exportName.

Copy link
Member

@qfox qfox Mar 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В общем, коммент надо унести к exportName, а это зарезать.
Только не забыть про старые версии


### License

Expand Down
18 changes: 8 additions & 10 deletions error.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,27 @@ var format = util.format;
/**
* @param {{description: string, column: number, lineNumber: number}} err - Error data
* @param {String} code - Code sample
* @param {String} filepath - Path to the file
* @param {String} filePath - Path to the file
* @return {String|Object}
*/
module.exports = function (err, code, filepath) {
module.exports = function (err, code, filePath) {
// Assume that esprima parser failed
if (err.description && err.column && err.lineNumber) {
var source = code.split('\n');

var addtionalLines = 3;
var additionalLines = 3;
var errorLine = err.lineNumber; // extra line from length prop
var startLine = Math.max(errorLine - addtionalLines, 0);
var endLine = Math.min(errorLine + addtionalLines, source.length);
var startLine = Math.max(errorLine - additionalLines, 0);
var endLine = Math.min(errorLine + additionalLines, source.length);

var fragment = source.slice(startLine, endLine);
// Adding marker
fragment.splice(errorLine - startLine + 1, 0, Array(err.column).join(' ') + '^');
fragment.splice(errorLine - startLine + 1, 0, new Array(err.column).join(' ') + '^');

var message = format('%s at %s:\n%s',
return format('%s at %s:\n%s',
err.description,
path.basename(filepath),
path.basename(filePath),
fragment.join('\n'));

return message;
}

return err;
Expand Down
36 changes: 22 additions & 14 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@ var isStream = require('is-stream');
var toArray = require('stream-to-array');

var formatError = require('./error');
var bundle = require('./lib/templates/bundle');

var pluginName = path.basename(__dirname);

/**
* bem-xjst templates compiler.
*
* @param {{extension: string}} options - Options for generator.
* @param {Object} [options] - Options for generator.
* @param {String} [options.extension] - File extension. Default: engine name.
* @param {String} [options.exportName] - Name for export. Please notice if you set this option generated code will
* @param {Object} [options.engine] - Engine compiler options. @see
* https://github.com/bem/bem-xjst/blob/master/docs/en/3-api.md#settings wrapped with CommonJS, YModules or Global
* @param {String|Function} engine - 'bemhtml' either 'bemtree' or any xjst-like engine function.
* @returns {Stream}
*/
module.exports = function(options, engine) {
module.exports = function (options, engine) {
options = options || {};

assert(typeof engine === 'string' || typeof (engine && engine.generate) === 'function', 'Invalid engine');
Expand All @@ -32,10 +37,10 @@ module.exports = function(options, engine) {
engineName = engine;
engine = bemxjst[engine];
} else {
engineName = (engine.engineName || engine.name || Object(engine.runtime).name).toLowerCase() || 'xjst';
engineName = (engine.engineName || (engine.runtime && engine.runtime.name)).toLowerCase() || 'xjst';
}

return through.obj(function(file, encoding, callback) {
return through.obj(function (file, encoding, callback) {
if (file.isNull()) {
return callback(null, file);
}
Expand All @@ -45,13 +50,16 @@ module.exports = function(options, engine) {
}

var code = file.contents.toString();
var res = tryCatch(function() {
return engine.generate(code, options);
}, function(e) {
var res = tryCatch(function () {
var compiledCode = engine.generate(code, options);

return options.exportName ? bundle(compiledCode, options) : compiledCode;
}, function (e) {
return new PluginError(pluginName, formatError(e, code, file.path), {
fileName: file.path
});
});

if (res instanceof PluginError) {
return callback(res);
}
Expand All @@ -64,28 +72,28 @@ module.exports = function(options, engine) {
});
};

module.exports.bemhtml = function(options) {
module.exports.bemhtml = function (options) {
return module.exports(options, 'bemhtml');
};

module.exports.bemtree = function(options) {
module.exports.bemtree = function (options) {
return module.exports(options, 'bemtree');
};

/**
* Wrapper for anything.apply with bemjson.
*
* @param {Stream<Vinyl>} templatesStream - Stream with bemhtmls
* @returns {TransformStream<Vinyl>} - transform stream that applies templates to each incoming bemjson vinyl
* @param {Stream<File>} templatesStream - Stream with bemhtmls
* @returns {stream.Transform<File>} - transform stream that applies templates to each incoming bemjson vinyl
*/
module.exports.toHtml = function(templatesStream) {
module.exports.toHtml = function (templatesStream) {
if (!isStream(templatesStream)) {
throw new PluginError(pluginName, 'Parameter should be a Stream');
}

var templatesPromise = toArray(templatesStream);

return through.obj(function(bemjsonFile, _, callback) {
return through.obj(function (bemjsonFile, _, callback) {
if (bemjsonFile.isNull()) {
return callback(null, bemjsonFile);
}
Expand All @@ -111,7 +119,7 @@ module.exports.toHtml = function(templatesStream) {
// Handle multiple templates case
var n = 0;

templatesVinyls.forEach(function(file) {
templatesVinyls.forEach(function (file) {
file.data || (file.data = _eval(String(file.contents)));

var html = tryCatch(function () {
Expand Down
41 changes: 41 additions & 0 deletions lib/assets/bundle.jst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
var ${ exportName };

(function(global) {
function buildBemXjst() {
var exports = {};

${ bemxjst }

return exports;
};

var defineAsGlobal = true;

// Provide with CommonJS
if (typeof module === 'object' && typeof module.exports === 'object') {
exports['${ exportName }'] = buildBemXjst();
defineAsGlobal = false;
}

// Provide to YModules
if (typeof modules === 'object') {
modules.define(
'${ exportName }',
[<%_.each([], function(name) {%>'${ name }',<%});%>],
function(
provide<%if ([].length) {%>,<%}%>
${ [].join(', ') }
) {
provide(buildBemXjst());
}
);

defineAsGlobal = false;
}

// Provide to global scope
if (defineAsGlobal) {
${ exportName } = buildBemXjst();
global['${ exportName }'] = ${ exportName };
}
})(typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : this);
31 changes: 31 additions & 0 deletions lib/templates/bundle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
var fs = require('fs');
var path = require('path');

var _ = require('lodash');

var assetDir = path.join(__dirname, '..', 'assets');
var templates = {
bundle: {path: path.join(assetDir, 'bundle.jst')}
};

// load templates
_.mapKeys(templates, function (template, name) {
templates[name] = _.template(fs.readFileSync(template.path, 'utf-8'));
});

/**
* Template for compile BEMHTML or BEMTREE to bundle.
*
* @param {String} code - Code compiled with the `bem-xjst` (BEMHTML or BEMTREE).
* @param {Object} options - Options.
* @param {String} [options.exportName=BEMHTML] - Name for exports.
* @returns {String}
*/
module.exports = function (code, options) {
options || (options = {});

return templates.bundle({
exportName: options.exportName || 'BEMHTML',
bemxjst: code
});
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"dependencies": {
"bem-xjst": "^8.4.0",
"is-stream": "^1.1.0",
"lodash": "^4.17.4",
"node-eval": "^1.1.0",
"plugin-error": "^0.1.2",
"stream-to-array": "^2.3.0",
Expand Down
70 changes: 66 additions & 4 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ describe('gulp-bemhtml', function () {
.on('end', next);

intoStream.obj([new File({
path: 'page.bemhtml',
contents: new Buffer('block(\'page\')(tag()(\'h1\'), content()(\'Hello, world!\'));')
})])
path: 'page.bemhtml',
contents: new Buffer('block(\'page\')(tag()(\'h1\'), content()(\'Hello, world!\'));')
})])
.pipe(stream);
});

Expand All @@ -41,7 +41,7 @@ describe('gulp-bemhtml', function () {
var vinylFile;

before(function (next) {
const stream = lib({}, bemxjst.bemhtml)
var stream = lib({}, bemxjst.bemhtml)
.on('data', function (file) {
vinylFile = file;
})
Expand All @@ -59,4 +59,66 @@ describe('gulp-bemhtml', function () {
expect(vinylFile.relative).to.be.equal('page.bemhtml.js');
});
});

describe('stream with exportName', function () {
var vinylFile;

before(function (next) {
var stream = lib.bemhtml({exportName: 'BEMHTML'})
.on('data', function (file) {
vinylFile = file;
})
.on('error', next)
.on('end', next);

intoStream.obj([new File({
path: 'page.bemhtml',
contents: new Buffer('block(\'page\')(tag()(\'h1\'), content()(\'Hello, world!\'));')
})])
.pipe(stream);
});

it('should export compiler to global', function () {
var engine = _eval(vinylFile.contents.toString());

expect(engine).to.have.property('BEMHTML');
expect(engine.BEMHTML.apply).to.be.a('function');
});

it('should export compiler to custom name', function (next) {
var testFile = '';
var stream = lib.bemhtml({exportName: 'customProperty'})
.on('data', function (file) {
testFile = file;
})
.on('error', compileDone)
.on('end', compileDone);

intoStream.obj([new File({
path: 'page.bemhtml',
contents: new Buffer('block(\'page\')(tag()(\'h1\'), content()(\'Hello, world!\'));')
})])
.pipe(stream);

function compileDone() {
var engine = _eval(testFile.contents.toString());

expect(engine).to.have.property('customProperty');
next();
}
});

it('should export compiler to YModules', function () {
var vm = require('vm');
var name = '';

vm.runInNewContext(vinylFile.contents.toString(), {
require: require,
console: console,
modules: {define: function (exportName) { name = exportName; }}
});

expect(name).to.be('BEMHTML');
});
});
});