1 | import fs from 'fs';
|
2 | import path from 'path';
|
3 | import r from 'rollup';
|
4 | import commonjs from 'rollup-plugin-commonjs';
|
5 | import pify from 'pify';
|
6 | import pMap from 'p-map';
|
7 | import today from 'time-stamp';
|
8 | import isObject from 'isobject';
|
9 | import isPromise from 'p-is-promise';
|
10 | import prettyConfig from '@tunnckocore/pretty-config';
|
11 | import builtinModules from 'builtin-modules';
|
12 | import isCI from 'is-ci';
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | function _objectWithoutProperties(source, excluded) {
|
18 | if (source == null) return {};
|
19 | const target = {};
|
20 | const sourceKeys = Object.keys(source);
|
21 | let key, i;
|
22 | for (i = 0; i < sourceKeys.length; i++) {
|
23 | key = sourceKeys[i];
|
24 | if (excluded.indexOf(key) >= 0) continue;
|
25 | target[key] = source[key];
|
26 | }
|
27 | if (Object.getOwnPropertySymbols) {
|
28 | const sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
29 | for (i = 0; i < sourceSymbolKeys.length; i++) {
|
30 | key = sourceSymbolKeys[i];
|
31 | if (excluded.indexOf(key) >= 0) continue;
|
32 | if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
33 | target[key] = source[key];
|
34 | }
|
35 | }
|
36 | return target;
|
37 | }
|
38 |
|
39 |
|
40 | function arrayify(val) {
|
41 | if (!val) return [];
|
42 | if (Array.isArray(val)) return val;
|
43 | return [val];
|
44 | }
|
45 |
|
46 | function getName(fp) {
|
47 | const ext = path.extname(fp);
|
48 | const basename = path.basename(fp, ext);
|
49 | return basename;
|
50 | }
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 | function rollupWrite(bundle, inputOptions_, outputOptions) {
|
67 | const inputOptions = _objectWithoutProperties(inputOptions_, ['output']);
|
68 |
|
69 | return bundle.write(outputOptions).then(() => ({ inputOptions, outputOptions }));
|
70 | }
|
71 |
|
72 | let CACHE = null;
|
73 | async function rolldown(config) {
|
74 | |
75 |
|
76 |
|
77 |
|
78 | if (isObject(config)) {
|
79 | const opts = Object.assign({}, config);
|
80 |
|
81 | if (Array.isArray(opts.input) && !opts.experimentalCodeSplitting) {
|
82 | const cfg = multipleInputs(opts);
|
83 |
|
84 | return rolldown(cfg);
|
85 | }
|
86 |
|
87 | if (opts.input && opts.output) {
|
88 | const outputs = arrayify(opts.output).reduce(
|
89 | (acc, item) => acc.concat(typeof item === 'string' ? { format: item } : item),
|
90 | [],
|
91 | );
|
92 | opts.output = outputs;
|
93 | opts.cache = CACHE;
|
94 |
|
95 | const bundle = await r.rollup(opts);
|
96 | CACHE = bundle;
|
97 |
|
98 | const targetMapper = createMapper(bundle, opts);
|
99 |
|
100 | return pMap(outputs, targetMapper);
|
101 | }
|
102 |
|
103 | |
104 |
|
105 |
|
106 |
|
107 |
|
108 | const obj = await extendDefaults(opts);
|
109 |
|
110 |
|
111 | console.log('extendDefaults', obj);
|
112 | return [];
|
113 |
|
114 | }
|
115 |
|
116 | |
117 |
|
118 |
|
119 |
|
120 | if (Array.isArray(config)) {
|
121 | return pMap(config, (cfg) => rolldown(cfg));
|
122 | }
|
123 |
|
124 | |
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 | console.log('config', config);
|
131 | return [];
|
132 |
|
133 | }
|
134 |
|
135 | function multipleInputs(opts) {
|
136 | return opts.input.filter(Boolean).reduce((acc, inputItem) => {
|
137 | const input = _objectWithoutProperties(inputItem, ['input']);
|
138 |
|
139 | return acc.concat(Object.assign({ input }, opts));
|
140 | }, []);
|
141 | }
|
142 |
|
143 | function createMapper(bundle, opts) {
|
144 | return function targetMapper(outputOptions) {
|
145 | const outFile = outputOptions.file || opts.file;
|
146 | let options = null;
|
147 |
|
148 |
|
149 |
|
150 | if (outFile) {
|
151 |
|
152 | const file = outFile
|
153 | .replace('[date]', today())
|
154 | .replace('[name]', getName(opts.input))
|
155 | .replace('[format]', outputOptions.format);
|
156 |
|
157 | options = { file };
|
158 | } else {
|
159 |
|
160 | const fmt = outputOptions.format;
|
161 | const basename = `${getName(opts.input)}.${fmt}.js`;
|
162 | const file = path.join('dist', basename);
|
163 | options = { file };
|
164 | }
|
165 |
|
166 | options = Object.assign({}, outputOptions, options);
|
167 |
|
168 | return rollupWrite(bundle, opts, options);
|
169 | };
|
170 | }
|
171 |
|
172 | async function extendDefaults(incomingOptions) {
|
173 | const filepath = 'src/cli.js';
|
174 | const hasCLI = fs.existsSync(filepath);
|
175 |
|
176 | return Object.assign(
|
177 | {
|
178 | input: ['src/index.js', hasCLI ? filepath : false],
|
179 | output: [{ format: 'cjs' }, { format: 'es' }],
|
180 | external: builtinModules,
|
181 | },
|
182 | incomingOptions,
|
183 | );
|
184 | }
|
185 |
|
186 | function getPkg(cwd) {
|
187 | return pify(fs.readFile)(path.join(cwd, 'package.json'), 'utf8').then(JSON.parse);
|
188 | }
|
189 |
|
190 | async function run(cwd) {
|
191 | const configFiles = prettyConfig.configFiles
|
192 | .slice(0, -1)
|
193 | .reduce((acc, item) => acc.concat(`src/${item}`, item), [])
|
194 | .concat('package.json');
|
195 |
|
196 | let settings = await prettyConfig('rollup', { configFiles });
|
197 |
|
198 | if (!settings) {
|
199 | settings = await prettyConfig('rolldown', { configFiles });
|
200 | }
|
201 |
|
202 | if (isPromise(settings)) {
|
203 | settings = await settings;
|
204 | }
|
205 |
|
206 | const pkg = await getPkg(cwd);
|
207 | settings.external = builtinModules.concat(Object.keys(pkg.dependencies));
|
208 | settings.plugins = [commonjs()];
|
209 |
|
210 | return rolldown(settings);
|
211 | }
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 | async function runnerWithLog(opts) {
|
218 | const results = await run(opts.cwd);
|
219 | const res = results.reduce((acc, config) => acc.concat(config), []).filter(Boolean);
|
220 |
|
221 | const log = (cfg) => {
|
222 | console.log(cfg.inputOptions.input, '->', cfg.outputOptions.file);
|
223 | };
|
224 |
|
225 | res.forEach((config) => {
|
226 | if (Array.isArray(config)) {
|
227 | config.forEach(log);
|
228 | } else {
|
229 | log(config);
|
230 | }
|
231 | });
|
232 | }
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 | const lint = async ({ argv, shell }) => {
|
240 | let cmd = 'eslint src test -f codeframe --quiet --fix';
|
241 |
|
242 | if (argv.dry) {
|
243 | cmd = `${cmd} --fix-dry`;
|
244 | } else {
|
245 | cmd = `${cmd} --fix`;
|
246 | }
|
247 |
|
248 | return shell(cmd);
|
249 | };
|
250 |
|
251 | const build = async (opts) => {
|
252 | const { shell } = opts;
|
253 | await shell('rm -rf dist');
|
254 | await runnerWithLog(opts);
|
255 | };
|
256 |
|
257 | const test = async (opts) => {
|
258 | const { argv, shell } = opts;
|
259 |
|
260 | const flags = Object.assign({ path: 'test', build: true }, argv);
|
261 | const cmd = `node ${flags.path}`;
|
262 |
|
263 | if (flags.build) {
|
264 | await build(opts);
|
265 | }
|
266 |
|
267 | if (flags.cov === false) {
|
268 | return shell(`node ${flags.path}`);
|
269 | }
|
270 | if (flags.check === false) {
|
271 | return shell([`nyc --reporter=lcov ${cmd}`, 'nyc report']);
|
272 | }
|
273 |
|
274 | return shell([`nyc --reporter=lcov ${cmd}`, 'nyc report', 'nyc check-coverage']);
|
275 | };
|
276 |
|
277 | const commit = async (opts) => {
|
278 | const { argv, shell } = opts;
|
279 |
|
280 | if (argv.lint !== false) {
|
281 | await lint(opts);
|
282 | }
|
283 |
|
284 | if (argv.dry) {
|
285 | return shell(['git add --all', 'gitcommit -s -S']);
|
286 | }
|
287 |
|
288 | if (argv.docs !== false) {
|
289 | await shell('yarn start docs');
|
290 | }
|
291 |
|
292 | if (argv.test !== false) {
|
293 | await test(opts);
|
294 | }
|
295 |
|
296 | return shell(['git status --porcelain', 'git add --all', 'gitcommit -s -S']);
|
297 | };
|
298 |
|
299 | const docs = 'verb';
|
300 |
|
301 | const protect = async () => {
|
302 | if (!isCI) {
|
303 | const msg = 'the "npm publish" is forbidden, we release and publish on CI service';
|
304 | throw new Error(msg);
|
305 | }
|
306 | };
|
307 |
|
308 | const release = async (opts) => {
|
309 | const { argv, shell } = opts;
|
310 | const flags = Object.assign({ build: true }, argv);
|
311 |
|
312 | if (flags.build) {
|
313 | await build(opts);
|
314 | }
|
315 |
|
316 | await protect();
|
317 |
|
318 | return shell('new-release');
|
319 | };
|
320 |
|
321 | const tasks = {
|
322 | lint,
|
323 | test,
|
324 | commit,
|
325 | docs,
|
326 | build,
|
327 | release,
|
328 | protect,
|
329 | };
|
330 |
|
331 | var index = { tasks };
|
332 |
|
333 | export default index;
|