Skip to content

Commit dddf539

Browse files
EurFeluxclaude
andauthored
fix(langs): declare all language packages as explicit dependencies (#760)
* fix(langs): declare all language packages as explicit dependencies The generated src/index.ts imports from 20+ @codemirror/lang-* and @codemirror/legacy-modes packages that were never declared in package.json. They only worked as phantom dependencies hoisted from @codemirror/language-data, which breaks under pnpm strict mode. - Enhance gen-langs-map.cjs to auto-sync package.json dependencies after generating the TypeScript file - Move @codemirror/language-data to devDependencies (only needed as input for the gen script, not at runtime) - Remove @codemirror/language-data from peerDependencies Fixes #759 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(langs): pin @codemirror/language-data to 6.5.2 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e1f67c4 commit dddf539

File tree

3 files changed

+110
-10
lines changed

3 files changed

+110
-10
lines changed

extensions/langs/gen-langs-map.cjs

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,6 @@ out += `// auto-generated by gen-langs-map.cjs – DO NOT EDIT\n`;
259259
out += importLines.join('\n') + (importLines.length ? '\n\n' : '');
260260
out += `export const langs = {\n`;
261261
for (const [k, v] of sorted) {
262-
const key = /^[a-z0-9_+-]+$/i.test(k) ? k : JSON.stringify(k);
263262
out += ` ${JSON.stringify(k)}: ${v},\n`;
264263
}
265264
out += `} satisfies Record<string, () => LanguageSupport | StreamLanguage<unknown>>;\n\n`;
@@ -270,4 +269,82 @@ out += `export function loadLanguage(name: LanguageName) {\n`;
270269
out += ` return langs[name] ? langs[name]() : null;\n`;
271270
out += `}\n`;
272271

273-
process.stdout.write(out);
272+
process.stdout.write(out);
273+
274+
// ── 自动同步 package.json 依赖 ──────────────────────────────────
275+
276+
function extractPkgName(modulePath) {
277+
// @scope/pkg/sub → @scope/pkg ; pkg/sub → pkg
278+
if (modulePath.startsWith('@')) {
279+
const parts = modulePath.split('/');
280+
return parts.slice(0, 2).join('/');
281+
}
282+
return modulePath.split('/')[0];
283+
}
284+
285+
function resolveVersionRange(pkgName) {
286+
// 先找本包 node_modules,再找 monorepo 根 node_modules
287+
const candidates = [
288+
path.resolve(__dirname, 'node_modules', pkgName, 'package.json'),
289+
path.resolve(__dirname, '../../node_modules', pkgName, 'package.json'),
290+
];
291+
for (const p of candidates) {
292+
if (fs.existsSync(p)) {
293+
const { version } = JSON.parse(fs.readFileSync(p, 'utf8'));
294+
const [major, minor] = version.split('.');
295+
// 0.x 版本下 ^0.0.0 范围太窄(仅匹配 <0.1.0),需用 ^0.minor.0
296+
return major === '0' ? `^0.${minor}.0` : `^${major}.0.0`;
297+
}
298+
}
299+
return null;
300+
}
301+
302+
// 1) 收集所有被导入的包名
303+
const allModules = new Set();
304+
305+
if (needsStreamLanguage) {
306+
allModules.add('@codemirror/language');
307+
}
308+
for (const mod of namedImports.keys()) {
309+
allModules.add(extractPkgName(mod));
310+
}
311+
for (const mod of starImports.keys()) {
312+
allModules.add(extractPkgName(mod));
313+
}
314+
// 硬编码的 @replit 包
315+
allModules.add('@replit/codemirror-lang-nix');
316+
allModules.add('@replit/codemirror-lang-svelte');
317+
allModules.add('@replit/codemirror-lang-solidity');
318+
319+
// 2) 读取 package.json 并合并依赖
320+
const pkgJsonPath = path.resolve(__dirname, 'package.json');
321+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
322+
const deps = pkgJson.dependencies || {};
323+
324+
const added = [];
325+
for (const mod of allModules) {
326+
if (deps[mod]) continue; // 已有声明的保留原版本号不动
327+
const range = resolveVersionRange(mod);
328+
if (range) {
329+
deps[mod] = range;
330+
added.push(` + ${mod}: ${range}`);
331+
} else {
332+
console.error(`[warn] 无法解析 ${mod} 的版本,跳过`);
333+
}
334+
}
335+
336+
// 按字母序排列
337+
const sortedDeps = {};
338+
for (const key of Object.keys(deps).sort()) {
339+
sortedDeps[key] = deps[key];
340+
}
341+
pkgJson.dependencies = sortedDeps;
342+
343+
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + '\n', 'utf8');
344+
345+
if (added.length) {
346+
console.error(`[gen-langs-map] 已向 package.json 新增 ${added.length} 个依赖:`);
347+
added.forEach(l => console.error(l));
348+
} else {
349+
console.error('[gen-langs-map] package.json 依赖已是最新,无需更新。');
350+
}

