UNPKG

7.75 kBJavaScriptView Raw
1import fs from 'fs';
2import path from 'path';
3import r from 'rollup';
4import commonjs from 'rollup-plugin-commonjs';
5import pify from 'pify';
6import pMap from 'p-map';
7import today from 'time-stamp';
8import isObject from 'isobject';
9import isPromise from 'p-is-promise';
10import prettyConfig from '@tunnckocore/pretty-config';
11import builtinModules from 'builtin-modules';
12import isCI from 'is-ci';
13
14/* eslint-disable import/max-dependencies, import/no-nodejs-modules */
15
16/* eslint-disable */
17function _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/* eslint-enable */
39
40function arrayify(val) {
41 if (!val) return [];
42 if (Array.isArray(val)) return val;
43 return [val];
44}
45
46function getName(fp) {
47 const ext = path.extname(fp);
48 const basename = path.basename(fp, ext);
49 return basename;
50}
51
52/**
53 * TODO
54 *
55 * @param {*} bundle
56 * @param {*} outputOptions
57 */
58// function rollupGenerate(bundle, outputOptions) {
59// return bundle.generate(outputOptions).then(({ code, map }) => ({
60// outputOptions,
61// code,
62// map,
63// }));
64// }
65
66function rollupWrite(bundle, inputOptions_, outputOptions) {
67 const inputOptions = _objectWithoutProperties(inputOptions_, ['output']);
68
69 return bundle.write(outputOptions).then(() => ({ inputOptions, outputOptions }));
70}
71
72let CACHE = null;
73async function rolldown(config) {
74 /**
75 * If returned is Rollup Config object
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 * If configs found, but for example only `plugins` is given,
105 * then extend the defaults with these coming configs.
106 */
107
108 const obj = await extendDefaults(opts);
109
110 // todo
111 console.log('extendDefaults', obj);
112 return [];
113 // return rolldown(extendDefaults(opts))
114 }
115
116 /**
117 * If returned is Array of Rollup Config objects
118 */
119
120 if (Array.isArray(config)) {
121 return pMap(config, (cfg) => rolldown(cfg));
122 }
123
124 /**
125 * If not found configs and not passed,
126 * then create some basic defaults.
127 * The `config` is `null` here.
128 */
129
130 console.log('config', config);
131 return [];
132 // return rolldown(createDefaults())
133}
134
135function 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
143function createMapper(bundle, opts) {
144 return function targetMapper(outputOptions) {
145 const outFile = outputOptions.file || opts.file;
146 let options = null;
147
148 // if `output.file` exist, use it;
149 // otherwise create `output.file` from given `input` and `output.format`
150 if (outFile) {
151 // support basic placeholders
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 // construct `foo.es.js`
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
172async 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
186function getPkg(cwd) {
187 return pify(fs.readFile)(path.join(cwd, 'package.json'), 'utf8').then(JSON.parse);
188}
189
190async 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 * CLI?
215 */
216
217async 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 * @copyright 2017-present, Charlike Mike Reagent <olsten.larck@gmail.com>
236 * @license Apache-2.0
237 */
238
239const 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
251const build = async (opts) => {
252 const { shell } = opts;
253 await shell('rm -rf dist');
254 await runnerWithLog(opts);
255};
256
257const 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
277const 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
299const docs = 'verb';
300
301const 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
308const 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
321const tasks = {
322 lint,
323 test,
324 commit,
325 docs,
326 build,
327 release,
328 protect,
329};
330
331var index = { tasks };
332
333export default index;