Fix tiptap selection sync and toolbar event loop
This commit is contained in:
@@ -73,6 +73,36 @@ const parseRuntimeBoolean = (value: unknown): boolean | undefined => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
function getServerNodeBuiltin<T>(moduleName: string): T | null {
|
||||
if (typeof window !== "undefined") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const processWithBuiltin = process as NodeJS.Process & {
|
||||
getBuiltinModule?: (id: string) => unknown;
|
||||
};
|
||||
if (typeof processWithBuiltin.getBuiltinModule === "function") {
|
||||
const builtIn = processWithBuiltin.getBuiltinModule(moduleName);
|
||||
if (builtIn) {
|
||||
return builtIn as T;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 说明:某些 Node/打包环境仍保留 CommonJS require,这里只作为兜底。
|
||||
const runtimeRequire = new Function(
|
||||
'return typeof require === "function" ? require : null',
|
||||
)() as NodeJS.Require | null;
|
||||
if (runtimeRequire) {
|
||||
return runtimeRequire(moduleName) as T;
|
||||
}
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const readFromEnv = (): MnoteRuntimeConfig => ({
|
||||
useConvex: process.env.USE_CONVEX === "1" || process.env.NEXT_PUBLIC_USE_CONVEX === "1",
|
||||
supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL,
|
||||
@@ -111,12 +141,14 @@ const readFromPublicJson = (): Partial<MnoteRuntimeConfig> => {
|
||||
// 桌面端运行时 process.cwd() 会被 Electron 切到 desktop-next 根目录。
|
||||
// 网页端运行时 process.cwd() 通常为 wolai-frontend。
|
||||
|
||||
// 说明:这里不能直接写 `require("fs")` / `require("path")`,
|
||||
// 否则客户端 bundle 在解析该模块时会把它们也当成浏览器依赖,触发持续重编译或空白页。
|
||||
// 仅在服务端运行时通过惰性 require 读取本地 public/mnote-env.json。
|
||||
const runtimeRequire = new Function("return require")() as NodeJS.Require;
|
||||
const fs = runtimeRequire("node:fs") as typeof import("fs");
|
||||
const path = runtimeRequire("node:path") as typeof import("path");
|
||||
// 说明:这里不能直接静态引入 `node:fs` / `node:path`,
|
||||
// 否则客户端 bundle 在解析该模块时会把它们也当成浏览器依赖。
|
||||
// Node 22 优先走 `process.getBuiltinModule`,其余环境再兜底到 runtime require。
|
||||
const fs = getServerNodeBuiltin<typeof import("fs")>("node:fs");
|
||||
const path = getServerNodeBuiltin<typeof import("path")>("node:path");
|
||||
if (!fs || !path) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// 说明:Next standalone 产物的 server.js 会执行 `process.chdir(__dirname)`,
|
||||
// 导致 process.cwd() 变成 `.next/standalone`,此时 public/mnote-env.json 位于上层目录。
|
||||
@@ -224,18 +256,28 @@ export const getMnoteRuntimeConfig = (): MnoteRuntimeConfig => {
|
||||
return normalizeRuntimeConfig(window.__MNOTE_RUNTIME_CONFIG__ ?? readFromEnv());
|
||||
}
|
||||
const isDesktop = process.env.MNOTE_DESKTOP === "1";
|
||||
const publicRuntime = readFromPublicJson();
|
||||
const envRuntime = readFromEnv();
|
||||
// 说明:桌面端需要优先使用 public/mnote-env.json 来覆盖 build 时注入的 NEXT_PUBLIC_*。
|
||||
// Web 端开发时则应优先使用环境变量(例如本机 http://127.0.0.1:18000),避免被
|
||||
// public/mnote-env.json 中的远程/自签地址覆盖导致浏览器登录请求失败。
|
||||
const merged: MnoteRuntimeConfig = isDesktop
|
||||
? {
|
||||
...readFromEnv(),
|
||||
...readFromPublicJson(),
|
||||
...envRuntime,
|
||||
...publicRuntime,
|
||||
isDesktop,
|
||||
}
|
||||
: {
|
||||
...readFromPublicJson(),
|
||||
...readFromEnv(),
|
||||
...publicRuntime,
|
||||
...envRuntime,
|
||||
// 说明:Rust Web 的 tree shell 属于运行期开关,必须允许 public/mnote-env.json
|
||||
// 在网页端覆盖环境变量;否则开发机上的旧 NEXT_PUBLIC_* 会把显式开关吃掉。
|
||||
...(publicRuntime.mnoteWebBaseUrl !== undefined
|
||||
? { mnoteWebBaseUrl: publicRuntime.mnoteWebBaseUrl }
|
||||
: {}),
|
||||
...(publicRuntime.mnoteWebTreeShellEnabled !== undefined
|
||||
? { mnoteWebTreeShellEnabled: publicRuntime.mnoteWebTreeShellEnabled }
|
||||
: {}),
|
||||
isDesktop,
|
||||
};
|
||||
return normalizeRuntimeConfig(merged);
|
||||
|
||||
Reference in New Issue
Block a user