rolldown 1.0.0-beta.1-commit.7c52c94 → 1.0.0-beta.2-commit.afd0727
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.
- package/dist/cjs/cli.cjs +981 -25
- package/dist/cjs/experimental-index.cjs +2 -2
- package/dist/cjs/index.cjs +2 -2
- package/dist/cjs/parallel-plugin-worker.cjs +2 -2
- package/dist/cjs/parse-ast-index.cjs +1 -1
- package/dist/esm/cli.mjs +981 -26
- package/dist/esm/experimental-index.mjs +2 -2
- package/dist/esm/index.mjs +2 -2
- package/dist/esm/parallel-plugin-worker.mjs +2 -2
- package/dist/esm/parse-ast-index.mjs +1 -1
- package/dist/shared/{binding-Bl7VQy7c.mjs → binding-l7VLSKnB.mjs} +3 -3
- package/dist/shared/{binding-fhgdIkpS.cjs → binding-orkvONpS.cjs} +3 -3
- package/dist/shared/prompt-B7tq3GL9.cjs +854 -0
- package/dist/shared/prompt-Nfm4Xz36.mjs +851 -0
- package/dist/shared/{src-lBcHSsjm.cjs → src-Db20iysW.cjs} +12 -6
- package/dist/shared/{src-CPCP99Z9.mjs → src-mclDryX0.mjs} +12 -6
- package/dist/types/api/build.js +22 -0
- package/dist/types/api/experimental.js +13 -0
- package/dist/types/api/rolldown/index.js +7 -0
- package/dist/types/api/rolldown/rolldown-build.js +43 -0
- package/dist/types/api/watch/index.js +8 -0
- package/dist/types/api/watch/watch-emitter.js +69 -0
- package/dist/types/api/watch/watcher.js +66 -0
- package/dist/types/binding.d.ts +40 -2
- package/dist/types/builtin-plugin/alias-plugin.js +4 -0
- package/dist/types/builtin-plugin/constructors.d.ts +2 -2
- package/dist/types/builtin-plugin/constructors.js +68 -0
- package/dist/types/builtin-plugin/replace-plugin.js +29 -0
- package/dist/types/builtin-plugin/transform-plugin.js +16 -0
- package/dist/types/builtin-plugin/utils.js +19 -0
- package/dist/types/cli/arguments/alias.js +63 -0
- package/dist/types/cli/arguments/index.js +127 -0
- package/dist/types/cli/arguments/normalize.js +48 -0
- package/dist/types/cli/arguments/utils.js +67 -0
- package/dist/types/cli/colors.js +17 -0
- package/dist/types/cli/commands/bundle.js +203 -0
- package/dist/types/cli/commands/help.js +88 -0
- package/dist/types/cli/index.js +27 -0
- package/dist/types/cli/load-config.js +95 -0
- package/dist/types/cli/logger.js +35 -0
- package/dist/types/constants/plugin-context.js +7 -0
- package/dist/types/constants/plugin.js +69 -0
- package/dist/types/experimental-index.js +9 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +7 -0
- package/dist/types/log/logHandler.js +25 -0
- package/dist/types/log/logger.js +107 -0
- package/dist/types/log/logging.js +11 -0
- package/dist/types/log/logs.js +86 -0
- package/dist/types/options/input-options.d.ts +47 -2
- package/dist/types/options/input-options.js +1 -0
- package/dist/types/options/normalized-input-options.js +21 -0
- package/dist/types/options/normalized-output-options.js +99 -0
- package/dist/types/options/output-options.d.ts +6 -0
- package/dist/types/options/output-options.js +1 -0
- package/dist/types/options/watch-options.js +1 -0
- package/dist/types/parallel-plugin-worker.js +31 -0
- package/dist/types/parallel-plugin.js +1 -0
- package/dist/types/parse-ast-index.js +73 -0
- package/dist/types/plugin/bindingify-build-hooks.js +213 -0
- package/dist/types/plugin/bindingify-hook-filter.js +39 -0
- package/dist/types/plugin/bindingify-output-hooks.js +189 -0
- package/dist/types/plugin/bindingify-plugin-hook-meta.js +19 -0
- package/dist/types/plugin/bindingify-plugin.js +124 -0
- package/dist/types/plugin/bindingify-watch-hooks.js +29 -0
- package/dist/types/plugin/hook-filter.js +1 -0
- package/dist/types/plugin/index.js +1 -0
- package/dist/types/plugin/minimal-plugin-context.js +25 -0
- package/dist/types/plugin/parallel-plugin-implementation.js +3 -0
- package/dist/types/plugin/parallel-plugin.js +6 -0
- package/dist/types/plugin/plugin-context-data.js +55 -0
- package/dist/types/plugin/plugin-context.js +108 -0
- package/dist/types/plugin/plugin-driver.js +88 -0
- package/dist/types/plugin/transform-plugin-context.js +37 -0
- package/dist/types/types/assert.js +1 -0
- package/dist/types/types/config-export.js +1 -0
- package/dist/types/types/misc.js +1 -0
- package/dist/types/types/module-info.js +1 -0
- package/dist/types/types/module-side-effects.js +1 -0
- package/dist/types/types/output-bundle.js +1 -0
- package/dist/types/types/rolldown-options.js +1 -0
- package/dist/types/types/rolldown-output.js +1 -0
- package/dist/types/types/schema.js +1 -0
- package/dist/types/types/sourcemap.js +16 -0
- package/dist/types/types/utils.js +1 -0
- package/dist/types/utils/asset-source.js +8 -0
- package/dist/types/utils/async-flatten.js +7 -0
- package/dist/types/utils/bindingify-input-options.js +225 -0
- package/dist/types/utils/bindingify-output-options.js +92 -0
- package/dist/types/utils/code-frame.js +46 -0
- package/dist/types/utils/compose-js-plugins.js +400 -0
- package/dist/types/utils/create-bundler-option.js +53 -0
- package/dist/types/utils/create-bundler.js +15 -0
- package/dist/types/utils/define-config.js +3 -0
- package/dist/types/utils/error.js +65 -0
- package/dist/types/utils/initialize-parallel-plugins.js +54 -0
- package/dist/types/utils/misc.js +22 -0
- package/dist/types/utils/normalize-hook.js +21 -0
- package/dist/types/utils/normalize-plugin-option.js +35 -0
- package/dist/types/utils/normalize-string-or-regex.js +14 -0
- package/dist/types/utils/plugin/index.js +7 -0
- package/dist/types/utils/transform-module-info.js +19 -0
- package/dist/types/utils/transform-rendered-chunk.js +43 -0
- package/dist/types/utils/transform-rendered-module.js +10 -0
- package/dist/types/utils/transform-side-effects.js +16 -0
- package/dist/types/utils/transform-sourcemap.js +29 -0
- package/dist/types/utils/transform-to-rollup-output.js +165 -0
- package/dist/types/utils/validator.js +275 -0
- package/package.json +28 -25
- package/dist/shared/consola_36c0034f-Cx52UqEq.mjs +0 -832
- package/dist/shared/consola_36c0034f-CynBWXXO.cjs +0 -859
- package/dist/shared/prompt-B58MxVuU.cjs +0 -762
- package/dist/shared/prompt-DjjlOckE.mjs +0 -758
- 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,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
|
+
}
|