diff --git a/.changeset/angry-carrots-occur.md b/.changeset/angry-carrots-occur.md new file mode 100644 index 0000000000..35056e02a9 --- /dev/null +++ b/.changeset/angry-carrots-occur.md @@ -0,0 +1,5 @@ +--- +'@ice/app': minor +--- + +feat: support htmlGeneratingMode option diff --git a/packages/ice/src/bundler/config/output.ts b/packages/ice/src/bundler/config/output.ts index 56ecbd9393..cf58c1a893 100644 --- a/packages/ice/src/bundler/config/output.ts +++ b/packages/ice/src/bundler/config/output.ts @@ -5,6 +5,7 @@ import injectInitialEntry from '../../utils/injectInitialEntry.js'; import { SERVER_OUTPUT_DIR } from '../../constant.js'; import { logger } from '../../utils/logger.js'; import type { BundlerOptions } from '../types.js'; +import type { HtmlGeneratingMode } from '../../types/index.js'; export async function getOutputPaths(options: { rootDir: string; @@ -21,7 +22,7 @@ export async function getOutputPaths(options: { } } if (serverEntry && userConfig.htmlGenerating) { - outputPaths = await buildCustomOutputs(rootDir, outputDir, serverEntry, bundleOptions); + outputPaths = await buildCustomOutputs(rootDir, outputDir, serverEntry, bundleOptions, userConfig.htmlGeneratingMode); } return outputPaths; } @@ -37,6 +38,7 @@ async function buildCustomOutputs( outputDir: string, serverEntry: string, bundleOptions: Pick, + generatingMode?: HtmlGeneratingMode, ) { const { userConfig, appConfig, routeManifest } = bundleOptions; const { ssg } = userConfig; @@ -52,6 +54,7 @@ async function buildCustomOutputs( renderMode: ssg ? 'SSG' : undefined, routeType: appConfig?.router?.type, routeManifest, + generatingMode, }); if (routeType === 'memory' && userConfig?.routes?.injectInitialEntry) { injectInitialEntry(routeManifest, outputDir); diff --git a/packages/ice/src/config.ts b/packages/ice/src/config.ts index 0dd14ca72b..c5a133de61 100644 --- a/packages/ice/src/config.ts +++ b/packages/ice/src/config.ts @@ -511,6 +511,11 @@ const userConfig = [ validation: 'boolean', defaultValue: true, }, + { + name: 'htmlGeneratingMode', + validation: 'string', + defaultValue: 'cleanUrl', + }, ]; const cliOption = [ diff --git a/packages/ice/src/types/userConfig.ts b/packages/ice/src/types/userConfig.ts index ae252c00a9..2796929a73 100644 --- a/packages/ice/src/types/userConfig.ts +++ b/packages/ice/src/types/userConfig.ts @@ -49,6 +49,8 @@ interface Fetcher { method?: string; } +export type HtmlGeneratingMode = 'cleanUrl' | 'compat'; + export interface UserConfig { /** * Feature polyfill for legacy browsers, which can not polyfilled by core-js. @@ -179,6 +181,15 @@ export interface UserConfig { * @see https://v3.ice.work/docs/guide/basic/config#htmlgenerating */ htmlGenerating?: boolean; + /** + * Control how file structure to generation html. + * Route: '/' '/foo' '/foo/bar' + * `cleanUrl`: '/index.html' '/foo.html' '/foo/bar.html' + * `compat`: '/index.html' '/foo/index.html' '/foo/bar/index.html' + * @see https://v3.ice.work/docs/guide/basic/config#htmlgeneratingmode + * @default 'cleanUrl' + */ + htmlGeneratingMode?: HtmlGeneratingMode; /** * Choose a style of souce mapping to enhance the debugging process. * @see https://v3.ice.work/docs/guide/basic/config#sourcemap diff --git a/packages/ice/src/utils/generateEntry.ts b/packages/ice/src/utils/generateEntry.ts index 198e59d8c1..5e9038fe51 100644 --- a/packages/ice/src/utils/generateEntry.ts +++ b/packages/ice/src/utils/generateEntry.ts @@ -1,6 +1,7 @@ import * as path from 'path'; import fse from 'fs-extra'; import type { ServerContext, RenderMode, AppConfig } from '@ice/runtime'; +import type { HtmlGeneratingMode } from '../types/index.js'; import dynamicImport from './dynamicImport.js'; import { logger } from './logger.js'; import type RouteManifest from './routeManifest.js'; @@ -12,6 +13,7 @@ interface Options { documentOnly: boolean; routeType: AppConfig['router']['type']; renderMode?: RenderMode; + generatingMode?: HtmlGeneratingMode; routeManifest: RouteManifest; } @@ -28,6 +30,7 @@ export default async function generateEntry(options: Options): Promise ({ 如果产物不想生成 html,可以设置为 `false`,在 SSG 开启的情况下,强制关闭 html 生成,将导致 SSG 失效。 +### htmlGeneratingMode + +- 类型: `'cleanUrl' | 'compat'` +- 默认值 `'cleanUrl'` + +当开启 html 生成的时候,可以用来配置生成目录的规则,避免在某些服务器下出现非首页内容 404 的情况。目前主要由两种,分别是: + +- `cleanUrl` 生成的文件路径和路由一致,只不过多了 `.html`。通常用于支持此模式的现代服务器 +- `compat` 生成兼容模式的路径文件,通常用于一些只能省略 `index.html` 的服务器 + +| 路径 | `/` | `/foo` | `/foo/bar` | +|------------|---------------|-------------------|-----------------------| +| `cleanUrl` | `/index.html` | `/foo.html` | `/foo/bar.html` | +| `compat` | `/index.html` | `/foo/index.html` | `/foo/bar/index.html` | + ### plugins - 类型:`PluginList`