pkgbld 1.36.0 → 2.1.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 +71 -89
- package/index.js +2 -2
- package/package.json +31 -27
- package/src/build-configuration.js +406 -0
- package/src/build-entries.js +271 -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 +108 -0
- package/src/builtin-plugins/json.js +14 -0
- package/src/builtin-plugins/package-imports.js +79 -0
- package/src/builtin-plugins/preprocess.js +37 -0
- package/src/builtin-plugins/resolve.js +22 -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 +44 -0
- package/src/get-rollup-configs.js +261 -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 +277 -0
- package/src/options/types.js +24 -0
- package/src/package-imports.js +240 -0
- package/src/plugin-name.js +6 -0
- package/src/priorities.js +11 -0
- package/src/process-pkg.js +244 -0
- package/src/process-ts-config.js +80 -0
- package/src/rollup-plugin-preprocess.d.ts +1 -0
- package/src/types.js +175 -0
- package/src/write-json.js +21 -0
- package/types/index.d.ts +310 -0
- package/dist/index.d.ts +0 -79
- package/dist/index.mjs +0 -1626
|
@@ -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,108 @@
|
|
|
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.filter(entry => entry.origin !== 'import').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 && !configuration.resolution.imports
|
|
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.resolution.imports && id.startsWith('#')) return false;
|
|
90
|
+
if (configuration.transforms.includeExternals === false) return external;
|
|
91
|
+
if (!external) return false;
|
|
92
|
+
const internals = /** @type {readonly string[]} */ (configuration.transforms.includeExternals);
|
|
93
|
+
if (internals.includes(id) || internals.some(internal => id.includes(internal))) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {string} currentInput
|
|
101
|
+
* @param {string | readonly string[]} inputs
|
|
102
|
+
* @param {string} id
|
|
103
|
+
*/
|
|
104
|
+
function isExternalInput(currentInput, inputs, id) {
|
|
105
|
+
const normalizedPath = path.isAbsolute(currentInput) ? `./${path.relative(process.cwd(), currentInput)}` : currentInput;
|
|
106
|
+
const normalizedId = path.isAbsolute(id) ? `./${path.relative(process.cwd(), id)}` : id;
|
|
107
|
+
return normalizedPath !== normalizedId && inputs.includes(normalizedPath);
|
|
108
|
+
}
|
|
@@ -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,79 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { Priority } from '../priorities.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('../types.js').BuildConfiguration} BuildConfiguration
|
|
8
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {Provider} provider
|
|
13
|
+
* @param {BuildConfiguration} configuration
|
|
14
|
+
*/
|
|
15
|
+
export default function (provider, configuration) {
|
|
16
|
+
if (!configuration.resolution.imports) return;
|
|
17
|
+
|
|
18
|
+
provider.globalImport('node:fs/promises', 'fs');
|
|
19
|
+
provider.globalImport('path', 'path');
|
|
20
|
+
const createPlugin = /** @type {typeof createPackageImportsPlugin} */ (
|
|
21
|
+
provider.globalSetup(createPackageImportsPlugin) ?? createPackageImportsPlugin
|
|
22
|
+
);
|
|
23
|
+
provider.provide(() => createPlugin(), Priority.packageImports);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Keep the package's private specifiers for runtime resolution. Each importer
|
|
28
|
+
* is assigned to its nearest real package boundary, so linked dependencies and
|
|
29
|
+
* nested workspace packages retain ownership of their own private imports.
|
|
30
|
+
*/
|
|
31
|
+
export function createPackageImportsPlugin() {
|
|
32
|
+
const packageRoot = fs.realpath(process.cwd());
|
|
33
|
+
/** @type {Map<string, string | null>} */
|
|
34
|
+
const owners = new Map();
|
|
35
|
+
return {
|
|
36
|
+
name: 'pkgbld:package-imports',
|
|
37
|
+
/** @param {string} id @param {string | undefined} importer */
|
|
38
|
+
async resolveId(id, importer) {
|
|
39
|
+
if (!id.startsWith('#') || !importer || importer.includes('\0')) return null;
|
|
40
|
+
let realImporter;
|
|
41
|
+
try {
|
|
42
|
+
realImporter = await fs.realpath(importer.split('?', 1)[0]);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (['ENOENT', 'EINVAL'].includes(/** @type {NodeJS.ErrnoException} */ (error).code ?? '')) return null;
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
const owner = await findOwner(path.dirname(realImporter));
|
|
48
|
+
return owner === (await packageRoot) ? { id, external: true } : null;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/** @param {string} start */
|
|
53
|
+
async function findOwner(start) {
|
|
54
|
+
let directory = start;
|
|
55
|
+
/** @type {string[]} */
|
|
56
|
+
const visited = [];
|
|
57
|
+
while (true) {
|
|
58
|
+
if (owners.has(directory)) {
|
|
59
|
+
const owner = /** @type {string | null} */ (owners.get(directory));
|
|
60
|
+
for (const visitedDirectory of visited) owners.set(visitedDirectory, owner);
|
|
61
|
+
return owner;
|
|
62
|
+
}
|
|
63
|
+
visited.push(directory);
|
|
64
|
+
try {
|
|
65
|
+
await fs.access(path.join(directory, 'package.json'));
|
|
66
|
+
for (const visitedDirectory of visited) owners.set(visitedDirectory, directory);
|
|
67
|
+
return directory;
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (/** @type {NodeJS.ErrnoException} */ (error).code !== 'ENOENT') throw error;
|
|
70
|
+
}
|
|
71
|
+
const parent = path.dirname(directory);
|
|
72
|
+
if (parent === directory) {
|
|
73
|
+
for (const visitedDirectory of visited) owners.set(visitedDirectory, null);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
directory = parent;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -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,22 @@
|
|
|
1
|
+
import { Priority } from '../priorities.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('../types.js').Provider} Provider
|
|
5
|
+
* @typedef {import('../types.js').BuildConfiguration} BuildConfiguration
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {Provider} provider
|
|
10
|
+
* @param {BuildConfiguration} configuration
|
|
11
|
+
*/
|
|
12
|
+
export default async function (provider, configuration) {
|
|
13
|
+
const pluginResolve = await provider.import('@rollup/plugin-node-resolve');
|
|
14
|
+
|
|
15
|
+
provider.provide(
|
|
16
|
+
() =>
|
|
17
|
+
configuration.resolution.conditions.length > 0
|
|
18
|
+
? pluginResolve({ exportConditions: [...configuration.resolution.conditions] })
|
|
19
|
+
: pluginResolve(),
|
|
20
|
+
Priority.resolve
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -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
|
+
}
|
package/src/eject.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import pkgbldPkg from '../package.json' with { type: 'json' };
|
|
5
|
+
import { camelCase } from './helpers.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('rollup').RollupOptions} RollupOptions
|
|
9
|
+
* @typedef {import('type-fest').PackageJson} PackageJson
|
|
10
|
+
* @typedef {import('./types.js').BuildConfiguration} BuildConfiguration
|
|
11
|
+
* @typedef {import('./types.js').PackageProcessingResult} PackageProcessingResult
|
|
12
|
+
* @typedef {import('./types.js').PkgbldRollupPlugin} PkgbldRollupPlugin
|
|
13
|
+
* @typedef {import('./types.js').Provider} Provider
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const imports = new Map();
|
|
17
|
+
const setup = new Set();
|
|
18
|
+
|
|
19
|
+
/** @type {<T extends object>(object: T) => string | boolean | RegExp | null | undefined} */
|
|
20
|
+
let generate;
|
|
21
|
+
/** @type {() => string} */
|
|
22
|
+
let generateGlobals;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @returns {Promise<[Provider, PkgbldRollupPlugin[]]>}
|
|
26
|
+
*/
|
|
27
|
+
export async function createEjectProvider() {
|
|
28
|
+
const createMockProvider = (await import('@slimlib/smart-mock')).default;
|
|
29
|
+
const provider = createMockProvider();
|
|
30
|
+
const createMock = provider.createMock;
|
|
31
|
+
generate = provider.generate;
|
|
32
|
+
generateGlobals = provider.generateGlobals;
|
|
33
|
+
/** @type {PkgbldRollupPlugin[]} */
|
|
34
|
+
const plugins = [];
|
|
35
|
+
return [
|
|
36
|
+
{
|
|
37
|
+
provide: (
|
|
38
|
+
/** @type {PkgbldRollupPlugin['plugin']} */ plugin,
|
|
39
|
+
/** @type {PkgbldRollupPlugin['priority']} */ priority,
|
|
40
|
+
/** @type {Omit<PkgbldRollupPlugin, 'plugin' | 'priority'>=} */ options
|
|
41
|
+
) => {
|
|
42
|
+
plugins.push({ priority, plugin, format: options?.format, inputs: options?.inputs, outputPlugin: options?.outputPlugin });
|
|
43
|
+
},
|
|
44
|
+
import: async (/** @type {string} */ name, /** @type {string=} */ exportName) => {
|
|
45
|
+
const result = await import(name);
|
|
46
|
+
const exports = result[exportName ?? 'default'];
|
|
47
|
+
const mangledName = camelCase(name);
|
|
48
|
+
imports.set(name, mangledName);
|
|
49
|
+
return createMock(exports, mangledName);
|
|
50
|
+
},
|
|
51
|
+
globalImport: (/** @type {string} */ module, /** @type {string | string[]=} */ exportName) => {
|
|
52
|
+
imports.set(module, exportName ?? 'default');
|
|
53
|
+
},
|
|
54
|
+
globalSetup: (/** @type {((...args: any[]) => any) | string} */ code) => {
|
|
55
|
+
if (typeof code === 'function') {
|
|
56
|
+
setup.add(code.toString());
|
|
57
|
+
return createMock(code, code.name);
|
|
58
|
+
}
|
|
59
|
+
setup.add(String(code));
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
plugins,
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {RollupOptions[]} config
|
|
68
|
+
* @param {string} pkgPath
|
|
69
|
+
* @param {BuildConfiguration} configuration
|
|
70
|
+
* @param {PackageProcessingResult} packageResult
|
|
71
|
+
* @param {ReturnType<import('./helpers.js').getHelpers>} helpers
|
|
72
|
+
* @param {PackageJson} pkg
|
|
73
|
+
*/
|
|
74
|
+
export async function ejectConfig(config, pkgPath, configuration, packageResult, helpers, pkg) {
|
|
75
|
+
const pkgName = /** @type {{ name: string }} */ (pkg).name;
|
|
76
|
+
|
|
77
|
+
const text = generate(config);
|
|
78
|
+
setup.add(generateGlobals());
|
|
79
|
+
|
|
80
|
+
setup.add(`const configuration = ${generate(configuration)}`);
|
|
81
|
+
setup.add(`const packageResult = { executableOutputs: ${generate(packageResult.executableOutputs)} }`);
|
|
82
|
+
setup.add(`const inputs = ${generate(packageResult.entries.values.map(entry => entry.sourcePath))}`);
|
|
83
|
+
|
|
84
|
+
if (configuration.outputs.formats.includes('umd')) {
|
|
85
|
+
imports.set('path', 'path');
|
|
86
|
+
imports.set('url', 'url');
|
|
87
|
+
setup.add(`const pkgName = ${generate(/** @type {never} */ (pkgName))}`);
|
|
88
|
+
setup.add(camelCase.toString());
|
|
89
|
+
setup.add(helpers.getGlobalName.toString());
|
|
90
|
+
setup.add("const __dirname = url.fileURLToPath(new URL('.', import.meta.url));");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const importsString = Array.from(imports)
|
|
94
|
+
.map(value => `import ${value[1]} from '${value[0]}';`)
|
|
95
|
+
.join('\n');
|
|
96
|
+
const setupString = Array.from(setup).join('\n');
|
|
97
|
+
|
|
98
|
+
const { minify } = await import('terser');
|
|
99
|
+
|
|
100
|
+
const result = await minify(`${importsString}\n${setupString}\nexport default ${text};`, {
|
|
101
|
+
module: true,
|
|
102
|
+
compress: {
|
|
103
|
+
booleans: false,
|
|
104
|
+
ecma: 2020,
|
|
105
|
+
module: true,
|
|
106
|
+
passes: 3,
|
|
107
|
+
unsafe: true,
|
|
108
|
+
},
|
|
109
|
+
mangle: false,
|
|
110
|
+
output: {
|
|
111
|
+
beautify: true,
|
|
112
|
+
ecma: 2020,
|
|
113
|
+
quote_style: 1,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
await fs.writeFile(path.join(path.dirname(pkgPath), 'rollup.config.mjs'), /** @type {string} */ (result.code));
|
|
117
|
+
|
|
118
|
+
await updatePackageJson(pkg);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @param {PackageJson} pkg
|
|
123
|
+
*/
|
|
124
|
+
async function updatePackageJson(pkg) {
|
|
125
|
+
if (typeof pkg.devDependencies !== 'object') {
|
|
126
|
+
pkg.devDependencies = {};
|
|
127
|
+
}
|
|
128
|
+
const devDependencies = pkg.devDependencies;
|
|
129
|
+
if ('pkgbld' in devDependencies) {
|
|
130
|
+
devDependencies.pkgbld = undefined;
|
|
131
|
+
}
|
|
132
|
+
devDependencies.rollup = /** @type {Record<string, string>} */ (pkgbldPkg.dependencies).rollup ?? '*';
|
|
133
|
+
const isBuiltin = (await import('is-builtin-module')).default;
|
|
134
|
+
for (const key of imports.keys()) {
|
|
135
|
+
const packageName = getPackageName(key);
|
|
136
|
+
if (!isBuiltin(packageName)) {
|
|
137
|
+
devDependencies[packageName] = /** @type {Record<string, string>} */ (pkgbldPkg.dependencies)[packageName] ?? '*';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @param {string} key
|
|
144
|
+
* @returns {string}
|
|
145
|
+
*/
|
|
146
|
+
function getPackageName(key) {
|
|
147
|
+
return key
|
|
148
|
+
.split('/')
|
|
149
|
+
.slice(0, key.startsWith('@') ? 2 : 1)
|
|
150
|
+
.join('/');
|
|
151
|
+
}
|
package/src/get-json.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('type-fest').JsonObject} JsonObject
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {string} fileName
|
|
10
|
+
* @returns {Promise<[string, JsonObject]>}
|
|
11
|
+
*/
|
|
12
|
+
export async function getJson(fileName) {
|
|
13
|
+
const pkgPath = path.resolve(fileName);
|
|
14
|
+
const buffer = await fs.readFile(pkgPath);
|
|
15
|
+
return [pkgPath, /** @type {JsonObject} */ (JSON.parse(buffer.toString()))];
|
|
16
|
+
}
|