chore(theme): dist 根 stub 清理归属钩子;build.format 显式契约
sf-literal-html-paths 钩子收尾清理 astro 5.18.2 内容层无条件发射的 content-assets.mjs/content-modules.mjs(content/consts.js ASSET_IMPORTS_FILE——本主题零内容集合,dist 树=target_file 面); build.format:'directory' 由缺省依赖升为显式契约,*.html.html 残留 自检守护折平前提(偏离即构建明错)。render-cases 钉死 dist 根无 stub。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,13 @@
|
|||||||
import { existsSync, renameSync, rmSync } from 'node:fs'
|
import { existsSync, readdirSync, renameSync, rmSync } from 'node:fs'
|
||||||
import { join, resolve } from 'node:path'
|
import { join, resolve } from 'node:path'
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
import { defineConfig } from 'astro/config'
|
import { defineConfig } from 'astro/config'
|
||||||
|
|
||||||
|
// dist 根 stub 清单(astro 5.18.2 content layer 无条件发射的空模块桩——content/consts.js
|
||||||
|
// 的 ASSET_IMPORTS_FILE='content-assets.mjs' / MODULES_IMPORTS_FILE='content-modules.mjs',
|
||||||
|
// 静态构建随 .astro/ 汇入 dist 根;本主题零内容集合,产物纯页面/媒体——桩归属主题清理)。
|
||||||
|
const DIST_ROOT_STUBS = ['content-assets.mjs', 'content-modules.mjs']
|
||||||
|
|
||||||
// 字面 .html 路径对齐(URL pathname 保真——快线 Task 4 钉死的映射规则之一):
|
// 字面 .html 路径对齐(URL pathname 保真——快线 Task 4 钉死的映射规则之一):
|
||||||
// Astro 页面产物在 build.format 三态下分别是 <path>/index.html(directory——尾斜杠路由
|
// Astro 页面产物在 build.format 三态下分别是 <path>/index.html(directory——尾斜杠路由
|
||||||
// 的正确形态)或 <path>.html(file/preserve——会给无后缀路由追加后缀)。两者都产不出与
|
// 的正确形态)或 <path>.html(file/preserve——会给无后缀路由追加后缀)。两者都产不出与
|
||||||
@@ -31,6 +36,22 @@ function literalHtmlPaths() {
|
|||||||
moved++
|
moved++
|
||||||
}
|
}
|
||||||
if (moved > 0) logger.info(`字面 .html 路径对齐:${moved} 页`)
|
if (moved > 0) logger.info(`字面 .html 路径对齐:${moved} 页`)
|
||||||
|
|
||||||
|
// format 契约自检:x.html.html 残留只在 format 偏离 directory(file/preserve 给
|
||||||
|
// .html 路由追加后缀)时出现——折平逻辑的前提破裂即明错,不留错形产物
|
||||||
|
const doubled = readdirSync(dist, { recursive: true }).filter(
|
||||||
|
(f) => typeof f === 'string' && f.replaceAll('\\', '/').endsWith('.html.html'),
|
||||||
|
)
|
||||||
|
if (doubled.length > 0) {
|
||||||
|
throw new Error(
|
||||||
|
`dist 出现 ${doubled.length} 个 *.html.html 残留(如 ${doubled[0]}):build.format 偏离 'directory'——字面 .html 折平前提破裂(Task 5 target_file 对齐将失真)`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dist 根 stub 清理(见 DIST_ROOT_STUBS 注记——内容层桩不是站点产物)
|
||||||
|
for (const stub of DIST_ROOT_STUBS) {
|
||||||
|
rmSync(join(dist, stub), { force: true })
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -40,10 +61,13 @@ function literalHtmlPaths() {
|
|||||||
// 单一入口),不设 site——canonical/og 的 origin 是每站点数据(site.json 的 origin),
|
// 单一入口),不设 site——canonical/og 的 origin 是每站点数据(site.json 的 origin),
|
||||||
// 不是主题级配置。@sf/contracts 直连源码(与根 tsconfig/vitest 同映射——契约包零依赖
|
// 不是主题级配置。@sf/contracts 直连源码(与根 tsconfig/vitest 同映射——契约包零依赖
|
||||||
// 纯 TS,vite 直接编译内联,无需预构建 dist)。
|
// 纯 TS,vite 直接编译内联,无需预构建 dist)。
|
||||||
|
// build.format='directory' 显式契约(非缺省依赖):尾斜杠路由 → <path>/index.html 是
|
||||||
|
// target_file 映射规则的半边——上面的 *.html.html 自检是其守卫。
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
output: 'static',
|
output: 'static',
|
||||||
srcDir: './src',
|
srcDir: './src',
|
||||||
outDir: './dist',
|
outDir: './dist',
|
||||||
|
build: { format: 'directory' },
|
||||||
integrations: [literalHtmlPaths()],
|
integrations: [literalHtmlPaths()],
|
||||||
vite: {
|
vite: {
|
||||||
resolve: {
|
resolve: {
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ describe('六类页面构建(astro build × render-input 夹具)', () => {
|
|||||||
// 404 独立静态页(Astro 特例 → 根级 404.html)
|
// 404 独立静态页(Astro 特例 → 根级 404.html)
|
||||||
expect(statSync(join(dist, '404.html')).isFile()).toBe(true)
|
expect(statSync(join(dist, '404.html')).isFile()).toBe(true)
|
||||||
expect(page('/')).toContain('demo-site')
|
expect(page('/')).toContain('demo-site')
|
||||||
|
// dist 根无内容层 stub(astro 5.18.2 无条件发射——钩子归属清理;dist 树=target_file 面)
|
||||||
|
expect(readdirSync(dist)).not.toContain('content-assets.mjs')
|
||||||
|
expect(readdirSync(dist)).not.toContain('content-modules.mjs')
|
||||||
})
|
})
|
||||||
|
|
||||||
it(`编码路径目录原样落盘:dist/${ENCODED}/ 字节不变(前置事实 7——禁 percent-decode)`, () => {
|
it(`编码路径目录原样落盘:dist/${ENCODED}/ 字节不变(前置事实 7——禁 percent-decode)`, () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user