@nocobase/build 0.7.0-alpha.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +0 -0
  3. package/bin/nocobase-build.js +71 -0
  4. package/lib/babel.js +252 -0
  5. package/lib/build.js +351 -0
  6. package/lib/es5ImcompatibleVersions.js +51 -0
  7. package/lib/getBabelConfig.js +75 -0
  8. package/lib/getRollupConfig.js +320 -0
  9. package/lib/getUserConfig.js +99 -0
  10. package/lib/importLibToEs.js +38 -0
  11. package/lib/index.js +13 -0
  12. package/lib/normalizeBundleOpts.js +35 -0
  13. package/lib/randomColor.js +32 -0
  14. package/lib/registerBabel.js +38 -0
  15. package/lib/rollup.js +144 -0
  16. package/lib/schema.js +213 -0
  17. package/lib/types.d.js +1 -0
  18. package/lib/utils/getLernaPackages/index.js +63 -0
  19. package/lib/utils/index.js +48 -0
  20. package/package.json +78 -0
  21. package/src/babel.ts +257 -0
  22. package/src/build.ts +260 -0
  23. package/src/es5ImcompatibleVersions.ts +33 -0
  24. package/src/getBabelConfig.ts +95 -0
  25. package/src/getRollupConfig.ts +343 -0
  26. package/src/getUserConfig.ts +87 -0
  27. package/src/importLibToEs.js +26 -0
  28. package/src/index.ts +3 -0
  29. package/src/normalizeBundleOpts.ts +24 -0
  30. package/src/randomColor.ts +34 -0
  31. package/src/registerBabel.ts +23 -0
  32. package/src/rollup.ts +77 -0
  33. package/src/schema.ts +175 -0
  34. package/src/types.d.ts +118 -0
  35. package/src/utils/getLernaPackages/fixtures/customize/core/core1/package.json +7 -0
  36. package/src/utils/getLernaPackages/fixtures/customize/core/core1/src/index.js +2 -0
  37. package/src/utils/getLernaPackages/fixtures/customize/core/core2/package.json +5 -0
  38. package/src/utils/getLernaPackages/fixtures/customize/core/core2/src/index.js +2 -0
  39. package/src/utils/getLernaPackages/fixtures/customize/lerna.json +6 -0
  40. package/src/utils/getLernaPackages/fixtures/customize/package.json +4 -0
  41. package/src/utils/getLernaPackages/fixtures/customize/packages/bar/package.json +4 -0
  42. package/src/utils/getLernaPackages/fixtures/customize/packages/bar/src/index.js +2 -0
  43. package/src/utils/getLernaPackages/fixtures/customize/packages/foo/package.json +7 -0
  44. package/src/utils/getLernaPackages/fixtures/customize/packages/foo/src/index.js +2 -0
  45. package/src/utils/getLernaPackages/fixtures/default/lerna.json +1 -0
  46. package/src/utils/getLernaPackages/fixtures/default/package.json +4 -0
  47. package/src/utils/getLernaPackages/fixtures/default/packages/bar/package.json +4 -0
  48. package/src/utils/getLernaPackages/fixtures/default/packages/bar/src/index.js +2 -0
  49. package/src/utils/getLernaPackages/fixtures/default/packages/foo/package.json +7 -0
  50. package/src/utils/getLernaPackages/fixtures/default/packages/foo/src/index.js +2 -0
  51. package/src/utils/getLernaPackages/index.ts +57 -0
  52. package/src/utils/index.ts +13 -0
  53. package/template/tsconfig.json +23 -0
