UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

257 lines (255 loc) 11.2 kB
"use strict"; var import_buffer = require("buffer"); var import_fs = require("fs"); var import_os = require("os"); var import_path = require("path"); var import_vitest = require("vitest"); var import_vite = require("vite"); var import_routeIndex = require("../../utils/routeIndex.native.js"); var import_virtualEntryPlugin = require("./virtualEntryPlugin.native.js"); import_vitest.vi.mock("vxrn", function () { return { isNativeEnvironment: function (env) { return (env === null || env === void 0 ? void 0 : env.name) === "ios" || (env === null || env === void 0 ? void 0 : env.name) === "android"; } }; }); import_vitest.vi.mock("@vxrn/compiler", function () { return { configuration: { enableNativewind: false } }; }); function loadEntry(plugin, envName) { var command = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "build", envMode = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : command === "serve" ? "dev" : "build"; var _plugin_configResolved; (_plugin_configResolved = plugin.configResolved) === null || _plugin_configResolved === void 0 ? void 0 : _plugin_configResolved.call(plugin, { root: "", command }); var ctx = { environment: { name: envName, mode: envMode } }; return plugin.load.handler.call(ctx, "\0virtual:one-entry"); } (0, import_vitest.describe)("virtualEntryPlugin", function () { (0, import_vitest.it)("keeps spa route matching without bundling the client module on the server", async function () { var root = (0, import_fs.mkdtempSync)((0, import_path.join)((0, import_os.tmpdir)(), "one-spa-server-")); var appDir = (0, import_path.join)(root, "app"); (0, import_fs.mkdirSync)(appDir); var spaRoute = (0, import_path.join)(appDir, "client-only+spa.tsx"); (0, import_fs.writeFileSync)(spaRoute, `export const browserPayload = 'must-not-enter-server-graph' export default function ClientOnlyPage() { return null } `); try { var result = await (0, import_vite.build)({ root, configFile: false, logLevel: "silent", plugins: [{ name: "test-one-entry", enforce: "pre", resolveId(id) { if (id === "one") return "\0test-one-entry"; }, load(id) { if (id === "\0test-one-entry") { return `export const createApp = (options) => options export const registerPreloadedRoute = () => {}`; } } }, (0, import_virtualEntryPlugin.createVirtualEntry)({ root: "app", flags: {}, routeIndex: (0, import_routeIndex.createRouteIndex)({ routerRoot: appDir }) })], build: { ssr: true, write: false, rolldownOptions: { input: "virtual:one-entry" } } }); if (Array.isArray(result)) throw new Error("expected one server build output"); if (!("output" in result)) throw new Error("expected completed server build"); var moduleIds = result.output.flatMap(function (output) { return output.type === "chunk" ? output.moduleIds : []; }); (0, import_vitest.expect)(moduleIds).not.toContain((0, import_path.resolve)(spaRoute)); (0, import_vitest.expect)(result.output.flatMap(function (output) { return output.type === "chunk" ? output.code : ""; }).join("\n")).not.toContain("must-not-enter-server-graph"); var entry = result.output.find(function (output) { return output.type === "chunk" && output.isEntry; }); if (!entry || entry.type !== "chunk") throw new Error("missing server entry chunk"); var built = await import(`data:text/javascript;base64,${import_buffer.Buffer.from(entry.code).toString("base64")}`); (0, import_vitest.expect)(Object.keys(built.default.routes)).toContain("/app/client-only+spa.tsx"); await (0, import_vitest.expect)(built.default.routes["/app/client-only+spa.tsx"]()).resolves.toEqual({}); } finally { (0, import_fs.rmSync)(root, { recursive: true, force: true }); } }); (0, import_vitest.describe)("setupFile", function () { var base = { root: "app", flags: {}, routeIndex: { getPaths: function () { return []; }, update: function () { return false; } } }; (0, import_vitest.it)("server (ssr) uses lazy dynamic import, not static import", function () { var plugin = (0, import_virtualEntryPlugin.createVirtualEntry)({ ...base, setupFile: { client: "./src/setupClient.ts", server: "./src/setupServer.ts" } }); var code = loadEntry(plugin, "ssr"); (0, import_vitest.expect)(code).not.toContain('import "./src/setupServer.ts"'); (0, import_vitest.expect)(code).toContain("__oneGetSetupPromise = () => import("); (0, import_vitest.expect)(code).toContain("./src/setupServer.ts"); (0, import_vitest.expect)(code).toContain("getSetupPromise: __oneGetSetupPromise"); }); (0, import_vitest.it)("client uses dynamic import for setupFile", function () { var plugin = (0, import_virtualEntryPlugin.createVirtualEntry)({ ...base, setupFile: { client: "./src/setupClient.ts", server: "./src/setupServer.ts" } }); var code = loadEntry(plugin, "client"); (0, import_vitest.expect)(code).toContain("__oneGetSetupPromise"); (0, import_vitest.expect)(code).toContain("import("); (0, import_vitest.expect)(code).toContain("./src/setupClient.ts"); (0, import_vitest.expect)(code).toContain("getSetupPromise: __oneGetSetupPromise"); (0, import_vitest.expect)(code).not.toContain('import "./src/setupClient.ts"'); }); (0, import_vitest.it)("native (ios) uses static import for setupFile", function () { var plugin = (0, import_virtualEntryPlugin.createVirtualEntry)({ ...base, setupFile: { client: "./src/setupClient.ts", native: "./src/setupNative.ts" } }); var code = loadEntry(plugin, "ios"); (0, import_vitest.expect)(code).toContain('import "./src/setupNative.ts"'); (0, import_vitest.expect)(code).not.toContain("__oneGetSetupPromise"); (0, import_vitest.expect)(code).not.toContain("getSetupPromise"); }); (0, import_vitest.it)("android uses static import like ios", function () { var plugin = (0, import_virtualEntryPlugin.createVirtualEntry)({ ...base, setupFile: { native: "./src/setupNative.ts" } }); var code = loadEntry(plugin, "android"); (0, import_vitest.expect)(code).toContain('import "./src/setupNative.ts"'); (0, import_vitest.expect)(code).not.toContain("__oneGetSetupPromise"); }); (0, import_vitest.it)("server (ssr) in dev mode uses static import for dep discovery", function () { var plugin = (0, import_virtualEntryPlugin.createVirtualEntry)({ ...base, setupFile: { client: "./src/setupClient.ts", server: "./src/setupServer.ts" } }); var code = loadEntry(plugin, "ssr", "serve"); (0, import_vitest.expect)(code).toContain('import "./src/setupServer.ts"'); (0, import_vitest.expect)(code).not.toContain("__oneGetSetupPromise"); }); (0, import_vitest.it)("no setupFile produces no import", function () { var plugin = (0, import_virtualEntryPlugin.createVirtualEntry)(base); var code = loadEntry(plugin, "ssr"); (0, import_vitest.expect)(code).not.toContain("setupServer"); (0, import_vitest.expect)(code).not.toContain("__oneGetSetupPromise"); (0, import_vitest.expect)(code).not.toContain("getSetupPromise"); }); (0, import_vitest.it)("string setupFile applies to all environments", function () { var plugin = (0, import_virtualEntryPlugin.createVirtualEntry)({ ...base, setupFile: "./src/setup.ts" }); var ssrCode = loadEntry(plugin, "ssr"); var clientCode = loadEntry(plugin, "client"); var iosCode = loadEntry(plugin, "ios"); (0, import_vitest.expect)(ssrCode).toContain("./src/setup.ts"); (0, import_vitest.expect)(ssrCode).toContain("__oneGetSetupPromise"); (0, import_vitest.expect)(ssrCode).not.toContain('import "./src/setup.ts"'); (0, import_vitest.expect)(clientCode).toContain("./src/setup.ts"); (0, import_vitest.expect)(clientCode).toContain("__oneGetSetupPromise"); (0, import_vitest.expect)(clientCode).not.toContain('import "./src/setup.ts"'); (0, import_vitest.expect)(iosCode).toContain('import "./src/setup.ts"'); (0, import_vitest.expect)(iosCode).not.toContain("__oneGetSetupPromise"); }); (0, import_vitest.it)("passes router linking config to createApp", function () { var plugin = (0, import_virtualEntryPlugin.createVirtualEntry)({ ...base, router: { linking: { scheme: "threepunchconvo", prefixes: ["threepunchconvo://app"] } } }); var code = loadEntry(plugin, "ios"); (0, import_vitest.expect)(code).toContain('linking: {"scheme":"threepunchconvo","prefixes":["threepunchconvo://app"]}'); }); }); (0, import_vitest.describe)("react-refresh preamble", function () { var base = { root: "app", flags: {}, routeIndex: { getPaths: function () { return []; }, update: function () { return false; } } }; (0, import_vitest.it)("dev client installs the preamble before route modules load", function () { var code = loadEntry((0, import_virtualEntryPlugin.createVirtualEntry)(base), "client", "serve"); (0, import_vitest.expect)(code).toContain(`from '/@react-refresh'`); (0, import_vitest.expect)(code).toContain("window.$RefreshReg$ = () => {}"); (0, import_vitest.expect)(code).toContain(`!window.$RefreshReg$`); (0, import_vitest.expect)(code.indexOf("__oneInjectRefresh(window)")).toBeLessThan(code.indexOf("createApp(")); }); (0, import_vitest.it)("production build emits no reference to the dev-only refresh runtime", function () { var code = loadEntry((0, import_virtualEntryPlugin.createVirtualEntry)(base), "client", "build"); (0, import_vitest.expect)(code).not.toContain("/@react-refresh"); (0, import_vitest.expect)(code).not.toContain("$RefreshReg$"); }); (0, import_vitest.it)("server and native entries never get the preamble", function () { for (var _i = 0, _iter = ["ssr", "ios", "android"]; _i < _iter.length; _i++) { var envName = _iter[_i]; var code = loadEntry((0, import_virtualEntryPlugin.createVirtualEntry)(base), envName, "serve"); (0, import_vitest.expect)(code).not.toContain("/@react-refresh"); (0, import_vitest.expect)(code).not.toContain("$RefreshReg$"); } }); }); }); //# sourceMappingURL=virtualEntryPlugin.test.native.js.map