-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.mjs
More file actions
80 lines (73 loc) · 3.37 KB
/
Copy pathbuild.mjs
File metadata and controls
80 lines (73 loc) · 3.37 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
import { execFile } from 'node:child_process';
import { readFile, readdir, rm, writeFile } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { promisify } from 'node:util';
import { fileURLToPath } from 'node:url';
import { build } from 'esbuild';
const execFileAsync = promisify(execFile);
const here = dirname(fileURLToPath(import.meta.url));
const dist = join(here, 'dist');
// The target is a fixed child of this repository, never a caller-provided path.
await rm(dist, { recursive: true, force: true });
await execFileAsync(
process.execPath,
[join(here, 'node_modules', 'typescript', 'bin', 'tsc'), '-p', join(here, 'tsconfig.build.json')],
{ cwd: here },
);
await useGridsBuiltEntryPoints();
await build({
// Complete public stack: the host port plus every control built against it.
// Bundled, so the grid is inlined here and no specifier survives to be
// resolved by whoever loads the file.
entryPoints: [join(here, 'src', 'index.ts')],
outfile: join(dist, 'sstradingcontrols.js'),
globalName: 'SSTradingControls',
bundle: true,
format: 'iife',
sourcemap: true,
target: 'es2020',
logLevel: 'info',
});
/// Move the emitted files — and only them — onto `@stocksharp/grids`'s BUILT
/// entry points.
///
/// The sources import the grid as `@stocksharp/grids/source/data-grid`, and that
/// is deliberate: `./source/*` is an unconditional path to the grid's own
/// TypeScript, which is what the two toolchains that compile these controls
/// from source both need. The terminal bundles them as .ts through esbuild, and
/// its unit tests bundle as CommonJS — while the grid's compiled entry points
/// declare only an `import` condition, so a CommonJS bundle cannot resolve them
/// at all.
///
/// It is exactly the wrong thing to publish, though. tsc copies an import
/// specifier through untouched, so without this the emitted `dist/esm/*.js`
/// would still say `./source/data-grid`, which resolves to a raw `.ts` file:
/// an adopter importing the package's own ESM entry gets ERR_MODULE_NOT_FOUND
/// from inside node_modules, on a package that installed cleanly.
///
/// Rewriting after the emit rather than switching the sources over keeps both
/// halves honest: source depends on the grid's source, dist depends on the
/// grid's dist, and neither has to be built for the other to work.
async function useGridsBuiltEntryPoints() {
const rewritten = [];
for (const path of await emittedFiles(dist)) {
const before = await readFile(path, 'utf8');
const after = before.replaceAll('@stocksharp/grids/source/', '@stocksharp/grids/');
if (after === before) continue;
await writeFile(path, after, 'utf8');
rewritten.push(path);
}
console.log(`grid specifiers moved to the built entry points in ${rewritten.length} emitted files`);
}
/// The JavaScript and the declarations tsc just wrote. Source maps are left
/// alone: they carry the original source, whose specifier is the correct one
/// for it.
async function emittedFiles(directory) {
const result = [];
for (const entry of await readdir(directory, { withFileTypes: true })) {
const path = join(directory, entry.name);
if (entry.isDirectory()) result.push(...await emittedFiles(path));
else if (entry.name.endsWith('.js') || entry.name.endsWith('.d.ts')) result.push(path);
}
return result;
}