@@ -0,0 +1,343 @@
1
+ import { existsSync } from 'fs'
2
+ import { basename, extname, join } from 'path';
3
+ import { ModuleFormat, RollupOptions, Plugin } from 'rollup';
4
+ import url from '@rollup/plugin-url';
5
+ import json from '@rollup/plugin-json';
6
+ import replace from '@rollup/plugin-replace';
7
+ import commonjs from '@rollup/plugin-commonjs';
8
+ import nodeResolve from '@rollup/plugin-node-resolve';
9
+ import inject, { RollupInjectOptions } from '@rollup/plugin-inject';
10
+ import babel, { RollupBabelInputPluginOptions } from '@rollup/plugin-babel';
11
+ import { createFilter } from '@rollup/pluginutils';
12
+ import postcss from 'rollup-plugin-postcss';
13
+ import { terser } from 'rollup-plugin-terser';
14
+ import typescript2 from 'rollup-plugin-typescript2';
15
+ import { camelCase } from 'lodash';
16
+ import tempDir from 'temp-dir';
17
+ import autoprefixer from 'autoprefixer';
18
+ import NpmImport from 'less-plugin-npm-import';
19
+ import svgr from '@svgr/rollup';
20
+ import getBabelConfig from './getBabelConfig';
21
+ import { getPkgPath, shouldTransform } from './es5ImcompatibleVersions';
22
+ import { IBundleOptions } from './types';
23
+
24
+ interface IGetRollupConfigOpts {
25
+ cwd: string;
26
+ rootPath: string;
27
+ entry: string;
28
+ type: ModuleFormat;
29
+ importLibToEs?: boolean;
30
+ bundleOpts: IBundleOptions;
31
+ }
32
+
33
+ interface IPkg {
34
+ dependencies?: Object;
35
+ peerDependencies?: Object;
36
+ name?: string;
37
+ }
38
+
39
+ export default function(opts: IGetRollupConfigOpts): RollupOptions[] {
40
+ const { type, entry, cwd, rootPath, importLibToEs, bundleOpts } = opts;
41
+ const {
42
+ umd,
43
+ esm,
44
+ cjs,
45
+ file,
46
+ target = 'browser',
47
+ extractCSS = false,
48
+ injectCSS = true,
49
+ cssModules: modules,
50
+ extraPostCSSPlugins = [],
51
+ extraBabelPresets = [],
52
+ extraBabelPlugins = [],
53
+ extraRollupPlugins = [],
54
+ autoprefixer: autoprefixerOpts,
55
+ include = /node_modules/,
56
+ runtimeHelpers: runtimeHelpersOpts,
57
+ replace: replaceOpts,
58
+ inject: injectOpts,
59
+ extraExternals = [],
60
+ externalsExclude = [],
61
+ nodeVersion,
62
+ typescriptOpts,
63
+ nodeResolveOpts = {},
64
+ disableTypeCheck,
65
+ lessInRollupMode = {},
66
+ sassInRollupMode = {},
67
+ } = bundleOpts;
68
+ const entryExt = extname(entry);
69
+ const name = file || basename(entry, entryExt);
70
+ const isTypeScript = entryExt === '.ts' || entryExt === '.tsx';
71
+ const extensions = ['.js', '.jsx', '.ts', '.tsx', '.es6', '.es', '.mjs'];
72
+
73
+ let pkg = {} as IPkg;
74
+ try {
75
+ pkg = require(join(cwd, 'package.json')); // eslint-disable-line
76
+ } catch (e) {}
77
+
78
+ // cjs 不给浏览器用,所以无需 runtimeHelpers
79
+ const runtimeHelpers = type === 'cjs' ? false : runtimeHelpersOpts;
80
+ const babelOpts = {
81
+ ...(getBabelConfig({
82
+ type,
83
+ target: type === 'esm' ? 'browser' : target,
84
+ // watch 模式下有几率走的 babel?原因未知。
85
+ // ref: https://github.com/umijs/father/issues/158
86
+ typescript: true,
87
+ runtimeHelpers,
88
+ nodeVersion,
89
+ }).opts),
90
+ // ref: https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers
91
+ babelHelpers: (runtimeHelpers ? 'runtime' : 'bundled') as RollupBabelInputPluginOptions['babelHelpers'],
92
+ // exclude: /\/node_modules\//,
93
+ filter: (filePath: string) => {
94
+ const rollupFilter = createFilter(null, /\/node_modules\//);
95
+ // 默认过滤 node_modules
96
+ if (!rollupFilter(filePath)) {
97
+ const pkgPath = getPkgPath(filePath);
98
+ return shouldTransform(pkgPath);
99
+ }
100
+ return true;
101
+ },
102
+ babelrc: false,
103
+ // ref: https://github.com/rollup/rollup-plugin-babel#usage
104
+ extensions,
105
+ };
106
+ if (importLibToEs && type === 'esm') {
107
+ babelOpts.plugins.push(require.resolve('../lib/importLibToEs'));
108
+ }
109
+ babelOpts.presets.push(...extraBabelPresets);
110
+ babelOpts.plugins.push(...extraBabelPlugins);
111
+
112
+ // rollup configs
113
+ const input = join(cwd, entry);
114
+ const format = type;
115
+
116
+ // ref: https://rollupjs.org/guide/en#external
117
+ // 潜在问题:引用包的子文件时会报 warning,比如 @babel/runtime/helpers/esm/createClass
118
+ // 解决方案:可以用 function 处理
119
+ const external = [
120
+ ...Object.keys(pkg.dependencies || {}),
121
+ ...Object.keys(pkg.peerDependencies || {}),
122
+ ...extraExternals,
123
+ ];
124
+ // umd 只要 external peerDependencies
125
+ const externalPeerDeps = [
126
+ ...Object.keys(pkg.peerDependencies || {}),
127
+ ...extraExternals,
128
+ ];
129
+
130
+ function getPkgNameByid(id) {
131
+ const splitted = id.split('/');
132
+ // @ 和 @tmp 是为了兼容 umi 的逻辑
133
+ if (id.charAt(0) === '@' && splitted[0] !== '@' && splitted[0] !== '@tmp') {
134
+ return splitted
135
+ .slice(0, 2)
136
+ .join('/');
137
+ } else {
138
+ return id.split('/')[0];
139
+ }
140
+ }
141
+
142
+ function testExternal(pkgs, excludes, id) {
143
+ if (excludes.includes(id)) {
144
+ return false;
145
+ }
146
+ return pkgs.includes(getPkgNameByid(id));
147
+ }
148
+
149
+ const terserOpts = {
150
+ compress: {
151
+ pure_getters: true,
152
+ unsafe: true,
153
+ unsafe_comps: true,
154
+ warnings: false,
155
+ },
156
+ };
157
+
158
+ // https://github.com/umijs/father/issues/164
159
+ function mergePlugins(defaultRollupPlugins: Array<Plugin> = [], extraRollupPlugins: Array<Plugin> = []) {
160
+ const pluginsMap: Record<string, Plugin> = Object.assign(
161
+ defaultRollupPlugins.reduce((r, plugin) => ({ ...r, [plugin.name]: plugin }), {}),
162
+ extraRollupPlugins.reduce((r, plugin) => ({ ...r, [plugin.name]: plugin }), {}),
163
+ );
164
+ return Object.values(pluginsMap);
165
+ }
166
+
167
+ function getPlugins(opts = {} as { minCSS: boolean; }) {
168
+ const { minCSS } = opts;
169
+ const defaultRollupPlugins = [
170
+ url(),
171
+ svgr(),
172
+ postcss({
173
+ extract: extractCSS,
174
+ inject: injectCSS,
175
+ modules,
176
+ // modules => all .less will convert into css modules
177
+ ...(modules ? { autoModules: false } : {}),
178
+ minimize: !!minCSS,
179
+ use: {
180
+ less: {
181
+ plugins: [new NpmImport({ prefix: '~' })],
182
+ javascriptEnabled: true,
183
+ ...lessInRollupMode
184
+ },
185
+ sass: {
186
+ ...sassInRollupMode,
187
+ },
188
+ stylus: false,
189
+ },
190
+ plugins: [autoprefixer({
191
+ // https://github.com/postcss/autoprefixer/issues/776
192
+ remove: false,
193
+ ...autoprefixerOpts,
194
+ }), ...extraPostCSSPlugins],
195
+ }),
196
+ ...(injectOpts ? [inject(injectOpts as RollupInjectOptions)] : []),
197
+ ...(replaceOpts && Object.keys(replaceOpts || {}).length ? [replace(replaceOpts)] : []),
198
+ nodeResolve({
199
+ mainFields: ['module', 'jsnext:main', 'main'],
200
+ extensions,
201
+ ...nodeResolveOpts,
202
+ }),
203
+ ...(isTypeScript
204
+ ? [
205
+ typescript2({
206
+ cwd,
207
+ // @see https://github.com/umijs/father/issues/61#issuecomment-544822774
208
+ clean: true,
209
+ cacheRoot: `${tempDir}/.rollup_plugin_typescript2_cache`,
210
+ // 支持往上找 tsconfig.json
211
+ // 比如 lerna 的场景不需要每个 package 有个 tsconfig.json
212
+ tsconfig: [join(cwd, 'tsconfig.json'), join(rootPath, 'tsconfig.json')].find(existsSync),
213
+ tsconfigDefaults: {
214
+ compilerOptions: {
215
+ // Generate declaration files by default
216
+ declaration: true,
217
+ },
218
+ },
219
+ tsconfigOverride: {
220
+ compilerOptions: {
221
+ // Support dynamic import
222
+ target: 'esnext',
223
+ },
224
+ },
225
+ check: !disableTypeCheck,
226
+ ...(typescriptOpts || {}),
227
+ }),
228
+ ]
229
+ : []),
230
+ babel(babelOpts),
231
+ json(),
232
+ ];
233
+ return mergePlugins(defaultRollupPlugins, extraRollupPlugins || []);
234
+ }
235
+
236
+ switch (type) {
237
+ case 'esm':
238
+ const output: Record<string, any> = {
239
+ dir: join(cwd, `${esm && (esm as any).dir || 'dist'}`),
240
+ entryFileNames: `${(esm && (esm as any).file) || `${name}.esm`}.js`,
241
+ }
242
+
243
+ return [
244
+ {
245
+ input,
246
+ output: {
247
+ format,
248
+ ...output,
249
+ },
250
+ plugins: [...getPlugins(), ...(esm && (esm as any).minify ? [terser(terserOpts)] : [])],
251
+ external: testExternal.bind(null, external, externalsExclude),
252
+ },
253
+ ...(esm && (esm as any).mjs
254
+ ? [
255
+ {
256
+ input,
257
+ output: {
258
+ format,
259
+ file: join(cwd, `dist/${(esm && (esm as any).file) || `${name}`}.mjs`),
260
+ },
261
+ plugins: [
262
+ ...getPlugins(),
263
+ replace({
264
+ 'process.env.NODE_ENV': JSON.stringify('production'),
265
+ }),
266
+ terser(terserOpts),
267
+ ],
268
+ external: testExternal.bind(null, externalPeerDeps, externalsExclude),
269
+ },
270
+ ]
271
+ : []),
272
+ ];
273
+
274
+ case 'cjs':
275
+ return [
276
+ {
277
+ input,
278
+ output: {
279
+ format,
280
+ file: join(cwd, `dist/${(cjs && (cjs as any).file) || name}.js`),
281
+ },
282
+ plugins: [...getPlugins(), ...(cjs && (cjs as any).minify ? [terser(terserOpts)] : [])],
283
+ external: testExternal.bind(null, external, externalsExclude),
284
+ },
285
+ ];
286
+
287
+ case 'umd':
288
+ // Add umd related plugins
289
+ const extraUmdPlugins = [
290
+ commonjs({
291
+ include,
292
+ // namedExports options has been remove from https://github.com/rollup/plugins/pull/149
293
+ }),
294
+ ];
295
+
296
+ return [
297
+ {
298
+ input,
299
+ output: {
300
+ format,
301
+ sourcemap: umd && umd.sourcemap,
302
+ file: join(cwd, `dist/${(umd && umd.file) || `${name}.umd`}.js`),
303
+ globals: umd && umd.globals,
304
+ name: (umd && umd.name) || (pkg.name && camelCase(basename(pkg.name))),
305
+ },
306
+ plugins: [
307
+ ...extraUmdPlugins,
308
+ ...getPlugins(),
309
+ replace({
310
+ 'process.env.NODE_ENV': JSON.stringify('development'),
311
+ }),
312
+ ],
313
+ external: testExternal.bind(null, externalPeerDeps, externalsExclude),
314
+ },
315
+ ...(umd && umd.minFile === false
316
+ ? []
317
+ : [
318
+ {
319
+ input,
320
+ output: {
321
+ format,
322
+ sourcemap: umd && umd.sourcemap,
323
+ file: join(cwd, `dist/${(umd && umd.file) || `${name}.umd`}.min.js`),
324
+ globals: umd && umd.globals,
325
+ name: (umd && umd.name) || (pkg.name && camelCase(basename(pkg.name))),
326
+ },
327
+ plugins: [
328
+ ...extraUmdPlugins,
329
+ ...getPlugins({ minCSS: true }),
330
+ replace({
331
+ 'process.env.NODE_ENV': JSON.stringify('production'),
332
+ }),
333
+ terser(terserOpts),
334
+ ],
335
+ external: testExternal.bind(null, externalPeerDeps, externalsExclude),
336
+ },
337
+ ]),
338
+ ];
339
+
340
+ default:
341
+ throw new Error(`Unsupported type ${type}`);
342
+ }
343
+ }
@@ -0,0 +1,87 @@
1
+ import AJV from 'ajv';
2
+ import { existsSync } from 'fs';
3
+ import { isAbsolute, relative, resolve } from 'path';
4
+ import signale from 'signale';
5
+ import slash from 'slash2';
6
+ import schema from './schema';
7
+ import { IBundleOptions } from './types';
8
+ import { getExistFile } from './utils';
9
+
10
+ function testDefault(obj) {
11
+ return obj.default || obj;
12
+ }
13
+
14
+ export const CONFIG_FILES = [
15
+ '.buildrc.js',
16
+ '.buildrc.jsx',
17
+ '.buildrc.ts',
18
+ '.buildrc.tsx',
19
+ '.fatherrc.js',
20
+ '.fatherrc.jsx',
21
+ '.fatherrc.ts',
22
+ '.fatherrc.tsx',
23
+ '.umirc.library.js',
24
+ '.umirc.library.jsx',
25
+ '.umirc.library.ts',
26
+ '.umirc.library.tsx',
27
+ ];
28
+ const CLASSES = {
29
+ Function: Function,
30
+ };
31
+ const extendAjv = (ajv: AJV.Ajv) => {
32
+ ajv.addKeyword('instanceof', {
33
+ compile: function(schema: string) {
34
+ var Class = CLASSES[schema];
35
+ return function(data: any) {
36
+ return data instanceof Class;
37
+ };
38
+ },
39
+ });
40
+ return ajv;
41
+ };
42
+ export default function({ cwd, customPath }: { cwd: string; customPath?: string }): IBundleOptions {
43
+ let finalPath = '';
44
+
45
+ if (customPath) {
46
+ finalPath = isAbsolute(customPath) ? customPath : resolve(process.cwd(), customPath);
47
+ if (!existsSync(finalPath)) {
48
+ throw new Error(`can\'t found config file: ${customPath}`);
49
+ }
50
+ }
51
+
52
+ const configFile =
53
+ finalPath ||
54
+ getExistFile({
55
+ cwd,
56
+ files: CONFIG_FILES,
57
+ returnRelative: false,
58
+ });
59
+
60
+ if (configFile) {
61
+ if (configFile.includes('.umirc.library.')) {
62
+ signale.warn(`.umirc.library.js is deprecated, please use .fatherrc.js instead.`);
63
+ }
64
+
65
+ const userConfig = testDefault(require(configFile)); // eslint-disable-line
66
+ const userConfigs = Array.isArray(userConfig) ? userConfig : [userConfig];
67
+ userConfigs.forEach((userConfig) => {
68
+ const ajv = extendAjv(new AJV({ allErrors: true }));
69
+ const isValid = ajv.validate(schema, userConfig);
70
+ if (!isValid) {
71
+ const errors = ajv.errors.map(({ dataPath, message }, index) => {
72
+ return `${index + 1}. ${dataPath}${dataPath ? ' ' : ''}${message}`;
73
+ });
74
+ throw new Error(
75
+ `
76
+ Invalid options in ${slash(relative(cwd, configFile))}
77
+
78
+ ${errors.join('\n')}
79
+ `.trim()
80
+ );
81
+ }
82
+ });
83
+ return userConfig;
84
+ } else {
85
+ return {};
86
+ }
87
+ }
@@ -0,0 +1,26 @@
1
+ import { join, dirname } from 'path';
2
+ import fs from 'fs';
3
+
4
+ const cwd = process.cwd();
5
+
6
+ function replacePath(path) {
7
+ if (path.node.source && /\/lib\//.test(path.node.source.value)) {
8
+ const esModule = path.node.source.value.replace('/lib/', '/es/');
9
+ const esPath = dirname(join(cwd, `node_modules/${esModule}`));
10
+ if (fs.existsSync(esPath)) {
11
+ console.log(`[es build] replace ${path.node.source.value} with ${esModule}`);
12
+ path.node.source.value = esModule;
13
+ }
14
+ }
15
+ }
16
+
17
+ function replaceLib() {
18
+ return {
19
+ visitor: {
20
+ ImportDeclaration: replacePath,
21
+ ExportNamedDeclaration: replacePath,
22
+ },
23
+ };
24
+ }
25
+
26
+ export default replaceLib;
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+
2
+ import build from './build';
3
+ export default build;
@@ -0,0 +1,24 @@
1
+ import { cloneDeep, merge } from 'lodash';
2
+ import { IBundleOptions } from './types';
3
+
4
+ function stripDotSlashPrefix(path) {
5
+ return path.replace(/^\.\//, '');
6
+ }
7
+
8
+ export default function(entry: string, opts: IBundleOptions): IBundleOptions {
9
+ let clone = cloneDeep(opts);
10
+ const stripedEntry = stripDotSlashPrefix(entry);
11
+ if (clone.overridesByEntry) {
12
+ Object.keys(clone.overridesByEntry).forEach(key => {
13
+ const stripedKey = stripDotSlashPrefix(key);
14
+ if (stripedKey !== key) {
15
+ clone.overridesByEntry[stripedKey] = clone.overridesByEntry[key];
16
+ }
17
+ });
18
+ if (clone.overridesByEntry[stripedEntry]) {
19
+ clone = merge(clone, clone.overridesByEntry[stripedEntry]);
20
+ }
21
+ delete clone.overridesByEntry;
22
+ }
23
+ return clone;
24
+ }
@@ -0,0 +1,34 @@
1
+ import chalk from 'chalk';
2
+
3
+ const colors = [
4
+ 'red',
5
+ 'green',
6
+ 'yellow',
7
+ 'blue',
8
+ 'magenta',
9
+ 'cyan',
10
+ 'gray',
11
+ 'redBright',
12
+ 'greenBright',
13
+ 'yellowBright',
14
+ 'blueBright',
15
+ 'magentaBright',
16
+ 'cyanBright',
17
+ ];
18
+
19
+ let index = 0;
20
+ const cache = {};
21
+
22
+ export default function (pkg) {
23
+ if (!cache[pkg]) {
24
+ const color = colors[index];
25
+ let str = chalk[color].bold(pkg);
26
+ cache[pkg] = str;
27
+ if (index === colors.length - 1) {
28
+ index = 0;
29
+ } else {
30
+ index += 1;
31
+ }
32
+ }
33
+ return cache[pkg];
34
+ }
@@ -0,0 +1,23 @@
1
+ import { join, isAbsolute } from 'path';
2
+ import slash from 'slash2';
3
+ import getBabelConfig from './getBabelConfig';
4
+
5
+ interface IRegisterBabelOpts {
6
+ cwd: string;
7
+ only: string[];
8
+ }
9
+
10
+ export default function(opts: IRegisterBabelOpts) {
11
+ const { cwd, only } = opts;
12
+ const { opts: babelConfig } = getBabelConfig({
13
+ target: 'node',
14
+ typescript: true,
15
+ });
16
+ require('@babel/register')({
17
+ ...babelConfig,
18
+ extensions: ['.es6', '.es', '.jsx', '.js', '.mjs', '.ts', '.tsx'],
19
+ only: only.map((file) => slash(isAbsolute(file) ? file : join(cwd, file))),
20
+ babelrc: false,
21
+ cache: false,
22
+ });
23
+ }
package/src/rollup.ts ADDED
@@ -0,0 +1,77 @@
1
+ import { ModuleFormat, rollup, watch } from 'rollup';
2
+ import signale from 'signale';
3
+ import chalk from 'chalk';
4
+ import getRollupConfig from './getRollupConfig';
5
+ import { Dispose, IBundleOptions } from './types';
6
+ import normalizeBundleOpts from './normalizeBundleOpts';
7
+
8
+ interface IRollupOpts {
9
+ cwd: string;
10
+ rootPath?: string;
11
+ entry: string | string[];
12
+ type: ModuleFormat;
13
+ log: (string) => void;
14
+ bundleOpts: IBundleOptions;
15
+ watch?: boolean;
16
+ dispose?: Dispose[];
17
+ importLibToEs?: boolean;
18
+ }
19
+
20
+ async function build(entry: string, opts: IRollupOpts) {
21
+ const { cwd, rootPath, type, log, bundleOpts, importLibToEs, dispose } = opts;
22
+ const rollupConfigs = getRollupConfig({
23
+ cwd,
24
+ rootPath:rootPath || cwd,
25
+ type,
26
+ entry,
27
+ importLibToEs,
28
+ bundleOpts: normalizeBundleOpts(entry, bundleOpts),
29
+ });
30
+
31
+ for (const rollupConfig of rollupConfigs) {
32
+ if (opts.watch) {
33
+ const watcher = watch([
34
+ {
35
+ ...rollupConfig,
36
+ watch: {},
37
+ },
38
+ ]);
39
+ await (new Promise<void>((resolve) => {
40
+ watcher.on('event', (event) => {
41
+ // 每次构建完成都会触发 BUNDLE_END 事件
42
+ // 当第一次构建完成或出错就 resolve
43
+ if (event.code === 'ERROR') {
44
+ signale.error(event.error);
45
+ resolve();
46
+ } else if (event.code === 'BUNDLE_END') {
47
+ log(`${chalk.green(`Build ${type} success`)} ${chalk.gray(`entry: ${entry}`)}`);
48
+ resolve();
49
+ }
50
+ });
51
+ }));
52
+ process.once('SIGINT', () => {
53
+ watcher.close();
54
+ });
55
+ dispose?.push(() => watcher.close());
56
+ } else {
57
+ const { output, ...input } = rollupConfig;
58
+ const bundle = await rollup(input); // eslint-disable-line
59
+ await bundle.write(output); // eslint-disable-line
60
+ log(`${chalk.green(`Build ${type} success`)} ${chalk.gray(`entry: ${entry}`)}`);
61
+ }
62
+ }
63
+ }
64
+
65
+ export default async function(opts: IRollupOpts) {
66
+ if (Array.isArray(opts.entry)) {
67
+ const { entry: entries } = opts;
68
+ for (const entry of entries) {
69
+ await build(entry, opts);
70
+ }
71
+ } else {
72
+ await build(opts.entry, opts);
73
+ }
74
+ if (opts.watch) {
75
+ opts.log(chalk.magentaBright(`Rebuild ${opts.type} since file changed 👀`));
76
+ }
77
+ }