one
Version:
One is a new React Framework that makes Vite serve both native and web.
236 lines (230 loc) • 10.3 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
value: true
}), mod);
var virtualEntryPlugin_exports = {};
__export(virtualEntryPlugin_exports, {
createVirtualEntry: () => createVirtualEntry
});
module.exports = __toCommonJS(virtualEntryPlugin_exports);
var import_node_path = require("node:path");
var import_node_url = require("node:url");
var import_compiler = require("@vxrn/compiler");
var import_micromatch = __toESM(require("micromatch"), 1);
var import_vxrn = require("vxrn");
var import_glob_patterns = require("../../router/glob-patterns.cjs");
var import_matchers = require("../../router/matchers.cjs");
var import_virtualEntryConstants = require("./virtualEntryConstants.cjs");
const escapeRe = s => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const VIRTUAL_ENTRY_SOURCE_RE = new RegExp(`^(?:${escapeRe(import_virtualEntryConstants.virtualEntryId)}|${escapeRe(import_virtualEntryConstants.virtualEntryIdNative)})$`);
const VIRTUAL_ENTRY_RESOLVED_RE = new RegExp(`^(?:${escapeRe(import_virtualEntryConstants.resolvedVirtualEntryId)}|${escapeRe(import_virtualEntryConstants.resolvedVirtualEntryIdNative)})$`);
function normalizeSetupFile(setupFile) {
if (!setupFile) return {};
if (typeof setupFile === "string") {
return {
client: setupFile,
server: setupFile,
ios: setupFile,
android: setupFile
};
}
if ("native" in setupFile) {
return {
client: setupFile.client,
server: setupFile.server,
ios: setupFile.native,
android: setupFile.native
};
}
const sf = setupFile;
return {
client: sf.client,
server: sf.server,
ios: sf.ios,
android: sf.android
};
}
function getSetupFileImport(environmentName, setupFiles, useStaticImport, root) {
const envMap = {
client: "client",
ssr: "server",
ios: "ios",
android: "android"
};
const key = envMap[environmentName];
if (!key) return {
importStatement: "",
promiseDeclaration: "",
promiseVarName: ""
};
const setupFile = setupFiles[key];
if (!setupFile) return {
importStatement: "",
promiseDeclaration: "",
promiseVarName: ""
};
const resolvedSetupFile = root ? (0, import_node_url.pathToFileURL)((0, import_node_path.resolve)(root, setupFile)).href : setupFile;
if (useStaticImport) {
return {
importStatement: `import ${JSON.stringify(resolvedSetupFile)}`,
promiseDeclaration: "",
promiseVarName: ""
};
}
return {
importStatement: "",
promiseDeclaration: `const __oneGetSetupPromise = () => import(${JSON.stringify(resolvedSetupFile)})`,
promiseVarName: "__oneGetSetupPromise"
};
}
function createVirtualEntry(options) {
const routeGlobs = [`/${options.root}/${import_glob_patterns.ROUTE_GLOB_PATTERN}`, ...(options.router?.ignoredRouteFiles?.map(pattern => `!/${options.root}/${pattern}`) || [])];
const apiRouteGlobs = `/${options.root}/${import_glob_patterns.API_ROUTE_GLOB_PATTERN}`;
const setupFiles = normalizeSetupFile(options.setupFile);
let viteRoot = "";
let isDevMode = false;
return {
name: "one-virtual-entry",
enforce: "pre",
configResolved(config) {
viteRoot = config.root;
isDevMode = config.command === "serve";
},
// only the two virtual entry ids reach js; every other import in the graph
// is rejected rust-side
resolveId: {
filter: {
id: VIRTUAL_ENTRY_SOURCE_RE
},
handler(id) {
if (id === import_virtualEntryConstants.virtualEntryId) {
return import_virtualEntryConstants.resolvedVirtualEntryId;
}
if (id === import_virtualEntryConstants.virtualEntryIdNative) {
return import_virtualEntryConstants.resolvedVirtualEntryIdNative;
}
}
},
load: {
filter: {
id: VIRTUAL_ENTRY_RESOLVED_RE
},
handler(id) {
if (id === import_virtualEntryConstants.resolvedVirtualEntryId) {
const isNative = (0, import_vxrn.isNativeEnvironment)(this.environment);
const isSSR = this.environment.name === "ssr";
const serverSpaRouteFiles = isSSR ? options.routeIndex.getPaths().map(file => file.replace(/^\.\//, "")).filter(file => /\.tsx?$/.test(file)).filter(file => !import_micromatch.default.isMatch(file, import_glob_patterns.ROUTE_WEB_EXCLUSION_GLOB_PATTERNS)).filter(file => {
const parts = file.split("/");
const filename = parts.at(-1) || "";
if (filename.startsWith("_layout") || filename.startsWith("_middleware")) {
return false;
}
const fileMode = (0, import_matchers.matchFileRenderMode)(filename);
if (fileMode) return fileMode === "spa";
let parentMode;
for (const directory of parts.slice(0, -1)) {
parentMode = (0, import_matchers.matchDirectoryRenderMode)(directory)?.renderMode ?? parentMode;
}
return parentMode === "spa";
}) : [];
const serverSpaRouteStubs = serverSpaRouteFiles.map(file => `${JSON.stringify(`/${options.root}/${file}`)}: () => Promise.resolve({})`).join(",\n ");
const serverSpaBuildGlobs = serverSpaRouteFiles.map(file => `/${options.root}/${file}`);
const serverSpaBuildRoutes = serverSpaBuildGlobs.length ? `{
loader: import.meta.glob(${JSON.stringify(serverSpaBuildGlobs)}, { exhaustive: true, import: 'loader', query: '?one-spa-build' }),
generateStaticParams: import.meta.glob(${JSON.stringify(serverSpaBuildGlobs)}, { exhaustive: true, import: 'generateStaticParams', query: '?one-spa-build' }),
sitemap: import.meta.glob(${JSON.stringify(serverSpaBuildGlobs)}, { exhaustive: true, import: 'sitemap', query: '?one-spa-build' })
}` : "{}";
const webRouteGlobs = [...routeGlobs, ...import_glob_patterns.ROUTE_WEB_EXCLUSION_GLOB_PATTERNS.map(pattern => `!${pattern}`), ...serverSpaRouteFiles.map(file => `!/${options.root}/${file}`)];
const useStaticImport = isNative || isSSR && isDevMode;
const setupResult = getSetupFileImport(this.environment.name, setupFiles, useStaticImport, viteRoot);
const nativewindImport = import_compiler.configuration.enableNativewind ? `import 'react-native-css-interop/dist/runtime/components'` : "";
const setupPromiseArg = setupResult.promiseVarName ? `getSetupPromise: ${setupResult.promiseVarName},` : "";
const linkingArg = options.router?.linking ? `linking: ${JSON.stringify(options.router.linking)},` : "";
const isDevClient = this.environment.mode === "dev" && this.environment.name === "client";
const refreshPreambleImport = isDevClient ? `import { injectIntoGlobalHook as __oneInjectRefresh } from '/@react-refresh'` : "";
const refreshPreambleSetup = isDevClient ? `if (typeof window !== 'undefined' && !window.$RefreshReg$) {
__oneInjectRefresh(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
}` : "";
return `
${setupResult.promiseDeclaration}
${nativewindImport}
${refreshPreambleImport}
import { createApp, registerPreloadedRoute as _registerPreloadedRoute } from 'one'
${setupResult.importStatement}
${refreshPreambleSetup}
// Export registerPreloadedRoute so preload files can import it from this bundle
// Named export that wraps the original function
export function registerPreloadedRoute(key, module) {
return _registerPreloadedRoute(key, module)
}
// Also expose on window for debugging and to prevent tree-shaking
if (typeof window !== 'undefined') {
window.__oneRegisterPreloadedRoute = registerPreloadedRoute
}
// build-only spa exports generate route artifacts without exposing the page
// component to the runtime server route map.
export const oneBuildOnlySpaRoutes = ${serverSpaBuildRoutes}
// globbing ${JSON.stringify(webRouteGlobs)}
export default createApp({
${setupPromiseArg}
routes: {
...import.meta.glob(${JSON.stringify(webRouteGlobs)}, { exhaustive: true }),
${serverSpaRouteStubs}
},
routerRoot: ${JSON.stringify(options.root)},
flags: ${JSON.stringify(options.flags)},
${linkingArg}
})
`;
}
if (id === import_virtualEntryConstants.resolvedVirtualEntryIdNative) {
const isNative = (0, import_vxrn.isNativeEnvironment)(this.environment);
const setupResult = getSetupFileImport(this.environment.name, setupFiles, isNative, viteRoot);
const linkingArg = options.router?.linking ? `linking: ${JSON.stringify(options.router.linking)},` : "";
return `
import { createApp } from 'one'
${setupResult.importStatement}
// globbing ${JSON.stringify(routeGlobs)}
export default createApp({
routes: import.meta.glob(${JSON.stringify([...routeGlobs, ...import_glob_patterns.ROUTE_NATIVE_EXCLUSION_GLOB_PATTERNS.map(p => `!${p}`), `!${apiRouteGlobs}`])}, { exhaustive: true }),
routerRoot: ${JSON.stringify(options.root)},
flags: ${JSON.stringify(options.flags)},
${linkingArg}
})
`;
}
}
}
};
}