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
|
||||
```
|
||||
|
||||
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):
|
||||
|
||||
```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
|
||||
execSync('npm run generate', { stdio: 'inherit', cwd: root });
|
||||
|
||||
|
|
|
|||
|
|
@ -1048,6 +1048,31 @@ describe('package scripts', () => {
|
|||
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', () => {
|
||||
const buildScript = readFileSync(
|
||||
path.join(root, 'scripts/build.js'),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue