-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.config.mjs
More file actions
127 lines (118 loc) · 4.51 KB
/
Copy pathbuild.config.mjs
File metadata and controls
127 lines (118 loc) · 4.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import * as esbuild from 'esbuild';
import { existsSync, readFileSync, rmSync } from 'fs';
import { fileURLToPath } from 'url';
import path from 'path';
import { createRequire } from 'module';
import { execFileSync } from 'child_process';
const currentFile = fileURLToPath(import.meta.url);
const currentDir = path.dirname(currentFile);
const entryPoint = path.resolve(currentDir, 'src', 'components', 'index.ts');
const require = createRequire(import.meta.url);
const LocalizationGenerator = require('./scripts/localizationGenerator');
const localizationPlugin = {
name: 'localization-plugin',
setup(build) {
build.onStart(async () => {
try {
const localizationGenerator = new LocalizationGenerator();
localizationGenerator.generateLocalizationFile();
} catch (error) {
process.stderr.write(
`Localization generation failed during build startup: ${error.message ?? error}\n`
);
throw error;
}
});
},
};
if (!existsSync(entryPoint)) {
process.stdout.write(
'Skipping build because this bootstrap PR does not include src/components/index.ts yet.\n'
);
process.exit(0);
}
async function generateTypeDeclarations() {
// esbuild does not emit type declarations, so the library's published `.d.ts`
// is produced in two steps: tsc emits per-file declarations (keeping the `@/*`
// path aliases) under temp/dts, then API Extractor rolls them into a single
// self-contained build/index.d.ts (resolving the aliases and inlining internals).
//
// tsc does not prune stale declarations for deleted/renamed sources, so a reused
// temp/dts could feed API Extractor leftover files and make the rollup depend on
// build history. Start from a clean intermediate directory for a deterministic result.
const dtsOutDir = path.resolve(currentDir, 'temp', 'dts');
rmSync(dtsOutDir, { recursive: true, force: true });
const tscBin = require.resolve('typescript/bin/tsc');
execFileSync(process.execPath, [tscBin, '-p', path.resolve(currentDir, 'tsconfig.dts.json')], {
stdio: 'inherit',
cwd: currentDir,
});
const { Extractor, ExtractorConfig } = await import('@microsoft/api-extractor');
const extractorConfig = ExtractorConfig.loadFileAndPrepare(
path.resolve(currentDir, 'api-extractor.json')
);
const result = Extractor.invoke(extractorConfig, {
localBuild: true,
showVerboseMessages: false,
});
if (!result.succeeded) {
throw new Error(
`API Extractor failed with ${result.errorCount} error(s) and ${result.warningCount} warning(s).`
);
}
// Invariant: the rollup must be self-contained. Fail the build if any internal
// `@/*` path-alias reference leaked through instead of being inlined — such a file
// would not resolve for consumers of the published package. Covers every alias form
// emitted into a `.d.ts`: `from "@/…"`, side-effect `import "@/…"`, and inline
// dynamic-import types `import("@/…").Type`.
const rollupPath = path.resolve(currentDir, 'build', 'index.d.ts');
if (/(?:\bfrom\s+|\bimport\s*\(?\s*)['"]@\//.test(readFileSync(rollupPath, 'utf8'))) {
throw new Error(
'build/index.d.ts contains unresolved "@/..." path-alias imports; the API Extractor rollup did not inline them.'
);
}
}
esbuild
.build({
outdir: path.resolve(currentDir, 'build'),
entryPoints: [entryPoint],
entryNames: '[name]',
bundle: true,
minify: true,
format: 'esm',
outExtension: { '.js': '.mjs' },
// Externalize only peer dependencies — the consumer provides them. Swiper is a
// direct dependency (not a peer), so it and its carousel CSS must stay bundled
// into build/index.css (exported as `@vilnacrm/ui-toolkit/styles.css`); blanket
// `packages: 'external'` would drop those required styles from the library.
external: [
'react',
'react-dom',
'react/jsx-runtime',
'react/jsx-dev-runtime',
'@mui/*',
'@emotion/*',
'react-hook-form',
'i18next',
'react-i18next',
],
tsconfig: path.resolve(currentDir, 'tsconfig.json'),
sourcemap: true,
target: ['es2020'],
loader: {
'.js': 'jsx',
'.svg': 'dataurl',
'.css': 'css',
'.ttf': 'file',
},
resolveExtensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.svg'],
plugins: [localizationPlugin],
define: {
'process.env.NODE_ENV': '"production"',
},
})
.then(generateTypeDeclarations)
.catch(error => {
process.stderr.write(`Build failed: ${error.message ?? error}\n`);
process.exit(1);
});