pkgbld 1.35.1 → 2.0.0
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/README.md +28 -63
- package/index.js +2 -2
- package/package.json +31 -27
- package/src/build-configuration.js +395 -0
- package/src/build-entries.js +214 -0
- package/src/build-plugin-lifecycle.js +100 -0
- package/src/builtin-plugins/binify.js +31 -0
- package/src/builtin-plugins/clean.js +30 -0
- package/src/builtin-plugins/commonjs.js +14 -0
- package/src/builtin-plugins/externals.js +107 -0
- package/src/builtin-plugins/json.js +14 -0
- package/src/builtin-plugins/preprocess.js +37 -0
- package/src/builtin-plugins/resolve.js +14 -0
- package/src/builtin-plugins/terser.js +50 -0
- package/src/eject.js +151 -0
- package/src/get-json.js +16 -0
- package/src/get-plugins.js +43 -0
- package/src/get-rollup-configs.js +224 -0
- package/src/helpers.js +229 -0
- package/src/index.js +133 -0
- package/src/load-plugins.js +37 -0
- package/src/messages.js +13 -0
- package/src/options/index.js +266 -0
- package/src/options/types.js +24 -0
- package/src/plugin-name.js +6 -0
- package/src/priorities.js +10 -0
- package/src/process-pkg.js +237 -0
- package/src/process-ts-config.js +80 -0
- package/src/rollup-plugin-preprocess.d.ts +1 -0
- package/src/types.js +170 -0
- package/src/write-json.js +21 -0
- package/types/index.d.ts +298 -0
- package/dist/index.d.ts +0 -78
- package/dist/index.mjs +0 -1617
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { isExists } from './helpers.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import('./types.js').BuildConfiguration} BuildConfiguration
|
|
7
|
+
* @typedef {import('./types.js').BuildEntries} BuildEntries
|
|
8
|
+
* @typedef {import('./types.js').BuildEntry} BuildEntry
|
|
9
|
+
* @typedef {import('./types.js').BuildEntryContribution} BuildEntryContribution
|
|
10
|
+
* @typedef {import('./types.js').BuildEntryContributions} BuildEntryContributions
|
|
11
|
+
* @typedef {import('./types.js').BuildEntryIssue} BuildEntryIssue
|
|
12
|
+
* @typedef {import('./types.js').BuildFormat} BuildFormat
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const sourceFileExtensions = /** @type {const} */ (['ts', 'tsx', 'js', 'jsx', 'cjs', 'mjs']);
|
|
16
|
+
|
|
17
|
+
export class BuildEntryError extends Error {
|
|
18
|
+
/** @param {BuildEntryIssue[]} issues */
|
|
19
|
+
constructor(issues) {
|
|
20
|
+
super(issues.map(issue => `${issue.path}: ${issue.message}`).join('\n'));
|
|
21
|
+
this.name = 'BuildEntryError';
|
|
22
|
+
this.issues = issues;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Resolve package-declared and Build plugin-contributed entry specifications into
|
|
28
|
+
* one immutable catalog.
|
|
29
|
+
*
|
|
30
|
+
* @param {readonly string[]} packageEntryNames
|
|
31
|
+
* @param {BuildConfiguration} configuration
|
|
32
|
+
* @param {(contributions: BuildEntryContributions) => void} contribute
|
|
33
|
+
* @returns {Promise<BuildEntries>}
|
|
34
|
+
*/
|
|
35
|
+
export async function resolveBuildEntries(packageEntryNames, configuration, contribute) {
|
|
36
|
+
/** @type {(BuildEntryContribution & { issuePath: string })[]} */
|
|
37
|
+
const specifications = packageEntryNames.map((name, index) => ({ name, issuePath: `package.entries[${index}]` }));
|
|
38
|
+
let contributionIndex = 0;
|
|
39
|
+
const contributions = {
|
|
40
|
+
/** @param {BuildEntryContribution} contribution */
|
|
41
|
+
add(contribution) {
|
|
42
|
+
specifications.push({ ...contribution, issuePath: `plugins.entries[${contributionIndex}]` });
|
|
43
|
+
contributionIndex += 1;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
contribute(contributions);
|
|
47
|
+
|
|
48
|
+
/** @type {BuildEntryIssue[]} */
|
|
49
|
+
const issues = [];
|
|
50
|
+
/** @type {BuildEntry[]} */
|
|
51
|
+
const values = [];
|
|
52
|
+
/** @type {Map<string, BuildEntry>} */
|
|
53
|
+
const byName = new Map();
|
|
54
|
+
|
|
55
|
+
for (const specification of specifications) {
|
|
56
|
+
const { issuePath } = specification;
|
|
57
|
+
const name = normalizeName(specification.name, issuePath, issues);
|
|
58
|
+
if (!name) continue;
|
|
59
|
+
if (byName.has(name)) {
|
|
60
|
+
issues.push({
|
|
61
|
+
code: 'DUPLICATE_BUILD_ENTRY',
|
|
62
|
+
path: issuePath,
|
|
63
|
+
name,
|
|
64
|
+
message: `Build entry ${JSON.stringify(name)} is declared more than once`,
|
|
65
|
+
});
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const source = await resolveSource(name, specification.sourcePath, configuration.paths.sourceDir);
|
|
70
|
+
if (!source) {
|
|
71
|
+
issues.push({
|
|
72
|
+
code: 'SOURCE_NOT_FOUND',
|
|
73
|
+
path: issuePath,
|
|
74
|
+
name,
|
|
75
|
+
message: `Build entry ${JSON.stringify(name)} has no supported source file`,
|
|
76
|
+
});
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** @type {Partial<Record<BuildFormat, string>>} */
|
|
81
|
+
const outputPaths = {};
|
|
82
|
+
for (const format of configuration.outputs.formats) {
|
|
83
|
+
if (format !== 'umd' || configuration.outputs.umdEntries.includes(name)) {
|
|
84
|
+
outputPaths[format] =
|
|
85
|
+
`./${configuration.paths.outputDir}/${configuration.outputs.patterns[format].replace('[name]', name)}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const entry = Object.freeze({
|
|
89
|
+
name,
|
|
90
|
+
sourcePath: source.sourcePath,
|
|
91
|
+
extension: source.extension,
|
|
92
|
+
outputPaths: Object.freeze(outputPaths),
|
|
93
|
+
});
|
|
94
|
+
values.push(entry);
|
|
95
|
+
byName.set(name, entry);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
validateSelections(byName, configuration.outputs.umdEntries, 'outputs.umdEntries', issues);
|
|
99
|
+
validateSelections(byName, configuration.transforms.preprocess, 'transforms.preprocess', issues);
|
|
100
|
+
validateOutputPaths(values, issues);
|
|
101
|
+
|
|
102
|
+
if (issues.length > 0) throw new BuildEntryError(issues);
|
|
103
|
+
|
|
104
|
+
const frozenValues = Object.freeze(values);
|
|
105
|
+
return Object.freeze({
|
|
106
|
+
values: frozenValues,
|
|
107
|
+
/** @param {string} name */
|
|
108
|
+
require(name) {
|
|
109
|
+
const entry = byName.get(name);
|
|
110
|
+
if (!entry) {
|
|
111
|
+
throw new BuildEntryError([
|
|
112
|
+
{
|
|
113
|
+
code: 'SELECTED_BUILD_ENTRY_NOT_FOUND',
|
|
114
|
+
path: 'entries',
|
|
115
|
+
name,
|
|
116
|
+
message: `Build entry ${JSON.stringify(name)} was not discovered; available entries: ${values.map(entry => entry.name).join(', ')}`,
|
|
117
|
+
},
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
120
|
+
return entry;
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @param {unknown} value
|
|
127
|
+
* @param {string} issuePath
|
|
128
|
+
* @param {BuildEntryIssue[]} issues
|
|
129
|
+
*/
|
|
130
|
+
function normalizeName(value, issuePath, issues) {
|
|
131
|
+
if (typeof value !== 'string') {
|
|
132
|
+
issues.push({ code: 'INVALID_BUILD_ENTRY_NAME', path: issuePath, message: 'Build entry name must be a string' });
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const name = value.replaceAll('\\', '/');
|
|
136
|
+
const segments = name.split('/');
|
|
137
|
+
if (
|
|
138
|
+
name.length === 0 ||
|
|
139
|
+
name.startsWith('/') ||
|
|
140
|
+
name.startsWith('./') ||
|
|
141
|
+
path.isAbsolute(name) ||
|
|
142
|
+
segments.some(segment => segment === '' || segment === '.' || segment === '..')
|
|
143
|
+
) {
|
|
144
|
+
issues.push({
|
|
145
|
+
code: 'INVALID_BUILD_ENTRY_NAME',
|
|
146
|
+
path: issuePath,
|
|
147
|
+
name,
|
|
148
|
+
message: `Invalid Build entry name ${JSON.stringify(value)}`,
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
return name;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @param {string} name
|
|
157
|
+
* @param {string | undefined} providedPath
|
|
158
|
+
* @param {string} sourceDir
|
|
159
|
+
* @returns {Promise<{ sourcePath: string; extension: import('./types.js').BuildEntryExtension } | undefined>}
|
|
160
|
+
*/
|
|
161
|
+
async function resolveSource(name, providedPath, sourceDir) {
|
|
162
|
+
if (providedPath != null) {
|
|
163
|
+
if (!(await isExists(providedPath))) return;
|
|
164
|
+
const extension = path.extname(providedPath).slice(1);
|
|
165
|
+
if (!sourceFileExtensions.includes(/** @type {typeof sourceFileExtensions[number]} */ (extension))) return;
|
|
166
|
+
return { sourcePath: providedPath, extension: /** @type {import('./types.js').BuildEntryExtension} */ (extension) };
|
|
167
|
+
}
|
|
168
|
+
for (const extension of sourceFileExtensions) {
|
|
169
|
+
const sourcePath = `./${sourceDir}/${name}.${extension}`;
|
|
170
|
+
if (await isExists(sourcePath)) return { sourcePath, extension };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @param {Map<string, BuildEntry>} byName
|
|
176
|
+
* @param {readonly string[]} names
|
|
177
|
+
* @param {string} selectionPath
|
|
178
|
+
* @param {BuildEntryIssue[]} issues
|
|
179
|
+
*/
|
|
180
|
+
function validateSelections(byName, names, selectionPath, issues) {
|
|
181
|
+
for (const [index, name] of names.entries()) {
|
|
182
|
+
if (!byName.has(name)) {
|
|
183
|
+
issues.push({
|
|
184
|
+
code: 'SELECTED_BUILD_ENTRY_NOT_FOUND',
|
|
185
|
+
path: `${selectionPath}[${index}]`,
|
|
186
|
+
name,
|
|
187
|
+
message: `Build entry ${JSON.stringify(name)} was selected but not discovered`,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @param {BuildEntry[]} entries
|
|
195
|
+
* @param {BuildEntryIssue[]} issues
|
|
196
|
+
*/
|
|
197
|
+
function validateOutputPaths(entries, issues) {
|
|
198
|
+
const owners = new Map();
|
|
199
|
+
for (const entry of entries) {
|
|
200
|
+
for (const [format, outputPath] of Object.entries(entry.outputPaths)) {
|
|
201
|
+
const owner = owners.get(outputPath);
|
|
202
|
+
if (owner) {
|
|
203
|
+
issues.push({
|
|
204
|
+
code: 'OUTPUT_PATH_COLLISION',
|
|
205
|
+
path: `entries.${entry.name}.outputPaths.${format}`,
|
|
206
|
+
name: entry.name,
|
|
207
|
+
message: `Output path ${JSON.stringify(outputPath)} is also produced by Build entry ${JSON.stringify(owner)}`,
|
|
208
|
+
});
|
|
209
|
+
} else {
|
|
210
|
+
owners.set(outputPath, entry.name);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('rollup').InternalModuleFormat} InternalModuleFormat
|
|
3
|
+
* @typedef {import('rollup').OutputOptions} OutputOptions
|
|
4
|
+
* @typedef {import('type-fest').JsonObject} JsonObject
|
|
5
|
+
* @typedef {import('type-fest').PackageJson} PackageJson
|
|
6
|
+
* @typedef {import('./types.js').BuildConfiguration} BuildConfiguration
|
|
7
|
+
* @typedef {import('./types.js').BuildConfigurationDraft} BuildConfigurationDraft
|
|
8
|
+
* @typedef {import('./types.js').BuildConfigurationSources} BuildConfigurationSources
|
|
9
|
+
* @typedef {import('./types.js').BuildEntries} BuildEntries
|
|
10
|
+
* @typedef {import('./types.js').BuildEntryContributions} BuildEntryContributions
|
|
11
|
+
* @typedef {import('./types.js').PackageProcessingResult} PackageProcessingResult
|
|
12
|
+
* @typedef {import('./types.js').PkgbldPlugin} PkgbldPlugin
|
|
13
|
+
* @typedef {import('./types.js').PluginSharedState} PluginSharedState
|
|
14
|
+
* @typedef {import('./types.js').Provider} Provider
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Owns Build plugin invocation and shared state for one build.
|
|
19
|
+
*
|
|
20
|
+
* The lifecycle preserves phase boundaries, but does not guarantee plugin order
|
|
21
|
+
* within a phase. Asynchronous hooks in the same phase run concurrently.
|
|
22
|
+
* Build plugins must not rely on same-phase shared-state reads and writes.
|
|
23
|
+
*
|
|
24
|
+
* @param {Partial<PkgbldPlugin>[]} plugins
|
|
25
|
+
*/
|
|
26
|
+
export function createBuildPluginLifecycle(plugins) {
|
|
27
|
+
/** @type {PluginSharedState} */
|
|
28
|
+
const shared = new Map();
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
/**
|
|
32
|
+
* @param {BuildConfigurationDraft} draft
|
|
33
|
+
* @param {BuildConfigurationSources} sources
|
|
34
|
+
*/
|
|
35
|
+
configure(draft, sources) {
|
|
36
|
+
for (const plugin of plugins) {
|
|
37
|
+
plugin.configure?.({ draft, sources, shared });
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {BuildEntryContributions} entries
|
|
43
|
+
* @param {BuildConfiguration} configuration
|
|
44
|
+
*/
|
|
45
|
+
contributeEntries(entries, configuration) {
|
|
46
|
+
for (const plugin of plugins) {
|
|
47
|
+
plugin.contributeEntries?.({ entries, configuration, shared });
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {JsonObject} config
|
|
53
|
+
* @param {BuildConfiguration} configuration
|
|
54
|
+
*/
|
|
55
|
+
processTsConfig(config, configuration) {
|
|
56
|
+
for (const plugin of plugins) {
|
|
57
|
+
plugin.processTsConfig?.({ config, configuration, shared });
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {PackageJson} packageJson
|
|
63
|
+
* @param {BuildEntries} entries
|
|
64
|
+
* @param {BuildConfiguration} configuration
|
|
65
|
+
*/
|
|
66
|
+
processPackageJson(packageJson, entries, configuration) {
|
|
67
|
+
for (const plugin of plugins) {
|
|
68
|
+
plugin.processPackageJson?.({ packageJson, entries, configuration, shared });
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @param {Provider} provider
|
|
74
|
+
* @param {BuildConfiguration} configuration
|
|
75
|
+
* @param {PackageProcessingResult} packageResult
|
|
76
|
+
*/
|
|
77
|
+
async provideRollupPlugins(provider, configuration, packageResult) {
|
|
78
|
+
await Promise.all(plugins.map(plugin => plugin.providePlugins?.({ provider, configuration, packageResult, shared })));
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {Partial<OutputOptions>} settings
|
|
83
|
+
* @param {InternalModuleFormat} format
|
|
84
|
+
* @param {string[]} inputs
|
|
85
|
+
* @param {BuildConfiguration} configuration
|
|
86
|
+
*/
|
|
87
|
+
extendOutputSettings(settings, format, inputs, configuration) {
|
|
88
|
+
for (const plugin of plugins) {
|
|
89
|
+
if (plugin.getExtraOutputSettings) {
|
|
90
|
+
Object.assign(settings, plugin.getExtraOutputSettings({ format, inputs, configuration, shared }));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
/** @param {BuildConfiguration} configuration */
|
|
96
|
+
async buildEnd(configuration) {
|
|
97
|
+
await Promise.all(plugins.map(plugin => plugin.buildEnd?.({ configuration, shared })));
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Priority } from '../priorities.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('rollup').OutputChunk} OutputChunk
|
|
5
|
+
* @typedef {import('../types.js').BuildConfiguration} BuildConfiguration
|
|
6
|
+
* @typedef {import('../types.js').PackageProcessingResult} PackageProcessingResult
|
|
7
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {Provider} provider
|
|
12
|
+
* @param {BuildConfiguration} configuration
|
|
13
|
+
* @param {PackageProcessingResult} packageResult
|
|
14
|
+
*/
|
|
15
|
+
export default async function (provider, configuration, packageResult) {
|
|
16
|
+
if (packageResult.executableOutputs.length > 0) {
|
|
17
|
+
const pluginBinify = await provider.import('@rollup-extras/plugin-binify');
|
|
18
|
+
|
|
19
|
+
provider.provide(
|
|
20
|
+
() =>
|
|
21
|
+
pluginBinify({
|
|
22
|
+
filter: (/** @type {OutputChunk} */ item) =>
|
|
23
|
+
item.type === 'chunk' &&
|
|
24
|
+
item.isEntry &&
|
|
25
|
+
packageResult.executableOutputs.some(input => input === `./${configuration.paths.outputDir}/${item.fileName}`),
|
|
26
|
+
}),
|
|
27
|
+
Priority.finalize,
|
|
28
|
+
{ outputPlugin: true, format: 'cjs' }
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Priority } from '../priorities.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('../types.js').BuildConfiguration} BuildConfiguration
|
|
5
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {Provider} provider
|
|
10
|
+
* @param {BuildConfiguration} configuration
|
|
11
|
+
*/
|
|
12
|
+
export default async function (provider, configuration) {
|
|
13
|
+
if (!configuration.execution.clean) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const pluginClean = await provider.import('@rollup-extras/plugin-clean');
|
|
18
|
+
|
|
19
|
+
const pluginInstance = pluginClean();
|
|
20
|
+
|
|
21
|
+
provider.provide(pluginFactory, Priority.cleanup, { outputPlugin: true });
|
|
22
|
+
|
|
23
|
+
let firstPluginInstance = true;
|
|
24
|
+
|
|
25
|
+
function pluginFactory() {
|
|
26
|
+
const result = firstPluginInstance ? pluginInstance : pluginInstance.api.addInstance();
|
|
27
|
+
firstPluginInstance = false;
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Priority } from '../priorities.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {Provider} provider
|
|
9
|
+
*/
|
|
10
|
+
export default async function (provider) {
|
|
11
|
+
const pluginCommonjs = await provider.import('@rollup/plugin-commonjs');
|
|
12
|
+
|
|
13
|
+
provider.provide(() => pluginCommonjs(), Priority.commonjs);
|
|
14
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { Priority } from '../priorities.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {(...args: any[]) => any} fn
|
|
7
|
+
* @param {any[]} args
|
|
8
|
+
* @returns {any}
|
|
9
|
+
*/
|
|
10
|
+
export function curry(fn, ...args) {
|
|
11
|
+
return args.length >= fn.length
|
|
12
|
+
? fn(...args)
|
|
13
|
+
: /** @type {(...nextArgs: any[]) => any} */ ((...nextArgs) => curry(fn, ...args, ...nextArgs));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {import('rollup').InternalModuleFormat} InternalModuleFormat
|
|
18
|
+
* @typedef {import('../types.js').BuildConfiguration} BuildConfiguration
|
|
19
|
+
* @typedef {import('../types.js').PackageProcessingResult} PackageProcessingResult
|
|
20
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {Provider} provider
|
|
25
|
+
* @param {BuildConfiguration} configuration
|
|
26
|
+
* @param {PackageProcessingResult} packageResult
|
|
27
|
+
*/
|
|
28
|
+
export default async function (provider, configuration, packageResult) {
|
|
29
|
+
const inputs = packageResult.entries.values.map(entry => entry.sourcePath);
|
|
30
|
+
if (configuration.transforms.includeExternals === true) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const pluginExternals = await provider.import('@rollup-extras/plugin-externals');
|
|
35
|
+
|
|
36
|
+
const allowGenericUmd = configuration.outputs.umdEntries.length === 1 && inputs.length === 1;
|
|
37
|
+
|
|
38
|
+
if (configuration.outputs.formats.length > 0) {
|
|
39
|
+
const format = /** @type {InternalModuleFormat[]} */ (
|
|
40
|
+
allowGenericUmd ? undefined : configuration.outputs.formats.filter(format => format !== 'umd')
|
|
41
|
+
);
|
|
42
|
+
provider.provide(
|
|
43
|
+
() =>
|
|
44
|
+
pluginExternals(
|
|
45
|
+
configuration.transforms.includeExternals === false
|
|
46
|
+
? {}
|
|
47
|
+
: (/** @type {string} */ id, /** @type {boolean} */ external, /** @type {string} */ importer) =>
|
|
48
|
+
includeExternals(importer, external, id, configuration)
|
|
49
|
+
),
|
|
50
|
+
Priority.externals,
|
|
51
|
+
{ format }
|
|
52
|
+
);
|
|
53
|
+
provider.globalImport('path', 'path');
|
|
54
|
+
provider.globalSetup(includeExternals);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!allowGenericUmd && configuration.outputs.umdEntries.length > 0) {
|
|
58
|
+
const curryForConfig = /** @type {typeof curry} */ (provider.globalSetup(curry) ?? curry);
|
|
59
|
+
for (const entryName of configuration.outputs.umdEntries) {
|
|
60
|
+
const currentInput = packageResult.entries.require(entryName).sourcePath;
|
|
61
|
+
const isExternal = curryForConfig(
|
|
62
|
+
(
|
|
63
|
+
/** @type {string} */ currentInput,
|
|
64
|
+
/** @type {string} */ id,
|
|
65
|
+
/** @type {boolean} */ external,
|
|
66
|
+
/** @type {string} */ importer
|
|
67
|
+
) => includeExternals(importer, external, id, configuration) || isExternalInput(currentInput, inputs, id)
|
|
68
|
+
)(currentInput);
|
|
69
|
+
provider.provide(() => pluginExternals(isExternal), Priority.externals, {
|
|
70
|
+
format: 'umd',
|
|
71
|
+
inputs: [currentInput],
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (configuration.outputs.formats.length === 0) {
|
|
75
|
+
provider.globalImport('path', 'path');
|
|
76
|
+
provider.globalSetup(includeExternals);
|
|
77
|
+
}
|
|
78
|
+
provider.globalSetup(isExternalInput);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @param {string} _importer
|
|
84
|
+
* @param {boolean} external
|
|
85
|
+
* @param {string} id
|
|
86
|
+
* @param {BuildConfiguration} configuration
|
|
87
|
+
*/
|
|
88
|
+
function includeExternals(_importer, external, id, configuration) {
|
|
89
|
+
if (configuration.transforms.includeExternals === false) return external;
|
|
90
|
+
if (!external) return false;
|
|
91
|
+
const internals = /** @type {readonly string[]} */ (configuration.transforms.includeExternals);
|
|
92
|
+
if (internals.includes(id) || internals.some(internal => id.includes(internal))) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {string} currentInput
|
|
100
|
+
* @param {string | readonly string[]} inputs
|
|
101
|
+
* @param {string} id
|
|
102
|
+
*/
|
|
103
|
+
function isExternalInput(currentInput, inputs, id) {
|
|
104
|
+
const normalizedPath = path.isAbsolute(currentInput) ? `./${path.relative(process.cwd(), currentInput)}` : currentInput;
|
|
105
|
+
const normalizedId = path.isAbsolute(id) ? `./${path.relative(process.cwd(), id)}` : id;
|
|
106
|
+
return normalizedPath !== normalizedId && inputs.includes(normalizedPath);
|
|
107
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Priority } from '../priorities.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {Provider} provider
|
|
9
|
+
*/
|
|
10
|
+
export default async function (provider) {
|
|
11
|
+
const pluginJson = await provider.import('@rollup/plugin-json');
|
|
12
|
+
|
|
13
|
+
provider.provide(() => pluginJson(), Priority.preprocess);
|
|
14
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Priority } from '../priorities.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('rollup').InternalModuleFormat} InternalModuleFormat
|
|
5
|
+
* @typedef {import('../types.js').BuildConfiguration} BuildConfiguration
|
|
6
|
+
* @typedef {import('../types.js').PackageProcessingResult} PackageProcessingResult
|
|
7
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {Provider} provider
|
|
12
|
+
* @param {BuildConfiguration} configuration
|
|
13
|
+
* @param {PackageProcessingResult} packageResult
|
|
14
|
+
*/
|
|
15
|
+
export default async function (provider, configuration, packageResult) {
|
|
16
|
+
if (configuration.transforms.preprocess.length > 0) {
|
|
17
|
+
const pluginPreprocess = /** @type {typeof import('rollup-plugin-preprocess')} */ (
|
|
18
|
+
await provider.import('rollup-plugin-preprocess')
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const include = configuration.transforms.preprocess.map(name => packageResult.entries.require(name).sourcePath);
|
|
22
|
+
|
|
23
|
+
for (const format of /** @type {readonly InternalModuleFormat[]} */ (configuration.outputs.formats)) {
|
|
24
|
+
if (format !== 'umd') {
|
|
25
|
+
provider.provide(() => pluginPreprocess.default({ include, context: { [format]: true } }), Priority.preprocess, { format });
|
|
26
|
+
} else {
|
|
27
|
+
for (const entryName of configuration.outputs.umdEntries) {
|
|
28
|
+
const currentInput = packageResult.entries.require(entryName).sourcePath;
|
|
29
|
+
provider.provide(() => pluginPreprocess.default({ include, context: { umd: true } }), Priority.preprocess, {
|
|
30
|
+
format,
|
|
31
|
+
inputs: [currentInput],
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Priority } from '../priorities.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {Provider} provider
|
|
9
|
+
*/
|
|
10
|
+
export default async function (provider) {
|
|
11
|
+
const pluginResolve = await provider.import('@rollup/plugin-node-resolve');
|
|
12
|
+
|
|
13
|
+
provider.provide(() => pluginResolve(), Priority.resolve);
|
|
14
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Priority } from '../priorities.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('rollup').InternalModuleFormat} InternalModuleFormat
|
|
5
|
+
* @typedef {import('../types.js').BuildConfiguration} BuildConfiguration
|
|
6
|
+
* @typedef {import('../types.js').PackageProcessingResult} PackageProcessingResult
|
|
7
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {Provider} provider
|
|
12
|
+
* @param {BuildConfiguration} configuration
|
|
13
|
+
* @param {PackageProcessingResult} packageResult
|
|
14
|
+
*/
|
|
15
|
+
export default async function (provider, configuration, packageResult) {
|
|
16
|
+
const filteredFormats = configuration.transforms.compress.filter(format => configuration.outputs.formats.includes(format));
|
|
17
|
+
|
|
18
|
+
if (filteredFormats.length > 0) {
|
|
19
|
+
const pluginTerser = await provider.import('@rollup/plugin-terser');
|
|
20
|
+
|
|
21
|
+
const options = {
|
|
22
|
+
mangle: {
|
|
23
|
+
properties: {
|
|
24
|
+
regex: /_$/,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
if (configuration.transforms.removeLegalComments) {
|
|
30
|
+
/** @type {any} */ (options).output = {
|
|
31
|
+
comments: false,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const format of /** @type {InternalModuleFormat[]} */ (filteredFormats)) {
|
|
36
|
+
if (format !== 'umd') {
|
|
37
|
+
provider.provide(() => pluginTerser(options), Priority.compress, { format, outputPlugin: true });
|
|
38
|
+
} else {
|
|
39
|
+
for (const entryName of configuration.outputs.umdEntries) {
|
|
40
|
+
const currentInput = packageResult.entries.require(entryName).sourcePath;
|
|
41
|
+
provider.provide(() => pluginTerser(options), Priority.compress, {
|
|
42
|
+
format,
|
|
43
|
+
outputPlugin: true,
|
|
44
|
+
inputs: [currentInput],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|