Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source map support (issue #108) #454

Merged
merged 1 commit into from
Jul 18, 2017
Merged
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
11 changes: 10 additions & 1 deletion bin/bem-xjst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ require('coa').Cmd()
.short('e').long('engine')
.def('bemhtml')
.end()
.opt()
.name('sourcemap').title('Generate source map (default: false)')
.short('s').long('sourcemap')
.def(false)
.flag()
.end()
.act(function(options) {
var input = [],
deferred = q.defer();
Expand All @@ -51,7 +57,10 @@ require('coa').Cmd()

function finish(source) {
var out = bem_xjst[options.engine].generate(source, {
'no-opt': options['no-opt']
'no-opt': options['no-opt'],
from: options.input.path,
to: options.output.path,
sourceMap: options.sourceMap
});

options.output.write(out);
Expand Down
29 changes: 29 additions & 0 deletions docs/en/3-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* [Using thirdparty libraries](#using-thirdparty-libraries)
* [Extending BEMContext](#extending-bemcontext)
* [Bundling](#bundling)
* [Source maps](#source-maps)

## Choosing an engine, compiling and applying templates

Expand Down Expand Up @@ -552,4 +553,32 @@ var bundle = bemxjst.bemhtml.generate(function() {
```
Now `bundle` has a string containing the JavaScript code of the BEMHTML core and the user-defined templates.

## Source maps

There is options in `generate` method to use source maps.

* `to` {String} — output bundle file name
* `sourceMap.from` {String} — file name
* `sourceMap.prev` {String|Function|SourceMapConsumer|SourceMapGenerator} —
* previous source maps in any format

Example of generating bundle with source maps:

```js
var fs = require('fs'),
bemxjst = require('bem-xjst').bemhtml,
tmpl = 'my-block-1.bemhtml.js',
bundle = 'bundle.bemhtml.js';

var result = bemxjst.generate(fs.readFileSync(tmpl, 'utf8'), {
to: bundle,
sourceMap: { from: tmpl }
});

fs.writeFileSync(bundle, result);
```

Also [see examples](../../examples/source-maps/) about source maps and
bem-xjst.

Read next: [Input data](4-data.md)
27 changes: 27 additions & 0 deletions docs/ru/3-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* [Подключение сторонних библиотек](#Подключение-сторонних-библиотек)
* [Расширение BEMContext](#Расширение-bemcontext)
* [Создание бандла](#Создание-бандла)
* [Source maps](#source-maps)

## Выбор движка, компиляция и применение шаблонов

Expand Down Expand Up @@ -556,4 +557,30 @@ fs.writeFile('bundle.js', bundle, function(err) {
полностью готов к исполению в браузерах, node.js или любой виртуальной машине
JS.

## Source maps

В опциях шаблонизатора у вас есть возможность указать данные про карты кода

* `to` {String} — имя выходного бандла-файла
* `sourceMap.from` {String} — имя файла
* `sourceMap.prev` {String|Function|SourceMapConsumer|SourceMapGenerator} — предыдущие карты кода в любом из перечисленных форматов

Пример генерирования бандла с шаблонами и ядром bem-xjst с использованием карт кода:

```js
var fs = require('fs'),
bemxjst = require('bem-xjst').bemhtml,
tmpl = 'my-block-1.bemhtml.js',
bundle = 'bundle.bemhtml.js';

var result = bemxjst.generate(fs.readFileSync(tmpl, 'utf8'), {
to: bundle,
sourceMap: { from: tmpl }
});

fs.writeFileSync(bundle, result);
```

Так же [смотрите примеры](../../examples/source-maps/) по использованию карт кода вместе с шаблонизатором.

Читать далее: [входные данные](4-data.md)
1 change: 1 addition & 0 deletions examples/source-maps/demo1/b1.bemhtml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
block('b1').tag()('blah');
1 change: 1 addition & 0 deletions examples/source-maps/demo1/demo1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<script src="bundle.bemhtml.js"></script>
11 changes: 11 additions & 0 deletions examples/source-maps/demo1/demo1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
var fs = require('fs'),
bemxjst = require('../../../').bemhtml,
tmpl = 'b1.bemhtml.js',
bundle = 'bundle.bemhtml.js';

var result = bemxjst.generate(fs.readFileSync(tmpl, 'utf8'), {
to: bundle,
sourceMap: { from: tmpl }
});

fs.writeFileSync(bundle, result);
1 change: 1 addition & 0 deletions examples/source-maps/demo2/demo2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<script src="bundle.bemhtml.js"></script>
11 changes: 11 additions & 0 deletions examples/source-maps/demo2/demo2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
var fs = require('fs'),
bemxjst = require('../../../').bemhtml,
tmpl = 'tmpls-with-sourcemap.bemhtml.js',
bundle = 'bundle.bemhtml.js';

var result = bemxjst.generate(fs.readFileSync(tmpl, 'utf8'), {
to: bundle,
sourceMap: { from: tmpl }
});

fs.writeFileSync(bundle, result);
72 changes: 72 additions & 0 deletions examples/source-maps/demo2/tmpls-with-sourcemap.bemhtml.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/source-maps/demo3/b3.bemhtml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
block('b3').tag()('blah');
1 change: 1 addition & 0 deletions examples/source-maps/demo3/demo3.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<script src="bundle.bemhtml.js"></script>
14 changes: 14 additions & 0 deletions examples/source-maps/demo3/demo3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var fs = require('fs'),
bemxjst = require('../../../').bemhtml,
tmpl = 'b3.bemhtml.js',
bundle = 'bundle.bemhtml.js';

var result = bemxjst.generate(fs.readFileSync(tmpl, 'utf8'), {
to: bundle,
sourceMap: {
prev: 'block(\'a\').tag()(\'a\');',
from: tmpl
},
});

fs.writeFileSync(bundle, result);
72 changes: 48 additions & 24 deletions lib/compiler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var fnToString = require('./bemxjst/utils').fnToString;
var readFileSync = require('fs').readFileSync;
var SourceMapFile = require('enb-source-map/lib/file');
var engines = {
bemhtml: require('./bemhtml'),
bemtree: require('./bemtree')
Expand Down Expand Up @@ -81,12 +82,14 @@ Compiler.prototype.compile = function compile(code, options) {

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

var exportName = options.exportName || this.engineName;
var sourceMap = options.sourceMap;

if (!options.to) options.to = process.cwd();
var file = new SourceMapFile(options.to, { sourceMap: sourceMap });

code = [
code + ';',
fnToString(code) + ';',
'oninit(function(exports, context) {',
'var BEMContext = exports.BEMContext || context.BEMContext;',
// Provides third-party libraries from different modular systems
Expand All @@ -98,26 +101,42 @@ Compiler.prototype.generate = function generate(code, options) {

var deps = getDeps(options.requires);

var source = [
'var ' + exportName + ';',
'(function(global) {',
'function buildBemXjst(libs) {',
'var exports;',

'/* BEM-XJST Runtime Start */',
'var ' + exportName + ' = function(module, exports) {',
bundles[this.engineName] + ';',
'return module.exports || exports.' + exportName + ';',
'}({}, {});',

'var api = new ' + exportName + '(' + JSON.stringify(options) + ');',
file
.writeContent([
'var ' + exportName + ';',
'(function(global) {',
'function buildBemXjst(libs) {',
'var exports;',

'/* BEM-XJST Runtime Start */',
'var ' + exportName + ' = function(module, exports) {',
bundles[this.engineName] + ';',
'return module.exports || exports.' + exportName + ';',
'}({}, {});',

'var api = new ' + exportName + '(' + JSON.stringify(options) + ');',

'api.compile(function(' +
require('./bemxjst').prototype.locals.join(', ') +
') {',
'/* BEM-XJST User code here: */'
].join(EOL));

if (sourceMap && sourceMap.from) {
file.writeFileContent(sourceMap.from, getCode(code, options.runtimeLint));

if (sourceMap.prev) {
file.writeContent(
file.writeFileFromPrevMap(sourceMap.from, sourceMap.prev));
}
} else {
file.writeContent(getCode(code, options.runtimeLint));
}

'/* BEM-XJST User-code Start */',
'api.compile(function(' +
require('./bemxjst').prototype.locals.join(', ') +
') {',
getCode(code, options.runtimeLint) + ';' +
'});',
file
.write(';')
.writeContent([
'});',

'exports = api.exportApply(exports);',
'if (libs) exports.BEMContext.prototype._libs = libs;',
Expand Down Expand Up @@ -173,9 +192,14 @@ Compiler.prototype.generate = function generate(code, options) {
'})(typeof window !== "undefined" ? ' +
'window : typeof global !== "undefined" ? global : this);'

].join(EOL);
].join(EOL));

return source;
return options.sourceMap && options.sourceMap.include === false ?
{
content: file.getContent(),
sourceMap: file.getSourceMap()
} :
file.render();
};

module.exports = Compiler;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"license": "MPL-2.0",
"dependencies": {
"coa": "^1.0.1",
"enb-source-map": "^1.11.0",
"inherits": "^2.0.1",
"q": "^2.0.3"
},
Expand Down