@mirta/rollup 0.3.2 → 0.3.4
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/index.d.mts +1 -0
- package/dist/index.mjs +185 -26
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import commonjs from '@rollup/plugin-commonjs';
|
|
|
4
4
|
import replace from '@rollup/plugin-replace';
|
|
5
5
|
import dts from 'rollup-plugin-dts';
|
|
6
6
|
import { deleteAsync } from 'del';
|
|
7
|
-
import nodePath
|
|
7
|
+
import nodePath from 'node:path';
|
|
8
8
|
import { readFileSync } from 'fs';
|
|
9
9
|
import multi from '@rollup/plugin-multi-entry';
|
|
10
10
|
import ts$1 from 'rollup-plugin-typescript2';
|
|
@@ -37,62 +37,223 @@ function del(options = {}) {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
class BuildError extends Error {
|
|
41
|
+
constructor(message) {
|
|
42
|
+
super(message);
|
|
43
|
+
// Убедимся, что экземпляр имеет правильный прототип
|
|
44
|
+
Object.setPrototypeOf(this, BuildError.prototype);
|
|
45
|
+
this.name = 'BuildError';
|
|
46
|
+
this.message = message;
|
|
47
|
+
Error.captureStackTrace(this, BuildError);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const dtsOutputDir = 'dist/dts';
|
|
51
|
+
function normalizeInput(input) {
|
|
52
|
+
const inputs = [];
|
|
53
|
+
// Нормализация входных данных.
|
|
54
|
+
// Строка, массив или объект преобразуются в единый массив строк inputs.
|
|
55
|
+
if (typeof input === 'string') {
|
|
56
|
+
inputs.push(input);
|
|
57
|
+
}
|
|
58
|
+
else if (Array.isArray(input)) {
|
|
59
|
+
inputs.push(...input);
|
|
60
|
+
}
|
|
61
|
+
else if (typeof input === 'object') {
|
|
62
|
+
inputs.push(...Object.values(input));
|
|
63
|
+
}
|
|
64
|
+
if (inputs.length === 0)
|
|
65
|
+
throw new BuildError('[Mirta Rollup] Input configuration cannot be empty');
|
|
66
|
+
return inputs;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Связывает исходные файлы проекта (`src/...`) с точками входа,
|
|
70
|
+
* определенными в `package.exports`. Ее основная цель — создать
|
|
71
|
+
* отображение между входными файлами (например, `src/index.ts`)
|
|
72
|
+
* и их выходными файлами (например, `dist/index.js`), а также источниками типов (`.d.ts`).
|
|
73
|
+
*
|
|
74
|
+
* @param inputs Массив путей к исходным файлам (например, `['src/index.ts', 'src/utils.ts']`)
|
|
75
|
+
* @param exports Объект из `package.exports`, описывающий точки входа пакета.
|
|
76
|
+
*
|
|
77
|
+
**/
|
|
78
|
+
function getInputBindings(inputs, exports) {
|
|
79
|
+
if (!inputs.length || !exports)
|
|
80
|
+
return {};
|
|
81
|
+
const candidates = {};
|
|
82
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
83
|
+
if (!value.import?.default || !key.startsWith('.'))
|
|
84
|
+
continue;
|
|
85
|
+
// Формируем outputFile на основе данных package.json,
|
|
86
|
+
// убирая префикс `dist/` из путей, так как он
|
|
87
|
+
// уже указан в настройках сборки (output.dir).
|
|
88
|
+
//
|
|
89
|
+
const outputFile = value.import.default.startsWith('./dist/')
|
|
90
|
+
? value.import.default.slice(7)
|
|
91
|
+
: value.import.default;
|
|
92
|
+
const source = key === '.' ? 'index' : key.slice(2);
|
|
93
|
+
// Генерация кандидатов для входных файлов.
|
|
94
|
+
//
|
|
95
|
+
// Для каждого ключа экспорта создает возможные пути
|
|
96
|
+
// к исходным файлам (например, `src/utils.ts` и `src/utils/index.ts`),
|
|
97
|
+
// учитывая как явные, так и неявные структуры каталогов.
|
|
98
|
+
Object.assign(candidates, {
|
|
99
|
+
// Варианты явного пути (например, `src/setup.ts`)
|
|
100
|
+
[`src/${source}.ts`]: { key, outputFile, dtsSource: source },
|
|
101
|
+
[`src/${source}.js`]: { key, outputFile, dtsSource: source },
|
|
102
|
+
// Варианты неявного пути (например, `src/setup/index.ts`):
|
|
103
|
+
[`src/${source}/index.ts`]: { key, outputFile, dtsSource: `${source}/index` },
|
|
104
|
+
[`src/${source}/index.js`]: { key, outputFile, dtsSource: `${source}/index` },
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
const result = {};
|
|
108
|
+
// Сопоставление с реальными входными файлами.
|
|
109
|
+
//
|
|
110
|
+
// Ппроверяет, какие из сгенерированных путей действительно существуют в массиве inputs.
|
|
111
|
+
//
|
|
112
|
+
for (const input of inputs) {
|
|
113
|
+
const entry = candidates[input];
|
|
114
|
+
// Если точка входа не ассоциирована с конфигурацией `package.json` — выбрасываем ошибку и прерываем сборку.
|
|
115
|
+
if (!entry)
|
|
116
|
+
throw new BuildError(`[Mirta Rollup] The input file "${input}" is not associated with corresponding export in the package.json`);
|
|
117
|
+
// Формирует итоговый объект result, где ключи — это точки входа из package.exports,
|
|
118
|
+
// а значения — связи между исходными файлами, выходными файлами и источниками типов.
|
|
119
|
+
//
|
|
120
|
+
result[entry.key] = {
|
|
121
|
+
sourceFile: input,
|
|
122
|
+
outputFile: entry.outputFile,
|
|
123
|
+
dtsSource: entry.dtsSource,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
127
|
+
if ((!value.import?.default && value.import?.types))
|
|
128
|
+
continue;
|
|
129
|
+
if (!(key in result))
|
|
130
|
+
throw new BuildError(`[Mirta Rollup] Export "${key}" defined in package.json has no corresponding input file in Rollup configuration`);
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Создаёт отображение между файлами типов `.d.ts` и их выходными путями
|
|
136
|
+
* на основе данных из `package.exports` и ранее сформированных связей ({@link inputBindings})
|
|
137
|
+
*
|
|
138
|
+
* @param inputBindings
|
|
139
|
+
* @param exports
|
|
140
|
+
* @returns
|
|
141
|
+
*/
|
|
142
|
+
function getDtsMappings(inputBindings, exports) {
|
|
143
|
+
if (!exports)
|
|
144
|
+
return {};
|
|
145
|
+
const result = {};
|
|
146
|
+
// Для каждой точки входа из package.exports
|
|
147
|
+
//
|
|
148
|
+
for (const [key, value] of Object.entries(exports)) {
|
|
149
|
+
// Где указан import.types
|
|
150
|
+
//
|
|
151
|
+
if (!value.import?.types || !key.startsWith('.'))
|
|
152
|
+
continue;
|
|
153
|
+
// Определяет путь к выходному файлу типов, убирая префикс `./dist/`
|
|
154
|
+
//
|
|
155
|
+
const outputFile = value.import.types.startsWith('./dist/')
|
|
156
|
+
? value.import.types.slice(7)
|
|
157
|
+
: value.import.types;
|
|
158
|
+
const binding = inputBindings[key];
|
|
159
|
+
// Если для указанного ключа отсутствует точка входа — выбрасываем ошибку и прерываем сборку.
|
|
160
|
+
if (!binding)
|
|
161
|
+
throw new BuildError(`[Mirta Rollup] Type definition "${outputFile}" has no corresponding input file`);
|
|
162
|
+
// Связывает с исходным файлом типов.
|
|
163
|
+
//
|
|
164
|
+
const dtsSource = binding.dtsSource;
|
|
165
|
+
result[`${dtsOutputDir}/${dtsSource}.d.ts`] = outputFile;
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
40
169
|
// Проверка TypeScript выполняется только для первой конфигурации.
|
|
41
170
|
let hasTsChecked = false;
|
|
42
|
-
let typesOutFile;
|
|
43
171
|
function definePackageConfig(options) {
|
|
44
|
-
const { cwd = process.cwd(), external = [], plugins } = options;
|
|
45
|
-
const pkgPath = resolve(cwd, 'package.json');
|
|
172
|
+
const { cwd = process.cwd(), input = 'src/index.ts', external = [], plugins, } = options;
|
|
173
|
+
const pkgPath = nodePath.resolve(cwd, 'package.json');
|
|
46
174
|
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
47
|
-
const { exports
|
|
48
|
-
typesOutFile = root?.import?.types;
|
|
175
|
+
const { exports = {} } = pkg;
|
|
49
176
|
const externalModules = [
|
|
50
177
|
/node_modules/,
|
|
51
178
|
pkgPath,
|
|
52
179
|
...external,
|
|
53
180
|
];
|
|
181
|
+
const inputBindings = getInputBindings(normalizeInput(input), exports);
|
|
182
|
+
const outputMappings = Object.keys(inputBindings)
|
|
183
|
+
.reduce((mappings, nextKey) => {
|
|
184
|
+
const inputMap = inputBindings[nextKey];
|
|
185
|
+
mappings[inputMap.sourceFile] = inputMap.outputFile;
|
|
186
|
+
return mappings;
|
|
187
|
+
}, {});
|
|
188
|
+
const dtsMappings = getDtsMappings(inputBindings, exports);
|
|
189
|
+
const dtsInputs = Object.keys(dtsMappings);
|
|
54
190
|
const rollupConfigs = [
|
|
55
191
|
createBuildConfig('mjs', {
|
|
56
192
|
cwd,
|
|
193
|
+
input,
|
|
57
194
|
external: externalModules,
|
|
195
|
+
emitDeclarations: dtsInputs.length > 0,
|
|
196
|
+
plugins,
|
|
58
197
|
output: {
|
|
59
|
-
|
|
198
|
+
dir: 'dist/',
|
|
60
199
|
format: 'es',
|
|
61
200
|
importAttributesKey: 'with',
|
|
62
|
-
|
|
201
|
+
entryFileNames(chunk) {
|
|
202
|
+
if (chunk.facadeModuleId) {
|
|
203
|
+
const localPath = nodePath
|
|
204
|
+
.relative(cwd, chunk.facadeModuleId)
|
|
205
|
+
.replaceAll(nodePath.sep, nodePath.posix.sep);
|
|
206
|
+
if (outputMappings[localPath])
|
|
207
|
+
return outputMappings[localPath];
|
|
208
|
+
}
|
|
209
|
+
return `${chunk.name}.mjs`;
|
|
210
|
+
},
|
|
211
|
+
chunkFileNames: '[name].mjs',
|
|
212
|
+
},
|
|
213
|
+
}),
|
|
63
214
|
];
|
|
64
|
-
if (
|
|
215
|
+
if (dtsInputs.length > 0) {
|
|
65
216
|
rollupConfigs.push({
|
|
66
|
-
input:
|
|
217
|
+
input: dtsInputs,
|
|
67
218
|
external: externalModules,
|
|
68
219
|
plugins: [
|
|
69
220
|
nodeResolve(),
|
|
70
221
|
commonjs(),
|
|
71
222
|
dts(),
|
|
72
223
|
del({
|
|
73
|
-
targets: [
|
|
224
|
+
targets: [dtsOutputDir],
|
|
74
225
|
hook: 'closeBundle',
|
|
75
226
|
}),
|
|
76
227
|
],
|
|
77
|
-
output:
|
|
78
|
-
|
|
79
|
-
|
|
228
|
+
output: {
|
|
229
|
+
dir: 'dist/',
|
|
230
|
+
format: 'es',
|
|
231
|
+
entryFileNames(chunk) {
|
|
232
|
+
if (chunk.facadeModuleId) {
|
|
233
|
+
const localPath = nodePath
|
|
234
|
+
.relative(cwd, chunk.facadeModuleId)
|
|
235
|
+
.replaceAll(nodePath.sep, nodePath.posix.sep);
|
|
236
|
+
if (dtsMappings[localPath])
|
|
237
|
+
return dtsMappings[localPath];
|
|
238
|
+
}
|
|
239
|
+
return `${chunk.name}.mts`;
|
|
240
|
+
},
|
|
241
|
+
},
|
|
80
242
|
});
|
|
81
243
|
}
|
|
82
244
|
return rollupConfigs;
|
|
83
245
|
}
|
|
84
|
-
function createBuildConfig(buildName, options
|
|
85
|
-
const { cwd, external, output } = options;
|
|
246
|
+
function createBuildConfig(buildName, options) {
|
|
247
|
+
const { cwd, external, input, emitDeclarations, plugins = [], output } = options;
|
|
86
248
|
output.sourcemap = !!process.env.SOURCE_MAP;
|
|
87
249
|
output.externalLiveBindings = false;
|
|
88
|
-
|
|
250
|
+
process.env.NODE_ENV === 'production';
|
|
89
251
|
const tsPlugin = ts({
|
|
90
|
-
tsconfig: resolve(cwd, './tsconfig.build.json'),
|
|
91
|
-
// cacheRoot: resolve(rootDir, './node_modules/.rts2_cache'),
|
|
252
|
+
tsconfig: nodePath.resolve(cwd, './tsconfig.build.json'),
|
|
92
253
|
compilerOptions: {
|
|
93
254
|
noCheck: hasTsChecked,
|
|
94
|
-
declaration:
|
|
95
|
-
declarationDir:
|
|
255
|
+
declaration: emitDeclarations,
|
|
256
|
+
declarationDir: emitDeclarations ? dtsOutputDir : void 0,
|
|
96
257
|
},
|
|
97
258
|
exclude: [
|
|
98
259
|
'packages/*/tests',
|
|
@@ -102,7 +263,7 @@ function createBuildConfig(buildName, options, plugins = []) {
|
|
|
102
263
|
// выполняются единожды - для первой конфигурации.
|
|
103
264
|
hasTsChecked = true;
|
|
104
265
|
return {
|
|
105
|
-
input
|
|
266
|
+
input,
|
|
106
267
|
external,
|
|
107
268
|
plugins: [
|
|
108
269
|
tsPlugin,
|
|
@@ -121,6 +282,7 @@ function createBuildConfig(buildName, options, plugins = []) {
|
|
|
121
282
|
}
|
|
122
283
|
function createReplacePlugin(isProduction, isBundlerEsmBuild, isNodeBuild) {
|
|
123
284
|
const replacements = {
|
|
285
|
+
// Preserve to be handled by bundlers
|
|
124
286
|
__DEV__: `(process.env.NODE_ENV !== 'production')`
|
|
125
287
|
,
|
|
126
288
|
__TEST__: `(process.env.NODE_ENV === 'test')`
|
|
@@ -277,7 +439,6 @@ function getEntry(path) {
|
|
|
277
439
|
}
|
|
278
440
|
function defineRuntimeConfig(options = {}) {
|
|
279
441
|
const { cwd = process.cwd(), external, monorepo, dotenv: dotenvOptions = {}, plugins = [], } = options;
|
|
280
|
-
const rootDir = monorepo?.rootDir;
|
|
281
442
|
const defaultPlugins = [
|
|
282
443
|
del({
|
|
283
444
|
targets: 'dist/*',
|
|
@@ -288,9 +449,7 @@ function defineRuntimeConfig(options = {}) {
|
|
|
288
449
|
}),
|
|
289
450
|
nodeResolve(),
|
|
290
451
|
ts$1({
|
|
291
|
-
|
|
292
|
-
? nodePath.resolve(rootDir, './node_modules/.rts2_cache')
|
|
293
|
-
: void 0,
|
|
452
|
+
clean: true,
|
|
294
453
|
}),
|
|
295
454
|
wbRulesImports(),
|
|
296
455
|
dotenv(dotenvOptions),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mirta/rollup",
|
|
3
3
|
"description": "Predefined Rollup configuration for wb-rules project builds.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.4",
|
|
5
5
|
"license": "Unlicense",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mirta",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"rollup-plugin-dts": "^6.2.3",
|
|
46
46
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
47
47
|
"typescript": "^5.8.3",
|
|
48
|
-
"@mirta/polyfills": "0.3.
|
|
48
|
+
"@mirta/polyfills": "0.3.4"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"rollup": "^4.52.4"
|