1 | #!/usr/bin/env node
|
2 |
|
3 | const babel = require('rollup-plugin-babel');
|
4 | const { default: babelrc } = require('babelrc-rollup');
|
5 | const { exists, stat, writeFile, readFile } = require('mz/fs');
|
6 | const paramCase = require('param-case');
|
7 | const path = require('path');
|
8 | const argv = require('yargs').argv;
|
9 | const forEach = require('apr-for-each');
|
10 | const parallel = require('apr-parallel');
|
11 | const main = require('apr-main');
|
12 | const readPkg = require('read-pkg');
|
13 | const pkgDir = require('pkg-dir');
|
14 | const { rollup } = require('rollup');
|
15 | const camelCase = require('camel-case');
|
16 | const makeDir = require('make-dir');
|
17 |
|
18 | const babelConfig = async ({ root, pkg }) => {
|
19 | const dotrc = path.join(root, '.babelrc');
|
20 | const dotrcExists = await exists(dotrc);
|
21 |
|
22 | if (dotrcExists) {
|
23 | const str = await readFile(dotrc, 'utf-8');
|
24 | return JSON.parse(str);
|
25 | }
|
26 |
|
27 | const dotjson = path.join(root, '.babelrc.json');
|
28 | const dotjsonExists = await exists(dotjson);
|
29 |
|
30 | if (dotjsonExists) {
|
31 | const str = await readFile(dotjson, 'utf-8');
|
32 | return JSON.parse(str);
|
33 | }
|
34 |
|
35 | return pkg.babel || {};
|
36 | };
|
37 |
|
38 | const build = async ({ pkg, main, external, root }) => {
|
39 | const config = await babelConfig({ root, pkg });
|
40 |
|
41 | const bundle = await rollup({
|
42 | input: main,
|
43 | external,
|
44 | sourcemap: true,
|
45 | plugins: [
|
46 | babel(
|
47 | babelrc({
|
48 | config,
|
49 | addExternalHelpersPlugin: true
|
50 | })
|
51 | )
|
52 | ]
|
53 | });
|
54 |
|
55 | const write = fmt => async () => {
|
56 | const { code, map } = await bundle.generate({
|
57 | format: fmt,
|
58 | amd: { id: pkg.name },
|
59 | name: fmt === 'iife' ? camelCase(pkg.name) : pkg.name,
|
60 | sourcemap: true
|
61 | });
|
62 |
|
63 | const file = await dest({ root, main, fmt, pkg });
|
64 |
|
65 | await makeDir(path.dirname(file));
|
66 | return writeFile(file, `${code}\n//# sourceMappingURL=${map.toUrl()}`);
|
67 | };
|
68 |
|
69 | return parallel([write('umd'), write('es'), write('iife')]);
|
70 | };
|
71 |
|
72 | const dest = async ({ root, main, fmt, pkg }) => {
|
73 | if (!pkg) {
|
74 | return path.join(process.cwd(), `dist/index.${fmt}.js`);
|
75 | }
|
76 |
|
77 | if (!pkg.entry || path.resolve(pkg.entry) === path.resolve(main)) {
|
78 | return path.join(root, `dist/${paramCase(pkg.name)}.${fmt}.js`);
|
79 | }
|
80 |
|
81 | const name = path.basename(main, path.extname(main));
|
82 | return path.join(process.cwd(), `dist/${paramCase(name)}.${fmt}.js`);
|
83 | };
|
84 |
|
85 | const getPkg = async dir => {
|
86 | if (!dir) {
|
87 | return;
|
88 | }
|
89 |
|
90 | const pathanme = path.join(dir, 'package.json');
|
91 | const hasPkg = await exists(pathanme);
|
92 |
|
93 | if (!hasPkg) {
|
94 | return;
|
95 | }
|
96 |
|
97 | return readPkg(pathanme);
|
98 | };
|
99 |
|
100 | const pkgEntry = async location => {
|
101 | const root = await pkgDir(location);
|
102 | const pkg = await getPkg(root);
|
103 | const pkgEntry = path.resolve(root, pkg.entry || 'index.js');
|
104 | const pkgEntryExists = await exists(pkgEntry);
|
105 | return pkgEntryExists ? pkgEntry : null;
|
106 | };
|
107 |
|
108 | const entry = async location => {
|
109 | const isDir = (await stat(location)).isDirectory();
|
110 |
|
111 | if (!isDir) {
|
112 | return location;
|
113 | }
|
114 |
|
115 | const index = path.join(location, 'index.js');
|
116 | const indexExists = await exists(index);
|
117 |
|
118 | if (indexExists) {
|
119 | return index;
|
120 | }
|
121 |
|
122 | const main = await pkgEntry(location);
|
123 |
|
124 | if (main) {
|
125 | return main;
|
126 | }
|
127 |
|
128 | throw new Error("Can't resolve entrypoint");
|
129 | };
|
130 |
|
131 | const external = async ({ pkg }) => {
|
132 | return ['dependencies', 'devDependencies', 'peerDependencies'].reduce(
|
133 | (deps, name) => Object.keys(pkg[name] || {}).concat(deps),
|
134 | []
|
135 | );
|
136 | };
|
137 |
|
138 | const run = async () => {
|
139 | if (!argv._.length) {
|
140 | argv._.push('.');
|
141 | }
|
142 |
|
143 | return forEach(argv._, async arg => {
|
144 | const location = path.resolve(process.cwd(), arg);
|
145 | const main = await entry(location);
|
146 | const root = await pkgDir(main);
|
147 | const pkg = await getPkg(root);
|
148 |
|
149 | const ctx = {
|
150 | main,
|
151 | location,
|
152 | root,
|
153 | pkg
|
154 | };
|
155 |
|
156 | return build(
|
157 | Object.assign(ctx, {
|
158 | external: await external(ctx)
|
159 | })
|
160 | );
|
161 | });
|
162 | };
|
163 |
|
164 | main(run());
|