extensions/langs/package.json

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,31 @@
3030
"cjs"
3131
],
3232
"peerDependencies": {
33-
"@codemirror/language": ">=6.0.0",
34-
"@codemirror/language-data": ">=6.0.0"
33+
"@codemirror/language": ">=6.0.0"
3534
},
3635
"dependencies": {
36+
"@codemirror/lang-cpp": "^6.0.0",
37+
"@codemirror/lang-css": "^6.0.0",
38+
"@codemirror/lang-go": "^6.0.0",
39+
"@codemirror/lang-html": "^6.0.0",
40+
"@codemirror/lang-java": "^6.0.0",
41+
"@codemirror/lang-javascript": "^6.0.0",
42+
"@codemirror/lang-jinja": "^6.0.0",
43+
"@codemirror/lang-json": "^6.0.0",
44+
"@codemirror/lang-less": "^6.0.0",
45+
"@codemirror/lang-liquid": "^6.0.0",
46+
"@codemirror/lang-markdown": "^6.0.0",
47+
"@codemirror/lang-php": "^6.0.0",
48+
"@codemirror/lang-python": "^6.0.0",
49+
"@codemirror/lang-rust": "^6.0.0",
50+
"@codemirror/lang-sass": "^6.0.0",
51+
"@codemirror/lang-sql": "^6.0.0",
52+
"@codemirror/lang-vue": "^0.1.0",
53+
"@codemirror/lang-wast": "^6.0.0",
54+
"@codemirror/lang-xml": "^6.0.0",
55+
"@codemirror/lang-yaml": "^6.0.0",
3756
"@codemirror/language": "^6.0.0",
38-
"@codemirror/language-data": "^6.5.1",
57+
"@codemirror/legacy-modes": "^6.0.0",
3958
"@replit/codemirror-lang-nix": "^6.0.1",
4059
"@replit/codemirror-lang-solidity": "^6.0.1",
4160
"@replit/codemirror-lang-svelte": "^6.0.0",
@@ -58,6 +77,7 @@
5877
"devDependencies": {
5978
"@babel/generator": "^7.28.0",
6079
"@babel/parser": "^7.28.0",
61-
"@babel/traverse": "^7.28.0"
80+
"@babel/traverse": "^7.28.0",
81+
"@codemirror/language-data": "6.5.2"
6282
}
6383
}

extensions/langs/src/index.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { go } from '@codemirror/lang-go';
66
import { html } from '@codemirror/lang-html';
77
import { java } from '@codemirror/lang-java';
88
import { javascript } from '@codemirror/lang-javascript';
9+
import { jinja } from '@codemirror/lang-jinja';
910
import { json } from '@codemirror/lang-json';
1011
import { less } from '@codemirror/lang-less';
1112
import { liquid } from '@codemirror/lang-liquid';
@@ -50,7 +51,6 @@ import { haskell } from '@codemirror/legacy-modes/mode/haskell';
5051
import { haxe, hxml } from '@codemirror/legacy-modes/mode/haxe';
5152
import { idl } from '@codemirror/legacy-modes/mode/idl';
5253
import { jsonld } from '@codemirror/legacy-modes/mode/javascript';
53-
import { jinja2 } from '@codemirror/legacy-modes/mode/jinja2';
5454
import { julia } from '@codemirror/legacy-modes/mode/julia';
5555
import { liveScript } from '@codemirror/legacy-modes/mode/livescript';
5656
import { lua } from '@codemirror/legacy-modes/mode/lua';
@@ -195,11 +195,11 @@ export const langs = {
195195
ini: () => StreamLanguage.define(properties),
196196
ino: () => cpp(),
197197
intr: () => StreamLanguage.define(dylan),
198-
j2: () => StreamLanguage.define(jinja2),
198+
j2: () => jinja(),
199199
jade: () => StreamLanguage.define(pug),
200200
java: () => java(),
201-
jinja: () => StreamLanguage.define(jinja2),
202-
jinja2: () => StreamLanguage.define(jinja2),
201+
jinja: () => jinja(),
202+
jinja2: () => jinja(),
203203
jl: () => StreamLanguage.define(julia),
204204
js: () => javascript(),
205205
json: () => json(),
@@ -323,7 +323,10 @@ export const langs = {
323323
wl: () => StreamLanguage.define(mathematica),
324324
wls: () => StreamLanguage.define(mathematica),
325325
xml: () => xml(),
326+
xq: () => StreamLanguage.define(xQuery),
327+
xqm: () => StreamLanguage.define(xQuery),
326328
xquery: () => StreamLanguage.define(xQuery),
329+
xqy: () => StreamLanguage.define(xQuery),
327330
xsd: () => xml(),
328331
xsl: () => xml(),
329332
xu: () => StreamLanguage.define(xu),

0 commit comments

Comments
 (0)