Closed qrac closed 1 year ago
this.emitFile
で追加したHTMLはそこからバンドルを行わないので普通にoutputした場合と同じになる。
HTMLを仮想モジュール化してバンドルに含めることで理想的な処理になりそうだったが this.emitFile()
されたHTMLのfileName
のパスがおかしくなりビルドが通らない。
Vite及びrollupにもemitした後のリストを修正する機能はないようなので厳しい。
src/pages
に一度HTMLファイルを出力して一時ファイルとして使えば通りそうだけど、あまり綺麗ではない...。
仮想モジュール化する場合の実装↓
import type { Plugin } from "vite"
import path from "node:path"
import { fileURLToPath } from "node:url"
import { createServer as createViteServer } from "vite"
import type { ResolvedConfig } from "../config/index.js"
import type { GetSources } from "../server/sources.js"
import type { ResolvedViteEntry } from "../config/vite.js"
import { compileApp } from "../compile/app.js"
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
type HtmlPages = {
fileId: string
moduleId: string
path: string
html: string
}[]
export function ssgv(config: ResolvedConfig): Plugin {
const PREFIX = `\0virtual:`
let htmlPages: HtmlPages = []
return {
name: "minista-vite-plugin:ssgv",
async config(viteConfig) {
const viteServer = await createViteServer(config.vite)
await viteServer.listen()
const { getSources } = (await viteServer.ssrLoadModule(
__dirname + "/../server/sources.js"
)) as { getSources: GetSources }
const { resolvedGlobal, resolvedPages } = await getSources()
await viteServer.close()
if (resolvedPages.length === 0) {
return
}
htmlPages = resolvedPages.map((page, index) => {
const fileId = "__minista_html" + index
const fileName = page.path.endsWith("/")
? path.join(page.path, "index.html")
: page.path + ".html"
const moduleId = path.join("src/pages", fileName)
return {
fileId,
moduleId,
path: page.path,
html: compileApp({
url: page.path,
resolvedGlobal,
resolvedPages: [page],
useDevelopBundle: false,
}),
}
})
const htmlArrayInputs = htmlPages.map((page) => [
page.fileId,
page.moduleId,
])
const htmlObjectInputs = Object.fromEntries(htmlArrayInputs)
const assetInputs = viteConfig.build?.rollupOptions?.input || {}
const mergedInputs = Object.assign(
assetInputs,
htmlObjectInputs
) as ResolvedViteEntry
return {
build: {
rollupOptions: {
input: mergedInputs,
},
},
}
},
resolveId(id) {
const target = htmlPages.find((page) => id === page.moduleId)
if (target) {
return PREFIX + id
}
},
load(id) {
if (id.startsWith(PREFIX)) {
id = id.slice(PREFIX.length)
const target = htmlPages.find((page) => id === page.moduleId)
if (target) {
return target.html
}
}
},
}
}
とりあえず、srcへの一時ファイル出力でなんとかした。バグが消えたら作り直したい。
参考:仮想モジュールを追加するViteプラグイン
参考:HTMLを追加するViteプラグインは仮想モジュールを使っておらず、どれも既存のHTMLを使うか生成した後に動かすか消すかを行なっている。
HTMLをエントリーするのではなく、一度SSR用にビルドしてプラグインをページのtsxに反映。nodeでHTMLを生成する。
v2のSSGは
.tsx
を.mjs
に変換(一時ファイル生成).mjs
読み込む.html
作成だったが、v3はViteのSSRを使うことで
.tsx
を読み込む.html
作成を直接行う。
https://ja.vitejs.dev/guide/ssr.html#pre-rendering-ssg