UNPKG

4.96 kBJavaScriptView Raw
1'use strict';
2
3var gutil = require('gulp-util');
4var File = require('vinyl');
5var MemoryFileSystem = require('memory-fs');
6var through = require('through');
7var ProgressPlugin = require('webpack/lib/ProgressPlugin');
8var clone = require('lodash.clone');
9
10var defaultStatsOptions = {
11 colors: gutil.colors.supportsColor,
12 hash: false,
13 timings: false,
14 chunks: false,
15 chunkModules: false,
16 modules: false,
17 children: true,
18 version: true,
19 cached: false,
20 cachedAssets: false,
21 reasons: false,
22 source: false,
23 errorDetails: false
24};
25
26module.exports = function (options, wp, done) {
27 options = clone(options) || {};
28 if (typeof done !== 'function') {
29 var callingDone = false;
30 done = function (err, stats) {
31 if (err) {
32 // The err is here just to match the API but isnt used
33 return;
34 }
35 stats = stats || {};
36 if (options.quiet || callingDone) {
37 return;
38 }
39 // Debounce output a little for when in watch mode
40 if (options.watch) {
41 callingDone = true;
42 setTimeout(function () {
43 callingDone = false;
44 }, 500);
45 }
46 if (options.verbose) {
47 gutil.log(stats.toString({
48 colors: gutil.colors.supportsColor
49 }));
50 } else {
51 var statsOptions = options && options.stats || {};
52
53 Object.keys(defaultStatsOptions).forEach(function (key) {
54 if (typeof statsOptions[key] === 'undefined') {
55 statsOptions[key] = defaultStatsOptions[key];
56 }
57 });
58
59 gutil.log(stats.toString(statsOptions));
60 }
61 };
62 }
63
64 var webpack = wp || require('webpack');
65 var entry = [];
66 var entries = Object.create(null);
67
68 var stream = through(function (file) {
69 if (file.isNull()) {
70 return;
71 }
72 if ('named' in file) {
73 if (!Array.isArray(entries[file.named])) {
74 entries[file.named] = [];
75 }
76 entries[file.named].push(file.path);
77 } else {
78 entry = entry || [];
79 entry.push(file.path);
80 }
81 }, function () {
82 var self = this;
83 options.output = options.output || {};
84
85 // Determine pipe'd in entry
86 if (Object.keys(entries).length > 0) {
87 entry = entries;
88 if (!options.output.filename) {
89 // Better output default for multiple chunks
90 options.output.filename = '[name].js';
91 }
92 } else if (entry.length < 2) {
93 entry = entry[0] || entry;
94 }
95
96 options.entry = options.entry || entry;
97 options.output.path = options.output.path || process.cwd();
98 options.output.filename = options.output.filename || '[hash].js';
99 entry = [];
100
101 if (!options.entry || options.entry.length < 1) {
102 gutil.log('webpack-stream - No files given; aborting compilation');
103 return self.emit('end');
104 }
105
106 var compiler = webpack(options, function (err, stats) {
107 if (err) {
108 self.emit('error', new gutil.PluginError('webpack-stream', err));
109 }
110 var jsonStats = stats.toJson() || {};
111 var errors = jsonStats.errors || [];
112 if (errors.length) {
113 var errorMessage = errors.reduce(function (resultMessage, nextError) {
114 resultMessage += nextError.toString();
115 return resultMessage;
116 }, '');
117 self.emit('error', new gutil.PluginError('webpack-stream', errorMessage));
118 }
119 if (!options.watch) {
120 self.queue(null);
121 }
122 done(err, stats);
123 if (options.watch && !options.quiet) {
124 gutil.log('webpack is watching for changes');
125 }
126 });
127
128 // In watch mode webpack returns a wrapper object so we need to get
129 // the underlying compiler
130 if (options.watch) {
131 compiler = compiler.compiler;
132 }
133
134 if (options.progress) {
135 compiler.apply(new ProgressPlugin(function (percentage, msg) {
136 percentage = Math.floor(percentage * 100);
137 msg = percentage + '% ' + msg;
138 if (percentage < 10) msg = ' ' + msg;
139 gutil.log('webpack', msg);
140 }));
141 }
142
143 var fs = compiler.outputFileSystem = new MemoryFileSystem();
144
145 compiler.plugin('after-emit', function (compilation, callback) {
146 Object.keys(compilation.assets).forEach(function (outname) {
147 if (compilation.assets[outname].emitted) {
148 var file = prepareFile(fs, compiler, outname);
149 self.queue(file);
150 }
151 });
152 callback();
153 });
154 });
155
156 // If entry point manually specified, trigger that
157 if (options.entry) {
158 stream.end();
159 }
160
161 return stream;
162};
163
164function prepareFile (fs, compiler, outname) {
165 var path = fs.join(compiler.outputPath, outname);
166 if (path.indexOf('?') !== -1) {
167 path = path.split('?')[0];
168 }
169 var contents = fs.readFileSync(path);
170 var file = new File({
171 base: compiler.outputPath,
172 path: path,
173 contents: contents
174 });
175 return file;
176}
177
178// Expose webpack if asked
179Object.defineProperty(module.exports, 'webpack', {
180 get: function () {
181 return require('webpack');
182 }
183});