UNPKG

4.74 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 if (stats.compilation.errors.toString()) {
111 self.emit('error', new gutil.PluginError('webpack-stream', stats.compilation.errors.toString()));
112 }
113 if (!options.watch) {
114 self.queue(null);
115 }
116 done(err, stats);
117 if (options.watch && !options.quiet) {
118 gutil.log('webpack is watching for changes');
119 }
120 });
121
122 // In watch mode webpack returns a wrapper object so we need to get
123 // the underlying compiler
124 if (options.watch) {
125 compiler = compiler.compiler;
126 }
127
128 if (options.progress) {
129 compiler.apply(new ProgressPlugin(function (percentage, msg) {
130 percentage = Math.floor(percentage * 100);
131 msg = percentage + '% ' + msg;
132 if (percentage < 10) msg = ' ' + msg;
133 gutil.log('webpack', msg);
134 }));
135 }
136
137 var fs = compiler.outputFileSystem = new MemoryFileSystem();
138
139 compiler.plugin('after-emit', function (compilation, callback) {
140 Object.keys(compilation.assets).forEach(function (outname) {
141 if (compilation.assets[outname].emitted) {
142 var file = prepareFile(fs, compiler, outname);
143 self.queue(file);
144 }
145 });
146 callback();
147 });
148 });
149
150 // If entry point manually specified, trigger that
151 if (options.entry) {
152 stream.end();
153 }
154
155 return stream;
156};
157
158function prepareFile (fs, compiler, outname) {
159 var path = fs.join(compiler.outputPath, outname);
160 if (path.indexOf('?') !== -1) {
161 path = path.split('?')[0];
162 }
163 var contents = fs.readFileSync(path);
164 var file = new File({
165 base: compiler.outputPath,
166 path: path,
167 contents: contents
168 });
169 return file;
170}
171
172// Expose webpack if asked
173Object.defineProperty(module.exports, 'webpack', {
174 get: function () {
175 return require('webpack');
176 }
177});