rolldown 1.0.0-beta.1-commit.7c52c94 → 1.0.0-beta.2-commit.f069c5d

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 (114) hide show
  1. package/dist/cjs/cli.cjs +981 -25
  2. package/dist/cjs/experimental-index.cjs +2 -2
  3. package/dist/cjs/index.cjs +2 -2
  4. package/dist/cjs/parallel-plugin-worker.cjs +2 -2
  5. package/dist/cjs/parse-ast-index.cjs +1 -1
  6. package/dist/esm/cli.mjs +981 -26
  7. package/dist/esm/experimental-index.mjs +2 -2
  8. package/dist/esm/index.mjs +2 -2
  9. package/dist/esm/parallel-plugin-worker.mjs +2 -2
  10. package/dist/esm/parse-ast-index.mjs +1 -1
  11. package/dist/shared/{binding-Bl7VQy7c.mjs → binding-l7VLSKnB.mjs} +3 -3
  12. package/dist/shared/{binding-fhgdIkpS.cjs → binding-orkvONpS.cjs} +3 -3
  13. package/dist/shared/prompt-B7tq3GL9.cjs +854 -0
  14. package/dist/shared/prompt-Nfm4Xz36.mjs +851 -0
  15. package/dist/shared/{src-lBcHSsjm.cjs → src-BRzD1T3r.cjs} +12 -6
  16. package/dist/shared/{src-CPCP99Z9.mjs → src-Cmr3pg11.mjs} +12 -6
  17. package/dist/types/api/build.js +22 -0
  18. package/dist/types/api/experimental.js +13 -0
  19. package/dist/types/api/rolldown/index.js +7 -0
  20. package/dist/types/api/rolldown/rolldown-build.js +43 -0
  21. package/dist/types/api/watch/index.js +8 -0
  22. package/dist/types/api/watch/watch-emitter.js +69 -0
  23. package/dist/types/api/watch/watcher.js +66 -0
  24. package/dist/types/binding.d.ts +40 -2
  25. package/dist/types/builtin-plugin/alias-plugin.js +4 -0
  26. package/dist/types/builtin-plugin/constructors.d.ts +2 -2
  27. package/dist/types/builtin-plugin/constructors.js +68 -0
  28. package/dist/types/builtin-plugin/replace-plugin.js +29 -0
  29. package/dist/types/builtin-plugin/transform-plugin.js +16 -0
  30. package/dist/types/builtin-plugin/utils.js +19 -0
  31. package/dist/types/cli/arguments/alias.js +63 -0
  32. package/dist/types/cli/arguments/index.js +127 -0
  33. package/dist/types/cli/arguments/normalize.js +48 -0
  34. package/dist/types/cli/arguments/utils.js +67 -0
  35. package/dist/types/cli/colors.js +17 -0
  36. package/dist/types/cli/commands/bundle.js +203 -0
  37. package/dist/types/cli/commands/help.js +88 -0
  38. package/dist/types/cli/index.js +27 -0
  39. package/dist/types/cli/load-config.js +95 -0
  40. package/dist/types/cli/logger.js +35 -0
  41. package/dist/types/constants/plugin-context.js +7 -0
  42. package/dist/types/constants/plugin.js +69 -0
  43. package/dist/types/experimental-index.js +9 -0
  44. package/dist/types/index.d.ts +2 -2
  45. package/dist/types/index.js +7 -0
  46. package/dist/types/log/logHandler.js +25 -0
  47. package/dist/types/log/logger.js +107 -0
  48. package/dist/types/log/logging.js +11 -0
  49. package/dist/types/log/logs.js +86 -0
  50. package/dist/types/options/input-options.d.ts +47 -2
  51. package/dist/types/options/input-options.js +1 -0
  52. package/dist/types/options/normalized-input-options.js +21 -0
  53. package/dist/types/options/normalized-output-options.js +99 -0
  54. package/dist/types/options/output-options.d.ts +6 -0
  55. package/dist/types/options/output-options.js +1 -0
  56. package/dist/types/options/watch-options.js +1 -0
  57. package/dist/types/parallel-plugin-worker.js +31 -0
  58. package/dist/types/parallel-plugin.js +1 -0
  59. package/dist/types/parse-ast-index.js +73 -0
  60. package/dist/types/plugin/bindingify-build-hooks.js +213 -0
  61. package/dist/types/plugin/bindingify-hook-filter.js +39 -0
  62. package/dist/types/plugin/bindingify-output-hooks.js +189 -0
  63. package/dist/types/plugin/bindingify-plugin-hook-meta.js +19 -0
  64. package/dist/types/plugin/bindingify-plugin.js +124 -0
  65. package/dist/types/plugin/bindingify-watch-hooks.js +29 -0
  66. package/dist/types/plugin/hook-filter.js +1 -0
  67. package/dist/types/plugin/index.js +1 -0
  68. package/dist/types/plugin/minimal-plugin-context.js +25 -0
  69. package/dist/types/plugin/parallel-plugin-implementation.js +3 -0
  70. package/dist/types/plugin/parallel-plugin.js +6 -0
  71. package/dist/types/plugin/plugin-context-data.js +55 -0
  72. package/dist/types/plugin/plugin-context.js +108 -0
  73. package/dist/types/plugin/plugin-driver.js +88 -0
  74. package/dist/types/plugin/transform-plugin-context.js +37 -0
  75. package/dist/types/types/assert.js +1 -0
  76. package/dist/types/types/config-export.js +1 -0
  77. package/dist/types/types/misc.js +1 -0
  78. package/dist/types/types/module-info.js +1 -0
  79. package/dist/types/types/module-side-effects.js +1 -0
  80. package/dist/types/types/output-bundle.js +1 -0
  81. package/dist/types/types/rolldown-options.js +1 -0
  82. package/dist/types/types/rolldown-output.js +1 -0
  83. package/dist/types/types/schema.js +1 -0
  84. package/dist/types/types/sourcemap.js +16 -0
  85. package/dist/types/types/utils.js +1 -0
  86. package/dist/types/utils/asset-source.js +8 -0
  87. package/dist/types/utils/async-flatten.js +7 -0
  88. package/dist/types/utils/bindingify-input-options.js +225 -0
  89. package/dist/types/utils/bindingify-output-options.js +92 -0
  90. package/dist/types/utils/code-frame.js +46 -0
  91. package/dist/types/utils/compose-js-plugins.js +400 -0
  92. package/dist/types/utils/create-bundler-option.js +53 -0
  93. package/dist/types/utils/create-bundler.js +15 -0
  94. package/dist/types/utils/define-config.js +3 -0
  95. package/dist/types/utils/error.js +65 -0
  96. package/dist/types/utils/initialize-parallel-plugins.js +54 -0
  97. package/dist/types/utils/misc.js +22 -0
  98. package/dist/types/utils/normalize-hook.js +21 -0
  99. package/dist/types/utils/normalize-plugin-option.js +35 -0
  100. package/dist/types/utils/normalize-string-or-regex.js +14 -0
  101. package/dist/types/utils/plugin/index.js +7 -0
  102. package/dist/types/utils/transform-module-info.js +19 -0
  103. package/dist/types/utils/transform-rendered-chunk.js +43 -0
  104. package/dist/types/utils/transform-rendered-module.js +10 -0
  105. package/dist/types/utils/transform-side-effects.js +16 -0
  106. package/dist/types/utils/transform-sourcemap.js +29 -0
  107. package/dist/types/utils/transform-to-rollup-output.js +165 -0
  108. package/dist/types/utils/validator.js +275 -0
  109. package/package.json +28 -25
  110. package/dist/shared/consola_36c0034f-Cx52UqEq.mjs +0 -832
  111. package/dist/shared/consola_36c0034f-CynBWXXO.cjs +0 -859
  112. package/dist/shared/prompt-B58MxVuU.cjs +0 -762
  113. package/dist/shared/prompt-DjjlOckE.mjs +0 -758
  114. package/dist/tsconfig.dts.tsbuildinfo +0 -1
