UNPKG

4.5 kBJavaScriptView Raw
1/**
2 * gulp-espower - A gulp plugin to apply espower to target files.
3 *
4 * https://github.com/power-assert-js/gulp-espower
5 *
6 * Copyright (c) 2013-2015 Takuto Wada
7 * Licensed under the MIT license.
8 * https://github.com/power-assert-js/gulp-espower/blob/master/LICENSE-MIT
9 */
10'use strict';
11
12var through = require('through2');
13var gutil = require('gulp-util');
14var extend = require('xtend');
15var BufferStreams = require('bufferstreams');
16var espower = require('espower');
17var espowerSource = require('espower-source');
18var esprima = require('esprima');
19var escodegen = require('escodegen');
20var applySourceMap = require('vinyl-sourcemaps-apply');
21var transfer = require('multi-stage-sourcemap').transfer;
22var 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 mergeEspowerOptions (options, file) {
35 return extend(espower.defaultOptions(), {
36 sourceRoot: file.cwd,
37 path: file.path
38 }, options, {
39 destructive: true
40 });
41}
42
43function transform (file, encoding, opt) {
44 var inMap = file.sourceMap;
45 var escodegenOptions = {};
46 var jsCode = file.contents.toString(encoding);
47
48 var jsAst = esprima.parse(jsCode, {tolerant: true, loc: true});
49
50 var espowerOptions = mergeEspowerOptions(opt, file);
51 if (inMap) {
52 espowerOptions.sourceMap = inMap;
53 // https://github.com/floridoo/gulp-sourcemaps#plugin-developers-only-how-to-add-source-map-support-to-plugins
54 escodegenOptions = extend(escodegenOptions, {
55 // use file.relative for `file` and `sources` to keep paths relative until the end of chain
56 file: file.relative,
57 sourceMap: file.relative,
58 // do not set sourceMapRoot to keep paths relative until the end of chain
59 // sourceMapRoot: file.base,
60 sourceMapWithCode: true
61 });
62 }
63 var modifiedAst = espower(jsAst, espowerOptions);
64 var escodegenOutput = escodegen.generate(modifiedAst, escodegenOptions);
65 if (inMap) {
66 file.contents = new Buffer(escodegenOutput.code);
67 var outMap = convert.fromJSON(escodegenOutput.map.toString());
68 outMap.setProperty('sources', inMap.sources);
69 outMap.setProperty('sourcesContent', inMap.sourcesContent);
70
71 var reMap;
72 if (inMap.mappings === '') {
73 applySourceMap(file, outMap.toJSON());
74 reMap = convert.fromObject(file.sourceMap);
75 } else {
76 reMap = convert.fromObject(mergeSourceMap(inMap, outMap.toJSON()));
77 }
78 reMap.setProperty('sources', inMap.sources);
79 reMap.setProperty('sourcesContent', inMap.sourcesContent);
80 // do not set sourceMapRoot to keep paths relative until the end of chain
81 // reMap.setProperty('sourceRoot', file.base);
82
83 file.sourceMap = reMap.toObject();
84 } else {
85 file.contents = new Buffer(escodegenOutput);
86 }
87}
88
89module.exports = function (opt) {
90 return through.obj(function (file, encoding, callback) {
91 encoding = encoding || 'utf8';
92 if (file.isNull()) {
93 this.push(file);
94 } else if (file.isBuffer()) {
95 try {
96 transform(file, encoding, opt);
97 this.push(file);
98 } catch (err) {
99 return callback(new gutil.PluginError('gulp-espoewr', err, {showStack: true}));
100 }
101 } else if (file.isStream()) {
102 file.contents = file.contents.pipe(new BufferStreams(function(err, buf, cb) {
103 if(err) {
104 cb(new gutil.PluginError('gulp-espower', err, {showStack: true}));
105 } else {
106 var modifiedCode;
107 try {
108 modifiedCode = espowerSource(buf.toString(encoding), file.path, mergeEspowerOptions(opt, file));
109 } catch (err) {
110 return callback(new gutil.PluginError('gulp-espoewr', err, {showStack: true}));
111 }
112 cb(null, new Buffer(modifiedCode));
113 }
114 }));
115 this.push(file);
116 }
117 callback();
118 });
119};