mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-10-19 04:41:56 +00:00
fix(build): re-apply the ink patch when install skipped lifecycle scripts (#14170)
packages/cli compiles against ink frame-controller types that only patches/ink+7.0.3.patch adds; pristine ink@7.0.3 exports none of them. That patch reaches node_modules through the root postinstall, so an install that skipped lifecycle scripts (--ignore-scripts, or ignore-scripts=true in the user's npm/pnpm config) leaves pristine ink in place and the build fails with ~50 errors that all blame ink -- which sends a reporter to compare ink versions on npm instead of to the missing patch. Because noEmitOnError is unset, tsc still emitted a dist that runs with text selection broken. scripts/build.js already heals a missing node_modules; heal a missing patch the same way. frame-controller.d.ts is created by that patch and absent from pristine ink@7.0.3, so its absence is the signal. If re-applying still does not produce it, name the patch rather than letting tsc point at ink. Fixes #14110 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
4b6b4270d0
commit
bab0e99d89
3 changed files with 47 additions and 0 deletions
|
|
@ -110,6 +110,8 @@ To install dependencies defined in `package.json` as well as root dependencies,
|
||||||
corepack pnpm install --frozen-lockfile
|
corepack pnpm install --frozen-lockfile
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The install also applies `patches/ink+7.0.3.patch` through the root `postinstall` (`patch-package`). `packages/cli` compiles against the `ink` frame-controller types that patch adds, and no published `ink` release exports them, so an install that skipped lifecycle scripts (`--ignore-scripts`, or `ignore-scripts=true` in your npm/pnpm config) leaves the build failing with many `Module 'ink' has no exported member ...` errors. `npm run build` re-applies the patch when it is missing; to apply it by hand, run `npm run postinstall`.
|
||||||
|
|
||||||
To build the entire project (all packages):
|
To build the entire project (all packages):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,26 @@ if (!existsSync(join(root, 'node_modules'))) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The root postinstall applies patches/ink+7.0.3.patch, and packages/cli
|
||||||
|
// compiles against ink types only that patch adds: an install that skipped
|
||||||
|
// lifecycle scripts fails the build with ~50 errors that all blame ink. The
|
||||||
|
// patch creates frame-controller.d.ts, which pristine ink@7.0.3 lacks.
|
||||||
|
const inkFrameController = join(
|
||||||
|
root,
|
||||||
|
'node_modules/ink/build/frame-controller.d.ts',
|
||||||
|
);
|
||||||
|
if (!existsSync(inkFrameController)) {
|
||||||
|
execSync('npm run postinstall', { stdio: 'inherit', cwd: root });
|
||||||
|
if (!existsSync(inkFrameController)) {
|
||||||
|
console.error(
|
||||||
|
'build: patches/ink+7.0.3.patch is not applied to node_modules/ink, so\n' +
|
||||||
|
'packages/cli cannot typecheck against it. Run "npm run postinstall"\n' +
|
||||||
|
'and resolve what patch-package reports.',
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// build all workspaces/packages in dependency order
|
// build all workspaces/packages in dependency order
|
||||||
execSync('npm run generate', { stdio: 'inherit', cwd: root });
|
execSync('npm run generate', { stdio: 'inherit', cwd: root });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1048,6 +1048,31 @@ describe('package scripts', () => {
|
||||||
expect(readPackageJson().workspaces).toContain('packages/*');
|
expect(readPackageJson().workspaces).toContain('packages/*');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('detects an unapplied ink patch by a file the patch creates', () => {
|
||||||
|
const buildScript = readFileSync(
|
||||||
|
path.join(root, 'scripts/build.js'),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
const sentinel = buildScript.match(
|
||||||
|
/'node_modules\/ink\/build\/([^']+)'/,
|
||||||
|
)?.[1];
|
||||||
|
expect(sentinel).toBeDefined();
|
||||||
|
expect(buildScript).toContain('npm run postinstall');
|
||||||
|
|
||||||
|
const inkPatch = readdirSync(path.join(root, 'patches')).find((name) =>
|
||||||
|
name.startsWith('ink+'),
|
||||||
|
);
|
||||||
|
expect(inkPatch).toBeDefined();
|
||||||
|
const created = readFileSync(path.join(root, 'patches', inkPatch), 'utf8')
|
||||||
|
.split(/^diff --git /m)
|
||||||
|
.find((file) =>
|
||||||
|
file.startsWith(`a/node_modules/ink/build/${sentinel} b/node_modules/`),
|
||||||
|
);
|
||||||
|
// The sentinel only proves the patch is missing if no published ink ships
|
||||||
|
// it, i.e. the patch must create the file rather than edit an existing one.
|
||||||
|
expect(created).toContain('new file mode');
|
||||||
|
});
|
||||||
|
|
||||||
it('selects the CLI dependency closure without selecting the same-named root', () => {
|
it('selects the CLI dependency closure without selecting the same-named root', () => {
|
||||||
const buildScript = readFileSync(
|
const buildScript = readFileSync(
|
||||||
path.join(root, 'scripts/build.js'),
|
path.join(root, 'scripts/build.js'),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue