refactor: replace webpack context loading with dev server proxy
Remove the webpack-based file indexing strategy in favor of a proxy approach. The dev server now proxies content requests to a local CLI server, simplifying the data loading logic and removing webpack-specific types and loaders.
This commit is contained in:
parent
52563fd3ef
commit
c661d2a1d2
|
|
@ -18,15 +18,6 @@ export default defineConfig({
|
|||
},
|
||||
},
|
||||
rspack: {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.md|\.yarn|\.csv$/,
|
||||
exclude: /\.schema\.csv$/,
|
||||
type: "asset/source",
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
process.env.ANALYZE ? new BundleAnalyzerPlugin() : undefined,
|
||||
].filter(Boolean),
|
||||
|
|
@ -40,13 +31,18 @@ export default defineConfig({
|
|||
index: "./src/main.tsx",
|
||||
},
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
// Proxy content API requests to the CLI dev server (npm run tttk)
|
||||
"/__CONTENT_INDEX.json": "http://localhost:3000",
|
||||
"/__COMPLETIONS.json": "http://localhost:3000",
|
||||
"/content": "http://localhost:3000",
|
||||
"/journal": "http://localhost:3000",
|
||||
},
|
||||
},
|
||||
output: {
|
||||
distPath: {
|
||||
root: "dist/web",
|
||||
},
|
||||
copy:
|
||||
process.env.NODE_ENV === "development"
|
||||
? [{ from: "./content", to: "content" }]
|
||||
: [],
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
/**
|
||||
* 文件索引管理器
|
||||
* 支持多种文件索引加载方式:
|
||||
* 1. CLI 环境:从 /__CONTENT_INDEX.json 加载
|
||||
* 2. Dev 环境:使用 webpackContext 仅加载 .md 文件(仅在 dev 构建中生效)
|
||||
* 3. 浏览器环境:用户选择本地文件夹,扫描文件索引
|
||||
* 支持两种文件索引加载方式:
|
||||
* 1. CLI / 代理环境:从 /__CONTENT_INDEX.json 加载
|
||||
* 2. 浏览器环境:用户选择本地文件夹,扫描文件索引
|
||||
* - 支持 IndexedDB 持久化目录句柄,刷新页面无需重新选择
|
||||
*
|
||||
* Dev 工作流:运行 CLI 服务器并在 rsbuild 配置中设置代理
|
||||
* > npm run tttk serve ./content
|
||||
* > npm run dev
|
||||
* rsbuild 会将 /__CONTENT_INDEX.json、/__COMPLETIONS.json、/content/ 代理到 CLI 服务器
|
||||
*/
|
||||
|
||||
import {
|
||||
|
|
@ -18,20 +22,20 @@ type FileIndex = Record<string, string>;
|
|||
|
||||
let fileIndex: FileIndex | null = null;
|
||||
let indexLoadPromise: Promise<void> | null = null;
|
||||
let activeSource: "cli" | "webpack" | "folder" | null = null;
|
||||
let activeSource: "cli" | "folder" | null = null;
|
||||
|
||||
/** Currently active directory handle (if folder source) */
|
||||
let activeDirHandle: FileSystemDirectoryHandle | null = null;
|
||||
|
||||
/**
|
||||
* 加载文件索引(只加载一次)
|
||||
* 尝试顺序:CLI JSON → webpack context (dev only) → 已持久化的目录句柄
|
||||
* 尝试顺序:CLI JSON → 已持久化的目录句柄
|
||||
*/
|
||||
function ensureIndexLoaded(): Promise<void> {
|
||||
if (indexLoadPromise) return indexLoadPromise;
|
||||
|
||||
indexLoadPromise = (async () => {
|
||||
// 策略 1: CLI 环境 — 从 /__CONTENT_INDEX.json 加载
|
||||
// 策略 1: CLI / 代理环境 — 从 /__CONTENT_INDEX.json 加载
|
||||
try {
|
||||
const response = await fetch("/__CONTENT_INDEX.json");
|
||||
if (response.ok) {
|
||||
|
|
@ -44,31 +48,7 @@ function ensureIndexLoaded(): Promise<void> {
|
|||
// CLI 索引不可用时尝试下一个策略
|
||||
}
|
||||
|
||||
// 策略 2: Dev 环境 — webpackContext + raw loader(仅 dev 构建时生效)
|
||||
// 生产构建时 process.env.NODE_ENV 被替换为 'production',整个分支会被 tree-shake 掉
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
try {
|
||||
const context = import.meta.webpackContext("../../content", {
|
||||
recursive: true,
|
||||
regExp: /\.md|\.yarn|\.csv|\.svg$/i,
|
||||
});
|
||||
const keys = context.keys();
|
||||
const index: FileIndex = {};
|
||||
for (const key of keys) {
|
||||
const module = context(key) as { default?: string } | string;
|
||||
const content =
|
||||
typeof module === "string" ? module : (module.default ?? "");
|
||||
const normalizedPath = "/content" + key.slice(1);
|
||||
index[normalizedPath] = content;
|
||||
}
|
||||
fileIndex = { ...fileIndex, ...index };
|
||||
activeSource = "webpack";
|
||||
} catch (e) {
|
||||
// webpackContext 不可用时忽略
|
||||
}
|
||||
}
|
||||
|
||||
// 策略 3: 浏览器 — 尝试从 IndexedDB 恢复保存的目录句柄
|
||||
// 策略 2: 浏览器 — 尝试从 IndexedDB 恢复保存的目录句柄
|
||||
if (!activeSource) {
|
||||
try {
|
||||
const restored = await restoreSavedHandle();
|
||||
|
|
@ -176,7 +156,7 @@ export async function loadFromUserFolder(): Promise<string[] | null> {
|
|||
|
||||
/**
|
||||
* 移除已保存的目录句柄,并清除索引
|
||||
* 之后确保索引加载时回退到 CLI/webpack 策略
|
||||
* 之后确保索引加载时回退到 CLI 策略
|
||||
*/
|
||||
export async function switchToBuiltInSource(): Promise<void> {
|
||||
await removeHandle();
|
||||
|
|
|
|||
|
|
@ -35,21 +35,6 @@ interface Window {
|
|||
): Promise<FileSystemDirectoryHandle>;
|
||||
}
|
||||
|
||||
interface WebpackContext {
|
||||
(path: string): { default?: string } | string;
|
||||
keys(): string[];
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
webpackContext(
|
||||
directory: string,
|
||||
options: {
|
||||
recursive?: boolean;
|
||||
regExp?: RegExp;
|
||||
},
|
||||
): WebpackContext;
|
||||
}
|
||||
|
||||
declare module "*.md" {
|
||||
const content: string;
|
||||
export default content;
|
||||
|
|
|
|||
Loading…
Reference in New Issue