UNPKG

3.9 kBJavaScriptView Raw
1/**
2 * gulp-espower - A gulp plugin to apply espower to target files.
3 *
4 * https://github.com/twada/gulp-espower
5 *
6 * Copyright (c) 2013-2015 Takuto Wada
7 * Licensed under the MIT license.
8 * https://github.com/twada/gulp-espower/blob/master/LICENSE-MIT
9 */
10'use strict';
11
12var through = require('through2'),
13 gutil = require('gulp-util'),
14 extend = require('xtend'),
15 BufferStreams = require('bufferstreams'),
16 espower = require('espower'),
17 espowerSource = require('espower-source'),
18 esprima = require('esprima'),
19 escodegen = require('escodegen'),
20 applySourceMap = require('vinyl-sourcemaps-apply'),
21 transfer = require('multi-stage-sourcemap').transfer,
22 convert = require('convert-source-map');
23
24function mergeSourceMap(incomingSourceMap, outgoingSourceMap) {
25 if (typeof outgoingSourceMap === 'string' || outgoingSourceMap instanceof String) {
26 outgoingSourceMap = JSON.parse(outgoingSourceMap);
27 }
28 if (!incomingSourceMap) {
29 return outgoingSourceMap;
30 }
31 return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap}));
32}
33
34function transform (file, encoding, opt) {
35 var inMap = file.sourceMap;
36 var escodegenOptions = {};
37 var jsCode = file.contents.toString(encoding);
38
39 // use file.relative to keep paths relative until the end of chain
40 var jsAst = esprima.parse(jsCode, {tolerant: true, loc: true, source: file.relative});
41
42 var espowerOptions = extend(espower.defaultOptions(), opt, {
43 destructive: true,
44 path: file.path
45 });
46 if (inMap) {
47 espowerOptions.sourceMap = inMap;
48 escodegenOptions = extend(escodegenOptions, {
49 file: file.relative,
50 sourceMap: true,
51 // do not set sourceMapRoot to keep paths relative until the end of chain
52 // sourceMapRoot: file.base,
53 sourceMapWithCode: true
54 });
55 }
56 var modifiedAst = espower(jsAst, espowerOptions);
57 var escodegenOutput = escodegen.generate(modifiedAst, escodegenOptions);
58 if (inMap) {
59 file.contents = new Buffer(escodegenOutput.code);
60 var outMap = convert.fromJSON(escodegenOutput.map.toString());
61 outMap.setProperty('sources', inMap.sources);
62 outMap.setProperty('sourcesContent', inMap.sourcesContent);
63
64 var reMap;
65 if (inMap.mappings === '') {
66 applySourceMap(file, outMap.toJSON());
67 reMap = convert.fromObject(file.sourceMap);
68 } else {
69 reMap = convert.fromObject(mergeSourceMap(inMap, outMap.toJSON()));
70 }
71 reMap.setProperty('sources', inMap.sources);
72 reMap.setProperty('sourcesContent', inMap.sourcesContent);
73 // do not set sourceMapRoot to keep paths relative until the end of chain
74 // reMap.setProperty('sourceRoot', file.base);
75
76 file.sourceMap = reMap.toObject();
77 } else {
78 file.contents = new Buffer(escodegenOutput);
79 }
80}
81
82module.exports = function (opt) {
83 return through.obj(function (file, encoding, callback) {
84 encoding = encoding || 'utf8';
85 if (file.isNull()) {
86 this.push(file);
87 } else if (file.isBuffer()) {
88 try {
89 transform(file, encoding, opt);
90 this.push(file);
91 } catch (err) {
92 return callback(new gutil.PluginError('gulp-espoewr', err, {showStack: true}));
93 }
94 } else if (file.isStream()) {
95 file.contents = file.contents.pipe(new BufferStreams(function(err, buf, cb) {
96 if(err) {
97 cb(new gutil.PluginError('gulp-espower', err, {showStack: true}));
98 } else {
99 cb(null, new Buffer(espowerSource(buf.toString(encoding), file.path, opt)));
100 }
101 }));
102 this.push(file);
103 }
104 callback();
105 });
106};