@@ -0,0 +1,92 @@
1
+ import { unimplemented } from './misc';
2
+ import { transformRenderedChunk } from './transform-rendered-chunk';
3
+ export function bindingifyOutputOptions(outputOptions) {
4
+ const { dir, format, exports, hashCharacters, sourcemap, sourcemapIgnoreList, sourcemapPathTransform, name, assetFileNames, entryFileNames, chunkFileNames, cssEntryFileNames, cssChunkFileNames, banner, footer, intro, outro, esModule, globals, file, } = outputOptions;
5
+ return {
6
+ dir,
7
+ // Handle case: rollup/test/sourcemaps/samples/sourcemap-file-hashed/_config.js
8
+ file: file == null ? undefined : file,
9
+ format: bindingifyFormat(format),
10
+ exports,
11
+ hashCharacters,
12
+ sourcemap: bindingifySourcemap(sourcemap),
13
+ sourcemapIgnoreList: bindingifySourcemapIgnoreList(sourcemapIgnoreList),
14
+ sourcemapPathTransform,
15
+ banner: bindingifyAddon(banner),
16
+ footer: bindingifyAddon(footer),
17
+ intro: bindingifyAddon(intro),
18
+ outro: bindingifyAddon(outro),
19
+ extend: outputOptions.extend,
20
+ globals,
21
+ esModule,
22
+ name,
23
+ assetFileNames,
24
+ entryFileNames,
25
+ chunkFileNames,
26
+ cssEntryFileNames,
27
+ cssChunkFileNames,
28
+ // TODO(sapphi-red): support parallel plugins
29
+ plugins: [],
30
+ minify: outputOptions.minify,
31
+ externalLiveBindings: outputOptions.externalLiveBindings,
32
+ inlineDynamicImports: outputOptions.inlineDynamicImports,
33
+ advancedChunks: outputOptions.advancedChunks,
34
+ polyfillRequire: outputOptions.polyfillRequire,
35
+ target: outputOptions.target,
36
+ };
37
+ }
38
+ function bindingifyAddon(configAddon) {
39
+ return async (chunk) => {
40
+ if (typeof configAddon === 'function') {
41
+ return configAddon(transformRenderedChunk(chunk));
42
+ }
43
+ return configAddon || '';
44
+ };
45
+ }
46
+ function bindingifyFormat(format) {
47
+ switch (format) {
48
+ case undefined:
49
+ case 'es':
50
+ case 'esm':
51
+ case 'module': {
52
+ return 'es';
53
+ }
54
+ case 'cjs':
55
+ case 'commonjs': {
56
+ return 'cjs';
57
+ }
58
+ case 'iife': {
59
+ return 'iife';
60
+ }
61
+ case 'umd': {
62
+ return 'umd';
63
+ }
64
+ case 'experimental-app': {
65
+ return 'app';
66
+ }
67
+ default:
68
+ unimplemented(`output.format: ${format}`);
69
+ }
70
+ }
71
+ function bindingifySourcemap(sourcemap) {
72
+ switch (sourcemap) {
73
+ case true:
74
+ return 'file';
75
+ case 'inline':
76
+ return 'inline';
77
+ case false:
78
+ case undefined:
79
+ return undefined;
80
+ case 'hidden':
81
+ return 'hidden';
82
+ default:
83
+ throw new Error(`unknown sourcemap: ${sourcemap}`);
84
+ }
85
+ }
86
+ function bindingifySourcemapIgnoreList(sourcemapIgnoreList) {
87
+ return typeof sourcemapIgnoreList === 'function'
88
+ ? sourcemapIgnoreList
89
+ : sourcemapIgnoreList === false
90
+ ? () => false
91
+ : (relativeSourcePath, _sourcemapPath) => relativeSourcePath.includes('node_modules');
92
+ }
@@ -0,0 +1,46 @@
1
+ function spaces(index) {
2
+ let result = '';
3
+ while (index--)
4
+ result += ' ';
5
+ return result;
6
+ }
7
+ function tabsToSpaces(value) {
8
+ return value.replace(/^\t+/, (match) => match.split('\t').join(' '));
9
+ }
10
+ const LINE_TRUNCATE_LENGTH = 120;
11
+ const MIN_CHARACTERS_SHOWN_AFTER_LOCATION = 10;
12
+ const ELLIPSIS = '...';
13
+ export function getCodeFrame(source, line, column) {
14
+ let lines = source.split('\n');
15
+ // Needed if a plugin did not generate correct sourcemaps
16
+ if (line > lines.length)
17
+ return '';
18
+ const maxLineLength = Math.max(tabsToSpaces(lines[line - 1].slice(0, column)).length +
19
+ MIN_CHARACTERS_SHOWN_AFTER_LOCATION +
20
+ ELLIPSIS.length, LINE_TRUNCATE_LENGTH);
21
+ const frameStart = Math.max(0, line - 3);
22
+ let frameEnd = Math.min(line + 2, lines.length);
23
+ lines = lines.slice(frameStart, frameEnd);
24
+ while (!/\S/.test(lines[lines.length - 1])) {
25
+ lines.pop();
26
+ frameEnd -= 1;
27
+ }
28
+ const digits = String(frameEnd).length;
29
+ return lines
30
+ .map((sourceLine, index) => {
31
+ const isErrorLine = frameStart + index + 1 === line;
32
+ let lineNumber = String(index + frameStart + 1);
33
+ while (lineNumber.length < digits)
34
+ lineNumber = ` ${lineNumber}`;
35
+ let displayedLine = tabsToSpaces(sourceLine);
36
+ if (displayedLine.length > maxLineLength) {
37
+ displayedLine = `${displayedLine.slice(0, maxLineLength - ELLIPSIS.length)}${ELLIPSIS}`;
38
+ }
39
+ if (isErrorLine) {
40
+ const indicator = spaces(digits + 2 + tabsToSpaces(sourceLine.slice(0, column)).length) + '^';
41
+ return `${lineNumber}: ${displayedLine}\n${indicator}`;
42
+ }
43
+ return `${lineNumber}: ${displayedLine}`;
44
+ })
45
+ .join('\n');
46
+ }
@@ -0,0 +1,400 @@
1
+ import { normalizeHook } from './normalize-hook';
2
+ import { isNullish } from './misc';
3
+ import { BuiltinPlugin } from '../builtin-plugin/constructors';
4
+ import * as R from 'remeda';
5
+ import { SYMBOL_FOR_RESOLVE_CALLER_THAT_SKIP_SELF } from '../constants/plugin-context';
6
+ import { isPluginHookName } from './plugin';
7
+ const unsupportedHookName = [
8
+ 'augmentChunkHash',
9
+ 'generateBundle',
10
+ 'moduleParsed',
11
+ 'onLog',
12
+ 'options',
13
+ 'outputOptions',
14
+ 'renderError',
15
+ 'renderStart',
16
+ 'resolveDynamicImport',
17
+ 'writeBundle',
18
+ ];
19
+ const unsupportedHooks = new Set(unsupportedHookName);
20
+ function isUnsupportedHooks(hookName) {
21
+ return unsupportedHooks.has(hookName);
22
+ }
23
+ function createComposedPlugin(plugins) {
24
+ // Throw errors if we try to merge plugins with unsupported hooks
25
+ const names = [];
26
+ const batchedHooks = {};
27
+ plugins.forEach((plugin, index) => {
28
+ const pluginName = plugin.name || `Anonymous(index: ${index})`;
29
+ names.push(pluginName);
30
+ R.keys(plugin).forEach((pluginProp) => {
31
+ if (isUnsupportedHooks(pluginProp)) {
32
+ throw new Error(`Failed to compose js plugins. Plugin ${pluginName} has an unsupported hook: ${pluginProp}`);
33
+ }
34
+ if (!isPluginHookName(pluginProp)) {
35
+ // Not hooks. Just ignore these properties
36
+ return;
37
+ }
38
+ switch (pluginProp) {
39
+ case 'buildStart': {
40
+ const handlers = batchedHooks.buildStart ?? [];
41
+ batchedHooks.buildStart = handlers;
42
+ if (plugin.buildStart) {
43
+ handlers.push([plugin.buildStart, plugin]);
44
+ }
45
+ break;
46
+ }
47
+ case 'load': {
48
+ const handlers = batchedHooks.load ?? [];
49
+ batchedHooks.load = handlers;
50
+ if (plugin.load) {
51
+ handlers.push([plugin.load, plugin]);
52
+ }
53
+ break;
54
+ }
55
+ case 'transform': {
56
+ const handlers = batchedHooks.transform ?? [];
57
+ batchedHooks.transform = handlers;
58
+ if (plugin.transform) {
59
+ handlers.push([plugin.transform, plugin]);
60
+ }
61
+ break;
62
+ }
63
+ case 'resolveId': {
64
+ const handlers = batchedHooks.resolveId ?? [];
65
+ batchedHooks.resolveId = handlers;
66
+ if (plugin.resolveId) {
67
+ handlers.push([plugin.resolveId, plugin]);
68
+ }
69
+ break;
70
+ }
71
+ case 'buildEnd': {
72
+ const handlers = batchedHooks.buildEnd ?? [];
73
+ batchedHooks.buildEnd = handlers;
74
+ if (plugin.buildEnd) {
75
+ handlers.push([plugin.buildEnd, plugin]);
76
+ }
77
+ break;
78
+ }
79
+ case 'renderChunk': {
80
+ const handlers = batchedHooks.renderChunk ?? [];
81
+ batchedHooks.renderChunk = handlers;
82
+ if (plugin.renderChunk) {
83
+ handlers.push([plugin.renderChunk, plugin]);
84
+ }
85
+ break;
86
+ }
87
+ case 'banner':
88
+ case 'footer':
89
+ case 'intro':
90
+ case 'outro': {
91
+ const hook = plugin[pluginProp];
92
+ if (hook) {
93
+ ;
94
+ (batchedHooks[pluginProp] ??= []).push([hook, plugin]);
95
+ }
96
+ break;
97
+ }
98
+ case 'closeBundle': {
99
+ const handlers = batchedHooks.closeBundle ?? [];
100
+ batchedHooks.closeBundle = handlers;
101
+ if (plugin.closeBundle) {
102
+ handlers.push([plugin.closeBundle, plugin]);
103
+ }
104
+ break;
105
+ }
106
+ case 'watchChange': {
107
+ const handlers = batchedHooks.watchChange ?? [];
108
+ batchedHooks.watchChange = handlers;
109
+ if (plugin.watchChange) {
110
+ handlers.push([plugin.watchChange, plugin]);
111
+ }
112
+ break;
113
+ }
114
+ case 'closeWatcher': {
115
+ const handlers = batchedHooks.closeWatcher ?? [];
116
+ batchedHooks.closeWatcher = handlers;
117
+ if (plugin.closeWatcher) {
118
+ handlers.push([plugin.closeWatcher, plugin]);
119
+ }
120
+ break;
121
+ }
122
+ default: {
123
+ }
124
+ }
125
+ });
126
+ });
127
+ const composed = {
128
+ name: `Composed(${names.join(', ')})`,
129
+ };
130
+ const createFixedPluginResolveFnMap = new Map();
131
+ function applyFixedPluginResolveFn(ctx, plugin) {
132
+ const createFixedPluginResolveFn = createFixedPluginResolveFnMap.get(plugin);
133
+ if (createFixedPluginResolveFn) {
134
+ ctx.resolve = createFixedPluginResolveFn(ctx, ctx.resolve.bind(ctx));
135
+ }
136
+ return ctx;
137
+ }
138
+ if (batchedHooks.resolveId) {
139
+ const batchedHandlers = batchedHooks.resolveId;
140
+ const handlerSymbols = batchedHandlers.map(([_handler, plugin]) => Symbol(plugin.name ?? `Anonymous`));
141
+ for (let handlerIdx = 0; handlerIdx < batchedHandlers.length; handlerIdx++) {
142
+ const [_handler, plugin] = batchedHandlers[handlerIdx];
143
+ const handlerSymbol = handlerSymbols[handlerIdx];
144
+ const createFixedPluginResolveFn = (ctx, resolve) => {
145
+ return (source, importer, rawContextResolveOptions) => {
146
+ const contextResolveOptions = rawContextResolveOptions ?? {};
147
+ if (contextResolveOptions.skipSelf) {
148
+ contextResolveOptions[SYMBOL_FOR_RESOLVE_CALLER_THAT_SKIP_SELF] =
149
+ handlerSymbol;
150
+ contextResolveOptions.skipSelf = false;
151
+ }
152
+ return resolve(source, importer, contextResolveOptions);
153
+ };
154
+ };
155
+ createFixedPluginResolveFnMap.set(plugin, createFixedPluginResolveFn);
156
+ }
157
+ composed.resolveId = async function (source, importer, rawHookResolveIdOptions) {
158
+ const hookResolveIdOptions = rawHookResolveIdOptions;
159
+ const symbolForCallerThatSkipSelf = hookResolveIdOptions?.[SYMBOL_FOR_RESOLVE_CALLER_THAT_SKIP_SELF];
160
+ for (let handlerIdx = 0; handlerIdx < batchedHandlers.length; handlerIdx++) {
161
+ const [handler, plugin] = batchedHandlers[handlerIdx];
162
+ const handlerSymbol = handlerSymbols[handlerIdx];
163
+ if (symbolForCallerThatSkipSelf === handlerSymbol) {
164
+ continue;
165
+ }
166
+ const { handler: handlerFn } = normalizeHook(handler);
167
+ const result = await handlerFn.call(applyFixedPluginResolveFn(this, plugin), source, importer, rawHookResolveIdOptions);
168
+ if (!isNullish(result)) {
169
+ return result;
170
+ }
171
+ }
172
+ };
173
+ }
174
+ R.keys(batchedHooks).forEach((hookName) => {
175
+ switch (hookName) {
176
+ case 'resolveId': {
177
+ // It's handled above
178
+ break;
179
+ }
180
+ case 'buildStart': {
181
+ if (batchedHooks.buildStart) {
182
+ const batchedHandlers = batchedHooks.buildStart;
183
+ composed.buildStart = async function (options) {
184
+ await Promise.all(batchedHandlers.map(([handler, plugin]) => {
185
+ const { handler: handlerFn } = normalizeHook(handler);
186
+ return handlerFn.call(applyFixedPluginResolveFn(this, plugin), options);
187
+ }));
188
+ };
189
+ }
190
+ break;
191
+ }
192
+ case 'load': {
193
+ if (batchedHooks.load) {
194
+ const batchedHandlers = batchedHooks.load;
195
+ composed.load = async function (id) {
196
+ for (const [handler, plugin] of batchedHandlers) {
197
+ const { handler: handlerFn } = normalizeHook(handler);
198
+ const result = await handlerFn.call(applyFixedPluginResolveFn(this, plugin), id);
199
+ if (!isNullish(result)) {
200
+ return result;
201
+ }
202
+ }
203
+ };
204
+ }
205
+ break;
206
+ }
207
+ case 'transform': {
208
+ if (batchedHooks.transform) {
209
+ const batchedHandlers = batchedHooks.transform;
210
+ composed.transform = async function (initialCode, id, moduleType) {
211
+ let code = initialCode;
212
+ let moduleSideEffects = undefined;
213
+ // TODO: we should deal with the returned sourcemap too.
214
+ function updateOutput(newCode, newModuleSideEffects) {
215
+ code = newCode;
216
+ moduleSideEffects = newModuleSideEffects ?? undefined;
217
+ }
218
+ for (const [handler, plugin] of batchedHandlers) {
219
+ const { handler: handlerFn } = normalizeHook(handler);
220
+ this.getCombinedSourcemap = () => {
221
+ throw new Error(`The getCombinedSourcemap is not implement in transform hook at composedJsPlugins`);
222
+ };
223
+ const result = await handlerFn.call(applyFixedPluginResolveFn(this, plugin), code, id, moduleType);
224
+ if (!isNullish(result)) {
225
+ if (typeof result === 'string') {
226
+ updateOutput(result);
227
+ }
228
+ else {
229
+ if (result.code) {
230
+ updateOutput(result.code, result.moduleSideEffects);
231
+ }
232
+ }
233
+ }
234
+ }
235
+ return {
236
+ code,
237
+ moduleSideEffects,
238
+ };
239
+ };
240
+ }
241
+ break;
242
+ }
243
+ case 'buildEnd': {
244
+ if (batchedHooks.buildEnd) {
245
+ const batchedHandlers = batchedHooks.buildEnd;
246
+ composed.buildEnd = async function (err) {
247
+ await Promise.all(batchedHandlers.map(([handler, plugin]) => {
248
+ const { handler: handlerFn } = normalizeHook(handler);
249
+ return handlerFn.call(applyFixedPluginResolveFn(this, plugin), err);
250
+ }));
251
+ };
252
+ }
253
+ break;
254
+ }
255
+ case 'renderChunk': {
256
+ if (batchedHooks.renderChunk) {
257
+ const batchedHandlers = batchedHooks.renderChunk;
258
+ composed.renderChunk = async function (code, chunk, options) {
259
+ for (const [handler, plugin] of batchedHandlers) {
260
+ const { handler: handlerFn } = normalizeHook(handler);
261
+ const result = await handlerFn.call(applyFixedPluginResolveFn(this, plugin), code, chunk, options);
262
+ if (!isNullish(result)) {
263
+ return result;
264
+ }
265
+ }
266
+ };
267
+ }
268
+ break;
269
+ }
270
+ case 'banner':
271
+ case 'footer':
272
+ case 'intro':
273
+ case 'outro': {
274
+ const hooks = batchedHooks[hookName];
275
+ if (hooks?.length) {
276
+ composed[hookName] = async function (chunk) {
277
+ const ret = [];
278
+ for (const [hook, plugin] of hooks) {
279
+ {
280
+ const { handler } = normalizeHook(hook);
281
+ ret.push(typeof handler === 'string'
282
+ ? handler
283
+ : await handler.call(applyFixedPluginResolveFn(this, plugin), chunk));
284
+ }
285
+ }
286
+ return ret.join('\n');
287
+ };
288
+ }
289
+ break;
290
+ }
291
+ case 'closeBundle': {
292
+ if (batchedHooks.closeBundle) {
293
+ const batchedHandlers = batchedHooks.closeBundle;
294
+ composed.closeBundle = async function () {
295
+ await Promise.all(batchedHandlers.map(([handler, plugin]) => {
296
+ const { handler: handlerFn } = normalizeHook(handler);
297
+ return handlerFn.call(applyFixedPluginResolveFn(this, plugin));
298
+ }));
299
+ };
300
+ }
301
+ break;
302
+ }
303
+ case 'watchChange': {
304
+ if (batchedHooks.watchChange) {
305
+ const batchedHandlers = batchedHooks.watchChange;
306
+ composed.watchChange = async function (id, event) {
307
+ await Promise.all(batchedHandlers.map(([handler, plugin]) => {
308
+ const { handler: handlerFn } = normalizeHook(handler);
309
+ return handlerFn.call(applyFixedPluginResolveFn(this, plugin), id, event);
310
+ }));
311
+ };
312
+ }
313
+ break;
314
+ }
315
+ case 'closeWatcher': {
316
+ if (batchedHooks.closeWatcher) {
317
+ const batchedHandlers = batchedHooks.closeWatcher;
318
+ composed.closeWatcher = async function () {
319
+ await Promise.all(batchedHandlers.map(([handler, plugin]) => {
320
+ const { handler: handlerFn } = normalizeHook(handler);
321
+ return handlerFn.call(applyFixedPluginResolveFn(this, plugin));
322
+ }));
323
+ };
324
+ }
325
+ break;
326
+ }
327
+ default: {
328
+ }
329
+ }
330
+ });
331
+ return composed;
332
+ }
333
+ function isComposablePlugin(plugin) {
334
+ if (plugin instanceof BuiltinPlugin) {
335
+ return false;
336
+ }
337
+ if ('_parallel' in plugin) {
338
+ return false;
339
+ }
340
+ // Check if the plugin has patterns that aren't composable
341
+ const hasNotComposablePattern = R.keys(plugin).some((hookName) => {
342
+ if (!isPluginHookName(hookName)) {
343
+ // Not hooks. Just ignore these properties since they don't affect the composable pattern
344
+ return false;
345
+ }
346
+ const OK_TO_COMPOSE = false;
347
+ if (isUnsupportedHooks(hookName)) {
348
+ return !OK_TO_COMPOSE;
349
+ }
350
+ if (plugin[hookName]) {
351
+ const { meta } = normalizeHook(plugin[hookName]);
352
+ // if `order` is specified with `pre` or `post`, it's unsafe to compose this plugin
353
+ if (meta.order === 'pre' || meta.order === 'post') {
354
+ return !OK_TO_COMPOSE;
355
+ }
356
+ }
357
+ return OK_TO_COMPOSE;
358
+ });
359
+ if (hasNotComposablePattern) {
360
+ return false;
361
+ }
362
+ return true;
363
+ }
364
+ export function composeJsPlugins(plugins) {
365
+ const newPlugins = [];
366
+ const toBeComposed = [];
367
+ plugins.forEach((plugin) => {
368
+ if (isComposablePlugin(plugin)) {
369
+ toBeComposed.push(plugin);
370
+ }
371
+ else {
372
+ if (toBeComposed.length > 0) {
373
+ if (toBeComposed.length > 1) {
374
+ newPlugins.push(createComposedPlugin(toBeComposed));
375
+ }
376
+ else {
377
+ // push the only plugin in toBeComposed
378
+ newPlugins.push(toBeComposed[0]);
379
+ }
380
+ toBeComposed.length = 0;
381
+ }
382
+ // push the plugin that is not composable
383
+ newPlugins.push(plugin);
384
+ }
385
+ });
386
+ // Considering the case:
387
+ // p = [c, c, c, c]
388
+ // after the loop, toBeComposed = [c, c, c, c], plugins = []
389
+ // we should consume all the toBeComposed plugins at the end
390
+ if (toBeComposed.length > 0) {
391
+ if (toBeComposed.length > 1) {
392
+ newPlugins.push(createComposedPlugin(toBeComposed));
393
+ }
394
+ else {
395
+ newPlugins.push(toBeComposed[0]);
396
+ }
397
+ toBeComposed.length = 0;
398
+ }
399
+ return newPlugins;
400
+ }
@@ -0,0 +1,53 @@
1
+ import { PluginDriver } from '../plugin/plugin-driver';
2
+ import { bindingifyInputOptions } from './bindingify-input-options';
3
+ import { bindingifyOutputOptions } from './bindingify-output-options';
4
+ import { composeJsPlugins } from './compose-js-plugins';
5
+ import { ANONYMOUS_OUTPUT_PLUGIN_PREFIX, ANONYMOUS_PLUGIN_PREFIX, checkOutputPluginOption, normalizePluginOption, normalizePlugins, } from './normalize-plugin-option';
6
+ import { initializeParallelPlugins } from './initialize-parallel-plugins';
7
+ import { getObjectPlugins } from '../plugin/plugin-driver';
8
+ import { logMinifyWarning } from '../log/logs';
9
+ import { getLogger, getOnLog } from '../log/logger';
10
+ import { validateTreeShakingOptions } from './validator';
11
+ import { LOG_LEVEL_INFO, LOG_LEVEL_WARN } from '../log/logging';
12
+ export async function createBundlerOptions(inputOptions, outputOptions) {
13
+ if (inputOptions.treeshake !== undefined) {
14
+ validateTreeShakingOptions(inputOptions.treeshake);
15
+ }
16
+ const inputPlugins = await normalizePluginOption(inputOptions.plugins);
17
+ const outputPlugins = await normalizePluginOption(outputOptions.plugins);
18
+ const logLevel = inputOptions.logLevel || LOG_LEVEL_INFO;
19
+ const onLog = getLogger(getObjectPlugins(inputPlugins), getOnLog(inputOptions, logLevel), logLevel);
20
+ // The `outputOptions` hook is called with the input plugins and the output plugins
21
+ outputOptions = PluginDriver.callOutputOptionsHook([...inputPlugins, ...outputPlugins], outputOptions);
22
+ if (outputOptions.minify === true) {
23
+ onLog(LOG_LEVEL_WARN, logMinifyWarning());
24
+ }
25
+ let plugins = [
26
+ ...normalizePlugins(inputPlugins, ANONYMOUS_PLUGIN_PREFIX),
27
+ ...checkOutputPluginOption(normalizePlugins(await normalizePluginOption(outputOptions.plugins), ANONYMOUS_OUTPUT_PLUGIN_PREFIX), onLog),
28
+ ];
29
+ if (inputOptions.experimental?.enableComposingJsPlugins ?? false) {
30
+ plugins = composeJsPlugins(plugins);
31
+ }
32
+ const parallelPluginInitResult = await initializeParallelPlugins(plugins);
33
+ try {
34
+ // Convert `InputOptions` to `BindingInputOptions`
35
+ const bindingInputOptions = bindingifyInputOptions(plugins, inputOptions, outputOptions, onLog, logLevel);
36
+ // Convert `OutputOptions` to `BindingInputOptions`
37
+ const bindingOutputOptions = bindingifyOutputOptions(outputOptions);
38
+ return {
39
+ bundlerOptions: {
40
+ inputOptions: bindingInputOptions,
41
+ outputOptions: bindingOutputOptions,
42
+ parallelPluginsRegistry: parallelPluginInitResult?.registry,
43
+ },
44
+ inputOptions,
45
+ onLog,
46
+ stopWorkers: parallelPluginInitResult?.stopWorkers,
47
+ };
48
+ }
49
+ catch (e) {
50
+ await parallelPluginInitResult?.stopWorkers();
51
+ throw e;
52
+ }
53
+ }
@@ -0,0 +1,15 @@
1
+ import { Bundler } from '../binding';
2
+ import { createBundlerOptions } from './create-bundler-option';
3
+ export async function createBundler(inputOptions, outputOptions) {
4
+ const option = await createBundlerOptions(inputOptions, outputOptions);
5
+ try {
6
+ return {
7
+ bundler: new Bundler(option.bundlerOptions),
8
+ stopWorkers: option.stopWorkers,
9
+ };
10
+ }
11
+ catch (e) {
12
+ await option.stopWorkers?.();
13
+ throw e;
14
+ }
15
+ }
@@ -0,0 +1,3 @@
1
+ export function defineConfig(config) {
2
+ return config;
3
+ }
@@ -0,0 +1,65 @@
1
+ export function normalizeErrors(rawErrors) {
2
+ const errors = rawErrors.map((e) => e instanceof Error
3
+ ? e
4
+ : // strip stacktrace of errors from native diagnostics
5
+ Object.assign(new Error(), {
6
+ kind: e.kind,
7
+ message: e.message,
8
+ stack: undefined,
9
+ }));
10
+ // based on https://github.com/evanw/esbuild/blob/9eca46464ed5615cb36a3beb3f7a7b9a8ffbe7cf/lib/shared/common.ts#L1673
11
+ // combine error messages as a top level error
12
+ let summary = `Build failed with ${errors.length} error${errors.length < 2 ? '' : 's'}:\n`;
13
+ for (let i = 0; i < errors.length; i++) {
14
+ if (i >= 5) {
15
+ summary += '\n...';
16
+ break;
17
+ }
18
+ summary += getErrorMessage(errors[i]) + '\n';
19
+ }
20
+ const wrapper = new Error(summary);
21
+ // expose individual errors as getters so that
22
+ // `console.error(wrapper)` doesn't expand unnecessary details
23
+ // when they are already presented in `wrapper.message`
24
+ Object.defineProperty(wrapper, 'errors', {
25
+ configurable: true,
26
+ enumerable: true,
27
+ get: () => errors,
28
+ set: (value) => Object.defineProperty(wrapper, 'errors', {
29
+ configurable: true,
30
+ enumerable: true,
31
+ value,
32
+ }),
33
+ });
34
+ return wrapper;
35
+ }
36
+ function getErrorMessage(e) {
37
+ let s = '';
38
+ if (e.plugin) {
39
+ s += `[plugin ${e.plugin}]`;
40
+ }
41
+ const id = e.id ?? e.loc?.file;
42
+ if (id) {
43
+ s += ' ' + id;
44
+ if (e.loc) {
45
+ s += `:${e.loc.line}:${e.loc.column}`;
46
+ }
47
+ }
48
+ if (s) {
49
+ s += '\n';
50
+ }
51
+ const message = `${e.name ?? 'Error'}: ${e.message}`;
52
+ s += message;
53
+ if (e.frame) {
54
+ s = joinNewLine(s, e.frame);
55
+ }
56
+ // copy stack since it's important for js plugin error
57
+ if (e.stack) {
58
+ s = joinNewLine(s, e.stack.replace(message, ''));
59
+ }
60
+ return s;
61
+ }
62
+ function joinNewLine(s1, s2) {
63
+ // ensure single new line in between
64
+ return s1.replace(/\n+$/, '') + '\n' + s2.replace(/^\n+/, '');
65
+ }