@@ -45,8 +45,8 @@ describe("vendorGroupOf 钉值", () => {
4545 [ "/r/node_modules/hast-util-to-text/lib/index.js" , "vendor-katex" ] ,
4646 [ "/r/node_modules/hast-util-from-dom/lib/index.js" , "vendor-katex" ] ,
4747 [ "/r/node_modules/hast-util-to-jsx-runtime/lib/index.js" , "vendor-md" ] ,
48- [ "/r/node_modules/property-information/lib/index.js" , "vendor-katex " ] ,
49- [ "/r/node_modules/hastscript/index.js" , "vendor-katex " ] ,
48+ [ "/r/node_modules/property-information/lib/index.js" , "vendor-md " ] ,
49+ [ "/r/node_modules/hastscript/index.js" , "vendor-md " ] ,
5050 [ "/r/node_modules/@tauri-apps/api/core.js" , "vendor-tauri" ] ,
5151 [ "/r/node_modules/@tauri-apps/plugin-dialog/dist-js/index.js" , "vendor-tauri" ] ,
5252 [ "/r/node_modules/codemirror/dist/index.js" , "vendor-editor" ] ,
@@ -131,9 +131,9 @@ const EXACT_PINS: readonly (readonly [string, VendorGroup])[] = [
131131 [ "hast-util-from-html-isomorphic" , "vendor-katex" ] ,
132132 [ "hast-util-is-element" , "vendor-katex" ] ,
133133 [ "hast-util-parse-selector" , "vendor-katex" ] ,
134- [ "hastscript " , "vendor-katex " ] ,
135- [ "property-information " , "vendor-katex " ] ,
136- [ "web-namespaces" , "vendor-katex " ] ,
134+ [ "property-information " , "vendor-md " ] ,
135+ [ "hastscript " , "vendor-md " ] ,
136+ [ "web-namespaces" , "vendor-md " ] ,
137137 [ "codemirror" , "vendor-editor" ] ,
138138 [ "crelt" , "vendor-editor" ] ,
139139 [ "style-mod" , "vendor-editor" ] ,
@@ -249,3 +249,44 @@ describe("接线面全量一致(manualChunks 不许有第二套逻辑)", ()
249249 expect ( ids . map ( manualChunks ) ) . toEqual ( ids . map ( ( id ) => vendorGroupOf ( id ) ) ) ;
250250 } ) ;
251251} ) ;
252+
253+ // Task 5(不装 GSAP):预留槽 + 循环 chunk 的**反例守卫**。槽位本身见 EXACT 的 gsap 两行。
254+ describe ( "批 6 预留:GSAP 必须落进独立 chunk(本批不安装 GSAP)" , ( ) => {
255+ it ( "GSAP 的两个包名都归 vendor-gsap,且与 react 不同组" , ( ) => {
256+ const gsap = vendorGroupOf ( "/r/node_modules/gsap/index.js" ) ;
257+ const gsapReact = vendorGroupOf ( "/r/node_modules/@gsap/react/dist/index.js" ) ;
258+ expect ( gsap ) . toBe ( "vendor-gsap" ) ;
259+ expect ( gsapReact ) . toBe ( "vendor-gsap" ) ;
260+ expect ( gsap ) . not . toBe ( vendorGroupOf ( "/r/node_modules/react/index.js" ) ) ;
261+ } ) ;
262+
263+ it ( "槽位在表里,且 package.json 此刻没有 gsap(两半必须同时成立)" , ( ) => {
264+ // 只查 package.json ⇒ 槽位被删也通过;只查表 ⇒ 批 6 装了依赖却没人复核产物也通过。
265+ // devDependencies 也查:本段问的是「gsap 装了没有」,不是「它进不进浏览器产物」。
266+ const pkg = JSON . parse ( readFileSync ( join ( HERE , ".." , ".." , "package.json" ) , "utf8" ) ) as {
267+ dependencies ?: Record < string , string > ;
268+ devDependencies ?: Record < string , string > ;
269+ } ;
270+ const all = { ...( pkg . dependencies ?? { } ) , ...( pkg . devDependencies ?? { } ) } ;
271+ // 批 6 装上后这条会红 ⇒ 去构建一次,核对 vendor-gsap chunk 独立生成且只经 import() 到达。
272+ expect ( Object . keys ( all ) . filter ( ( d ) => d === "gsap" || d === "@gsap/react" ) ) . toEqual ( [ ] ) ;
273+ expect ( vendorGroupOf ( "/r/node_modules/gsap/index.js" ) ) . toBe ( "vendor-gsap" ) ;
274+ } ) ;
275+
276+ it ( "反例:槽位不得被任何前缀规则吞掉(防将来有人加宽前缀)" , ( ) => {
277+ expect ( vendorGroupOf ( "/r/node_modules/gsap-core/index.js" ) ) . toBeUndefined ( ) ;
278+ expect ( vendorGroupOf ( "/r/node_modules/not-gsap/index.js" ) ) . toBeUndefined ( ) ;
279+ } ) ;
280+ } ) ;
281+
282+ // 实测(Task 4):vite 警告 `Circular chunk: vendor-katex -> vendor-md -> vendor-katex`,两 chunk
283+ // 首行互指 ⇒ 130.66 kB gzip 熔成不可分簇。断环只靠**方向**(不靠把 katex 并进 md —— 那会被
284+ // 上面的 EXACT 钉值表抓住):md→katex 的桥留在 md 侧,katex→md 的单向边保留。
285+ describe ( "循环 chunk 反例守卫(vendor-md ⇄ vendor-katex 不许成环)" , ( ) => {
286+ it ( "md→katex 的桥(property-information 族)必须留在 vendor-md" , ( ) => {
287+ for ( const n of [ "property-information" , "hastscript" , "web-namespaces" ] ) {
288+ expect ( EXACT [ n ] ) . toBe ( "vendor-md" ) ;
289+ expect ( vendorGroupOf ( `/r/node_modules/${ n } /index.js` ) ) . toBe ( "vendor-md" ) ;
290+ }
291+ } ) ;
292+ } ) ;
0 commit comments