1 | #!/usr/bin/env node
|
2 |
|
3 | 'use strict';
|
4 |
|
5 | var program = require('commander');
|
6 | var chalk = require('chalk');
|
7 | var events = require('events');
|
8 | var genUnit = require('gen-unit');
|
9 | var path = require('path');
|
10 | var prettyMs = require('pretty-ms');
|
11 | var slash = require('slash');
|
12 | var loadJsonFile = require('load-json-file');
|
13 | var bundlib_js = require('../dist/bundlib.js');
|
14 | var fs = require('fs');
|
15 | var rollup = require('rollup');
|
16 |
|
17 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
18 |
|
19 | var program__default = _interopDefaultLegacy(program);
|
20 | var chalk__default = _interopDefaultLegacy(chalk);
|
21 | var prettyMs__default = _interopDefaultLegacy(prettyMs);
|
22 | var slash__default = _interopDefaultLegacy(slash);
|
23 | var loadJsonFile__default = _interopDefaultLegacy(loadJsonFile);
|
24 |
|
25 | const name = "bundlib";
|
26 | const displayName = "Bundlib";
|
27 | const version = "0.17.8";
|
28 |
|
29 | function readPkg(cwd) {
|
30 | return loadJsonFile__default['default'](path.join(cwd, 'package.json'));
|
31 | }
|
32 |
|
33 | const END = 'end';
|
34 | const BUILD_END = 'build-end';
|
35 | const REBUILD = 'rebuild';
|
36 | const WARN = 'warn';
|
37 | const ERROR = 'error';
|
38 |
|
39 | function oneByOne(arr, callback, done) {
|
40 | let index = 0;
|
41 | const len = arr.length;
|
42 |
|
43 | const next = error => {
|
44 | if (error) {
|
45 | return done(error);
|
46 | }
|
47 |
|
48 | if (index >= len) {
|
49 | return done();
|
50 | }
|
51 |
|
52 | callback(arr[index], next);
|
53 | index++;
|
54 | };
|
55 |
|
56 | next();
|
57 | }
|
58 |
|
59 | function build(configs, emitter) {
|
60 | const cache = {};
|
61 | oneByOne(configs, async (config, next) => {
|
62 | const {
|
63 | input,
|
64 | output
|
65 | } = config;
|
66 | const {
|
67 | file: outputFile,
|
68 | format
|
69 | } = output;
|
70 | const cacheKey = `${format}:${input}`;
|
71 | config.cache = cache[cacheKey];
|
72 |
|
73 | try {
|
74 | const currentTime = Date.now();
|
75 | const buildResult = await rollup.rollup(config);
|
76 | config.cache = cache[cacheKey] = buildResult.cache;
|
77 | await buildResult.write(output);
|
78 | const {
|
79 | size
|
80 | } = fs.statSync(outputFile);
|
81 | const totalTime = Date.now() - currentTime;
|
82 | emitter.emit(BUILD_END, outputFile, size, totalTime);
|
83 | } catch (err) {
|
84 | next(err);
|
85 | throw err;
|
86 | }
|
87 |
|
88 | next();
|
89 | }, error => {
|
90 | if (error) {
|
91 | emitter.emit(ERROR, error);
|
92 | } else {
|
93 | emitter.emit(END);
|
94 | }
|
95 | });
|
96 | }
|
97 |
|
98 | function watch(configs, emitter) {
|
99 | let buildIndex = 0;
|
100 | const handlers = {
|
101 | START() {
|
102 | if (buildIndex) {
|
103 | emitter.emit(REBUILD, buildIndex);
|
104 | }
|
105 |
|
106 | buildIndex++;
|
107 | },
|
108 |
|
109 | END() {
|
110 | emitter.emit(END);
|
111 | },
|
112 |
|
113 | BUNDLE_END(e) {
|
114 | const {
|
115 | length: len
|
116 | } = e.output;
|
117 |
|
118 | for (let i = 0; i < len; i++) {
|
119 | const stats = fs.statSync(e.output[i]);
|
120 | emitter.emit(BUILD_END, e.output[i], stats.size, e.duration);
|
121 | }
|
122 | },
|
123 |
|
124 | ERROR(e) {
|
125 | emitter.emit(ERROR, e.error);
|
126 | }
|
127 |
|
128 | };
|
129 | rollup.watch(configs).on('event', event => {
|
130 | const handleEvent = handlers[event.code];
|
131 |
|
132 | if (handleEvent) {
|
133 | handleEvent(event);
|
134 | }
|
135 | });
|
136 | }
|
137 |
|
138 | async function bundlib(cwd, dev, watch$1, emitter, pkg) {
|
139 | const onwarn = warning => {
|
140 | emitter.emit(WARN, warning);
|
141 | };
|
142 |
|
143 | (watch$1 ? watch : build)(await bundlib_js.configsFromPkg(cwd, {
|
144 | dev,
|
145 | watch: watch$1,
|
146 | onwarn
|
147 | }, pkg), emitter);
|
148 | }
|
149 |
|
150 | function create(name) {
|
151 | const method = console[name];
|
152 | return msg => method(msg);
|
153 | }
|
154 |
|
155 | const log = create('log');
|
156 | const error = create('error');
|
157 | function logError(err) {
|
158 | if (err.stack) {
|
159 | error(err.stack);
|
160 | }
|
161 |
|
162 | const tag = chalk.red.bgWhite.inverse(' error ');
|
163 | error(`${tag} ${chalk.red(err.message || err)}`);
|
164 | }
|
165 |
|
166 | const {
|
167 | bold,
|
168 | inverse,
|
169 | cyan,
|
170 | yellow
|
171 | } = chalk__default['default'];
|
172 | const greenBold = bold.green;
|
173 | const yellowBold = bold.yellow;
|
174 | const magentaBold = bold.magenta;
|
175 |
|
176 | function prjInfo(name, ver) {
|
177 | const projName = greenBold(name);
|
178 | const projVer = yellowBold(`v${ver}`);
|
179 | return `${projName} ${projVer}`;
|
180 | }
|
181 |
|
182 | if (!chalk__default['default'].level && 'MINGW_CHOST' in process.env) {
|
183 | chalk__default['default'].level = 1;
|
184 | }
|
185 |
|
186 | async function action(displayName, version, dev, watch, silent) {
|
187 | const cwd = process.cwd();
|
188 | const pkg = await readPkg(cwd);
|
189 |
|
190 | if (!silent) {
|
191 | log(`${prjInfo(displayName, version)}
|
192 | `);
|
193 | const {
|
194 | name: prjName,
|
195 | displayName: prjDispName,
|
196 | version: prjVer
|
197 | } = pkg;
|
198 | const prjInfoName = prjDispName || prjName;
|
199 |
|
200 | if (prjInfoName && prjVer) {
|
201 | log(`${cyan('building:')} ${prjInfo(prjInfoName, prjVer)}
|
202 | `);
|
203 | }
|
204 | }
|
205 |
|
206 | const showError = watch ? logError : err => {
|
207 | logError(err);
|
208 | process.exit(1);
|
209 | };
|
210 | const emitter = new events.EventEmitter();
|
211 | emitter.on(ERROR, showError);
|
212 |
|
213 | if (!silent) {
|
214 | const formatFileSize = genUnit.createFormatter({
|
215 | unit: 'B',
|
216 | round: 2,
|
217 | find: 1024
|
218 | });
|
219 | emitter.on(BUILD_END, (filename, size, duration) => {
|
220 | const tag = inverse.green(' built ');
|
221 | const path$1 = yellowBold(slash__default['default'](path.relative(cwd, filename)));
|
222 | const coloredSize = magentaBold(formatFileSize(size));
|
223 | const coloredDuration = magentaBold(prettyMs__default['default'](duration, {
|
224 | secondsDecimalDigits: 2
|
225 | }));
|
226 | const info = cyan(`( ${coloredSize} in ${coloredDuration} )`);
|
227 | log(`${tag} ${path$1} ${info}`);
|
228 | });
|
229 | emitter.on(WARN, warning => {
|
230 | const {
|
231 | plugin,
|
232 | message
|
233 | } = warning;
|
234 | const tag = inverse.yellow(' warning! ');
|
235 | const pluginInfo = cyan(`( plugin: ${greenBold(plugin || '<UNKNOWN>')} )`);
|
236 | log(`${tag} ${pluginInfo} ${yellow(message)}`);
|
237 | });
|
238 |
|
239 | if (watch) {
|
240 | emitter.on(REBUILD, () => {
|
241 | log(cyan(`rebuilding...
|
242 | `));
|
243 | });
|
244 | emitter.on(END, () => {
|
245 | log(cyan(`
|
246 | waiting for changes...`));
|
247 | });
|
248 | }
|
249 | }
|
250 |
|
251 | try {
|
252 | await bundlib(cwd, dev, watch, emitter, pkg);
|
253 | } catch (err) {
|
254 | showError(err);
|
255 | }
|
256 | }
|
257 |
|
258 | void program__default['default'].version(version, '-v, --version').name(name).option('-d, --dev', 'create development builds').option('-w, --watch', 'run bundlib in watch mode').option('-s, --silent', 'prevent messages from showing in the console').action(async () => {
|
259 | const {
|
260 | dev,
|
261 | watch,
|
262 | silent
|
263 | } = program__default['default'];
|
264 | await action(displayName, version, dev, watch, silent);
|
265 | }).parseAsync(process.argv);
|
266 |
|