one
Version:
One is a new React Framework that makes Vite serve both native and web.
698 lines • 27 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 one_exports = {};
__export(one_exports, {
one: () => one
});
module.exports = __toCommonJS(one_exports);
var import_compiler = require("@vxrn/compiler");
var import_resolve = require("@vxrn/resolve");
var import_vite_plugin_metro = require("@vxrn/vite-plugin-metro");
var import_node_events = __toESM(require("node:events"), 1);
var import_node_fs = require("node:fs");
var import_node_path = __toESM(require("node:path"), 1);
var import_vxrn = require("vxrn");
var import_vite_plugin = __toESM(require("vxrn/vite-plugin"), 1);
var import_constants = require("../constants.cjs");
var import_getViteMetroPluginOptions = require("../metro-config/getViteMetroPluginOptions.cjs");
var import_polyfills_server = require("../polyfills-server.cjs");
var import_setServerGlobals = require("../server/setServerGlobals.cjs");
var import_getRouterRootFromOneOptions = require("../utils/getRouterRootFromOneOptions.cjs");
var import_ensureTsConfig = require("./ensureTsConfig.cjs");
var import_loadConfig = require("./loadConfig.cjs");
var import_clientTreeShakePlugin = require("./plugins/clientTreeShakePlugin.cjs");
var import_devtoolsPlugin = require("./plugins/devtoolsPlugin.cjs");
var import_fileSystemRouterPlugin = require("./plugins/fileSystemRouterPlugin.cjs");
var import_fixDependenciesPlugin = require("./plugins/fixDependenciesPlugin.cjs");
var import_generateFileSystemRouteTypesPlugin = require("./plugins/generateFileSystemRouteTypesPlugin.cjs");
var import_criticalCSSPlugin = require("./plugins/criticalCSSPlugin.cjs");
var import_imageDataPlugin = require("./plugins/imageDataPlugin.cjs");
var import_sourceInspectorPlugin = require("./plugins/sourceInspectorPlugin.cjs");
var import_SSRCSSPlugin = require("./plugins/SSRCSSPlugin.cjs");
var import_virtualEntryConstants = require("./plugins/virtualEntryConstants.cjs");
var import_virtualEntryPlugin = require("./plugins/virtualEntryPlugin.cjs");
var import_environmentGuardPlugin = require("./plugins/environmentGuardPlugin.cjs");
import_node_events.default.setMaxListeners(1e3);
globalThis.__vxrnEnableNativeEnv = true;
function one(options = {}) {
(0, import_setServerGlobals.setServerGlobals)();
const routerRoot = (0, import_getRouterRootFromOneOptions.getRouterRootFromOneOptions)(options);
const nativeDisabled = options.native === false;
const nativeOptions = options.native === false ? void 0 : options.native;
if (nativeDisabled) {
globalThis.__vxrnEnableNativeEnv = false;
}
const metroOptions = (() => {
if (nativeDisabled) return null;
if (nativeOptions?.bundler !== "metro" && !process.env.ONE_METRO_MODE) return null;
if (process.env.ONE_METRO_MODE) {
console.info("ONE_METRO_MODE environment variable is set, enabling Metro mode");
}
const routerRoot2 = (0, import_getRouterRootFromOneOptions.getRouterRootFromOneOptions)(options);
const defaultMetroOptions = (0, import_getViteMetroPluginOptions.getViteMetroPluginOptions)({
projectRoot: nativeOptions?.bundlerOptions?.argv?.projectRoot || process.cwd(),
relativeRouterRoot: routerRoot2,
ignoredRouteFiles: options.router?.ignoredRouteFiles,
userDefaultConfigOverrides: nativeOptions?.bundlerOptions?.defaultConfigOverrides,
setupFile: options.setupFile
});
const userMetroOptions = nativeOptions?.bundlerOptions;
const babelConfig = {
...defaultMetroOptions?.babelConfig,
...userMetroOptions?.babelConfig
};
return {
...defaultMetroOptions,
...userMetroOptions,
defaultConfigOverrides: defaultMetroOptions?.defaultConfigOverrides,
// defaultConfigOverrides is merged by getViteMetroPluginOptions, so we need to set it here again.
argv: {
...defaultMetroOptions?.argv,
...userMetroOptions?.argv
},
babelConfig: {
...babelConfig,
plugins: [...(babelConfig.plugins || []), ...(options.react?.compiler === true || options.react?.compiler === "native" ? ["babel-plugin-react-compiler"] : [])]
},
mainModuleName: "one/metro-entry",
// So users won't need to write `"main": "one/metro-entry"` in their `package.json` like ordinary Expo apps.
// allow env var to enable lazy startup
startup: process.env.ONE_METRO_LAZY ? "lazy" : userMetroOptions?.startup
};
})();
const vxrnPlugins = [];
if (!process.env.IS_VXRN_CLI) {
console.warn("Experimental: running VxRN as a Vite plugin. This is not yet stable.");
vxrnPlugins.push((0, import_vite_plugin.default)({
metro: metroOptions,
disableNative: nativeDisabled
}));
} else {
if (!globalThis.__oneOptions) {
(0, import_loadConfig.setOneOptions)(options);
globalThis["__vxrnPluginConfig__"] = options;
globalThis["__vxrnMetroOptions__"] = metroOptions;
return [];
}
}
if (options.config?.ensureTSConfig !== false) {
void (0, import_ensureTsConfig.ensureTSConfig)();
}
const vxrnOptions = (0, import_vxrn.getOptionsFilled)();
const root = vxrnOptions?.root || process.cwd();
const compiler = options.react?.compiler;
if (compiler) {
(0, import_compiler.configureVXRNCompilerPlugin)({
enableCompiler:
// pass through object config, regex, or function directly
typeof compiler === "object" || typeof compiler === "function" ? compiler : compiler === "native" ? ["ios", "android"] : compiler === "web" ? ["ssr", "client"] : true
});
}
const autoDepsOptions = options.ssr?.autoDepsOptimization;
const dedupeSymlinks = options.ssr?.dedupeSymlinkedModules ?? false;
let ssrDedup_optimizedPackages = null;
let ssrDedup_projectRoot = "";
const ssrSymlinkDedupPlugin = {
name: "one:ssr-symlink-dedup",
enforce: "pre",
configResolved(config) {
if (!dedupeSymlinks) return;
ssrDedup_projectRoot = config.root || process.cwd();
const ssrInclude = config.ssr?.optimizeDeps?.include;
if (!ssrInclude?.length) return;
ssrDedup_optimizedPackages = /* @__PURE__ */new Set();
for (const entry of ssrInclude) {
if (entry.startsWith("@")) {
const parts = entry.split("/");
ssrDedup_optimizedPackages.add(`${parts[0]}/${parts[1]}`);
} else {
ssrDedup_optimizedPackages.add(entry.split("/")[0]);
}
}
},
async resolveId(source, importer, options2) {
if (!dedupeSymlinks) return;
if (source[0] === "." || source[0] === "/") return;
let pkgName;
let subpath = null;
if (source.startsWith("@")) {
const parts = source.split("/");
pkgName = parts.length >= 2 ? `${parts[0]}/${parts[1]}` : source;
if (parts.length > 2) subpath = `./${parts.slice(2).join("/")}`;
} else {
const parts = source.split("/");
pkgName = parts[0];
if (parts.length > 1) subpath = `./${parts.slice(1).join("/")}`;
}
const resolved = await this.resolve(source, importer, {
...options2,
skipSelf: true
});
if (!resolved?.id) return;
if (resolved.id.includes("/node_modules/")) return;
const path2 = await import("node:path");
const fs = await import("node:fs");
const {
join,
dirname
} = path2;
const {
realpathSync,
existsSync: existsSync2,
readFileSync: readFileSync2
} = fs;
let dir = ssrDedup_projectRoot;
while (dir !== dirname(dir)) {
const nmPkgDir = join(dir, "node_modules", pkgName);
if (existsSync2(nmPkgDir)) {
if (subpath) {
try {
const pkg = JSON.parse(readFileSync2(join(nmPkgDir, "package.json"), "utf8"));
const exportEntry = pkg.exports?.[subpath];
if (exportEntry && typeof exportEntry === "object") {
const target = exportEntry.import || exportEntry.module || exportEntry.default;
if (target) {
const fullPath = join(nmPkgDir, target);
if (existsSync2(fullPath)) return {
id: fullPath,
external: resolved.external
};
}
}
} catch {}
}
const realPkgDir = realpathSync(nmPkgDir);
if (resolved.id.startsWith(realPkgDir)) {
const relativePart = resolved.id.slice(realPkgDir.length);
return {
id: nmPkgDir + relativePart,
external: resolved.external
};
}
break;
}
dir = dirname(dir);
}
}
};
const devAndProdPlugins = [{
name: "one:config",
__get: options
}, {
name: "one:env-prefix",
config(userConfig) {
if (userConfig.envPrefix) return;
return {
envPrefix: ["VITE_", "EXPO_PUBLIC_"]
};
}
}, (0, import_environmentGuardPlugin.environmentGuardPlugin)(options.environmentGuards), (0, import_criticalCSSPlugin.criticalCSSPlugin)(), (0, import_imageDataPlugin.imageDataPlugin)(), {
name: "one-define-client-env",
async config(userConfig) {
const clientEnvDefine = options.skipEnv ? {} : (await (0, import_vxrn.loadEnv)(vxrnOptions?.mode ?? userConfig?.mode ?? "development", process.cwd(), userConfig?.envPrefix)).clientEnvDefine;
return {
define: {
...clientEnvDefine,
...(process.env.ONE_DEBUG_ROUTER && {
"process.env.ONE_DEBUG_ROUTER": JSON.stringify(process.env.ONE_DEBUG_ROUTER)
})
}
};
}
}, ...(autoDepsOptions === false ? [] : [(0, import_vxrn.autoDepOptimizePlugin)({
onScannedDeps({
hasReanimated,
hasNativewind
}) {
(0, import_compiler.configureVXRNCompilerPlugin)({
enableReanimated: hasReanimated,
enableNativeCSS: nativeOptions?.css ?? hasNativewind,
enableNativewind: hasNativewind
});
},
root,
include: /node_modules/,
...(autoDepsOptions === true ? {} : autoDepsOptions)
})]), ...(options.config?.tsConfigPaths === false ? [] : [/* @__PURE__ */(() => {
let mappings = [];
function loadMappings(resolvedRoot) {
try {
const configPath = import_node_path.default.resolve(resolvedRoot, "tsconfig.json");
if (!(0, import_node_fs.existsSync)(configPath)) return;
const raw = (0, import_node_fs.readFileSync)(configPath, "utf-8");
const stripped = raw.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => g ? "" : m);
const config = JSON.parse(stripped);
const paths = config?.compilerOptions?.paths;
const baseUrl = config?.compilerOptions?.baseUrl || ".";
if (!paths) return;
for (const [pattern, targets] of Object.entries(paths)) {
const target = targets[0];
if (!target) continue;
if (pattern.endsWith("/*")) {
const resolved = import_node_path.default.resolve(resolvedRoot, baseUrl, target.slice(0, -1));
mappings.push({
prefix: pattern.slice(0, -1),
replacement: resolved.endsWith("/") ? resolved : resolved + "/",
wildcard: true
});
} else {
mappings.push({
prefix: pattern,
replacement: import_node_path.default.resolve(resolvedRoot, baseUrl, target),
wildcard: false
});
}
}
} catch {}
}
return {
name: "one:tsconfig-paths",
enforce: "pre",
config() {
return {
resolve: {
tsconfigPaths: true
}
};
},
configResolved(config) {
if (mappings.length === 0) {
loadMappings(config.root);
}
},
resolveId(source) {
const jsExts = [".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs", ".cjs", ".cts"];
for (const m of mappings) {
let candidate;
if (m.wildcard) {
if (source.startsWith(m.prefix)) {
candidate = m.replacement + source.slice(m.prefix.length);
}
} else if (source === m.prefix) {
candidate = m.replacement;
}
if (!candidate) continue;
if (jsExts.includes(import_node_path.default.extname(candidate))) return candidate;
for (const e of jsExts) {
if ((0, import_node_fs.existsSync)(candidate + e)) return candidate + e;
}
for (const e of jsExts) {
if ((0, import_node_fs.existsSync)(candidate + "/index" + e)) return candidate + "/index" + e;
}
return candidate;
}
}
};
})()]),
// resolveId-based aliases that work during both vite transforms AND
// rolldown dep pre-bundling (where resolve.alias is not applied)
...(options.alias ? [(() => {
const resolveMap = map => {
if (!map) return null;
const out = {};
for (const [key, value] of Object.entries(map)) {
try {
out[key] = import_node_path.default.isAbsolute(value) ? value : (0, import_resolve.resolvePath)(value);
} catch {
out[key] = value;
}
}
return out;
};
const a = options.alias;
const resolved = {
web: resolveMap(a.web),
native: resolveMap(a.native),
client: resolveMap(a.client),
ssr: resolveMap(a.ssr),
ios: resolveMap(a.ios),
android: resolveMap(a.android)
};
return {
name: "one:alias",
enforce: "pre",
resolveId(source) {
const env = this.environment?.name;
const specific = env ? resolved[env] : null;
if (specific && source in specific) {
return {
id: specific[source],
external: false
};
}
const isWeb = !env || env === "client" || env === "ssr";
const general = isWeb ? resolved.web : resolved.native;
if (general && source in general) {
return {
id: general[source],
external: false
};
}
}
};
})()] : []), {
// rolldown fails on deep react-native/Libraries/* imports during dep pre-bundling.
// these are native-only paths that don't exist in react-native-web.
name: "one:redirect-rn-deep-imports",
enforce: "pre",
resolveId(source) {
if (this.environment?.name === "client" || this.environment?.name === "ssr") {
if (source.startsWith("react-native/Libraries/") || /react-native-web(-lite)?\/.*\/Libraries\//.test(source)) {
return "\0rn-empty-module";
}
}
},
load(id) {
if (id === "\0rn-empty-module") {
return "export default {}; export {};";
}
}
}, {
name: "one-aliases",
enforce: "pre",
config() {
let tslibLitePath = "";
try {
tslibLitePath = (0, import_resolve.resolvePath)("@vxrn/tslib-lite", process.cwd());
} catch (err) {
console.info(`Can't find tslib-lite, falling back to tslib`);
if (process.env.DEBUG) {
console.error(err);
}
}
return {
resolve: {
alias: {
// testing getting transition between routes working
// 'use-sync-external-store/with-selector': resolvePath(
// 'use-sync-external-store/shim/with-selector'
// ),
...(tslibLitePath && {
tslib: tslibLitePath
})
}
}
};
}
}, {
name: "one:init-config",
config() {
const setupFileDefines = (() => {
if (!options.setupFile) return {};
let setupFiles;
if (typeof options.setupFile === "string") {
setupFiles = {
client: options.setupFile,
server: options.setupFile,
ios: options.setupFile,
android: options.setupFile
};
} else if ("native" in options.setupFile) {
setupFiles = {
client: options.setupFile.client,
server: options.setupFile.server,
ios: options.setupFile.native,
android: options.setupFile.native
};
} else {
setupFiles = options.setupFile;
}
return {
...(setupFiles.client && {
"process.env.ONE_SETUP_FILE_CLIENT": JSON.stringify(setupFiles.client)
}),
...(setupFiles.server && {
"process.env.ONE_SETUP_FILE_SERVER": JSON.stringify(setupFiles.server)
}),
...(setupFiles.ios && {
"process.env.ONE_SETUP_FILE_IOS": JSON.stringify(setupFiles.ios)
}),
...(setupFiles.android && {
"process.env.ONE_SETUP_FILE_ANDROID": JSON.stringify(setupFiles.android)
})
};
})();
const serverURL = process.env.ONE_SERVER_URL || vxrnOptions?.server.url;
return {
// Platform env defined at root level for client (workaround for Vite bug with environment.client.define)
define: {
...(0, import_vite_plugin_metro.getPlatformEnvDefine)("client"),
...setupFileDefines,
...(options.web?.defaultRenderMode && {
"process.env.ONE_DEFAULT_RENDER_MODE": JSON.stringify(options.web.defaultRenderMode),
"import.meta.env.ONE_DEFAULT_RENDER_MODE": JSON.stringify(options.web.defaultRenderMode)
}),
...(process.env.NODE_ENV !== "production" && serverURL && {
"process.env.ONE_SERVER_URL": JSON.stringify(serverURL),
"import.meta.env.ONE_SERVER_URL": JSON.stringify(serverURL)
}),
...(options.web?.linkPrefetch && {
"process.env.ONE_LINK_PREFETCH": JSON.stringify(options.web.linkPrefetch)
}),
...(options.web?.skewProtection !== void 0 && {
"process.env.ONE_SKEW_PROTECTION": JSON.stringify(options.web.skewProtection === true ? "true" : options.web.skewProtection === false ? "false" : options.web.skewProtection
// 'proactive'
)
}),
...(options.web?.suspendRoutes !== void 0 && {
"process.env.ONE_SUSPEND_ROUTES": JSON.stringify(options.web.suspendRoutes ? "1" : "0")
})
},
environments: {
ssr: {
define: (0, import_vite_plugin_metro.getPlatformEnvDefine)("ssr")
},
ios: {
define: {
...(0, import_vite_plugin_metro.getPlatformEnvDefine)("ios"),
...(nativeOptions?.suspendRoutes !== void 0 && {
"process.env.ONE_SUSPEND_ROUTES_NATIVE": JSON.stringify(nativeOptions.suspendRoutes ? "1" : "0")
})
}
},
android: {
define: {
...(0, import_vite_plugin_metro.getPlatformEnvDefine)("android"),
...(nativeOptions?.suspendRoutes !== void 0 && {
"process.env.ONE_SUSPEND_ROUTES_NATIVE": JSON.stringify(nativeOptions.suspendRoutes ? "1" : "0")
})
}
}
},
ssr: {
// ensure server-only/client-only go through vite so our environmentGuardPlugin can handle them
noExternal: ["server-only", "client-only"]
}
};
}
}, {
name: "one:tamagui",
config() {
return {
define: {
// safe to set because it only affects web in tamagui, and one is always react 19
"process.env.TAMAGUI_REACT_19": '"1"'
},
environments: {
ssr: {
define: {
"process.env.TAMAGUI_IS_SERVER": '"1"',
"process.env.TAMAGUI_KEEP_THEMES": '"1"'
}
},
ios: {
define: {
"process.env.TAMAGUI_KEEP_THEMES": '"1"'
}
},
android: {
define: {
"process.env.TAMAGUI_KEEP_THEMES": '"1"'
}
}
}
};
}
}, {
name: "route-module-hmr-fix",
hotUpdate({
server,
modules,
file
}) {
const envName = this.environment?.name;
const fileRelativePath = import_node_path.default.relative(server.config.root, file);
const fileRootDir = fileRelativePath.split(import_node_path.default.sep)[0];
const isAppFile = fileRootDir === "app";
if (envName === "ssr" && isAppFile) {
return [];
}
let hasRouteUpdate = false;
const result = modules.map(m => {
const {
id
} = m;
if (!id) return m;
const relativePath = import_node_path.default.relative(server.config.root, id);
const rootDir = relativePath.split(import_node_path.default.sep)[0];
if (rootDir === "app") {
m.acceptedHmrExports = /* @__PURE__ */new Set();
const isRootLayout = relativePath === import_node_path.default.join("app", "_layout.tsx") || /^app[\\/]\([^)]+\)[\\/]_layout\.tsx$/.test(relativePath);
if (isRootLayout) {
hasRouteUpdate = true;
}
}
return m;
});
if (hasRouteUpdate) {
server.hot.send({
type: "custom",
event: "one:route-update",
data: {
file: fileRelativePath
}
});
}
return result;
}
},
// Plugins may transform the source code and add imports of `react/jsx-dev-runtime`, which won't be discovered by Vite's initial `scanImports` since the implementation is using ESbuild where such plugins are not executed.
// Thus, if the project has a valid `react/jsx-dev-runtime` import, we tell Vite to optimize it, so Vite won't only discover it on the next page load and trigger a full reload.
{
name: "one:optimize-dev-deps",
config(_, env) {
if (env.mode === "development") {
return {
optimizeDeps: {
include: ["react/jsx-dev-runtime", "react/compiler-runtime"]
}
};
}
}
}, {
name: "one:remove-server-from-client",
enforce: "pre",
transform(code, id) {
if (this.environment.name === "client") {
if (id.includes(`one-server-only`)) {
return code.replace(`import { AsyncLocalStorage } from "node:async_hooks"`, `class AsyncLocalStorage {}`);
}
}
}
},
// packages in resolve.dedupe must also be pre-bundled for SSR to prevent
// duplicate module instances (e.g. symlinked monorepo packages resolving
// to different paths)
{
name: "one:ssr-dedupe-prebundle",
config(config) {
if (!dedupeSymlinks) return;
const dedupeList = config.resolve?.dedupe;
if (!Array.isArray(dedupeList) || dedupeList.length === 0) return;
return {
ssr: {
optimizeDeps: {
include: [...dedupeList]
},
noExternal: [...dedupeList]
}
};
}
},
// fix: vite's ssr dep optimizer registers pre-bundled deps by their
// node_modules path, but symlinks cause imports to resolve to the real
// (source) path. the optimizer doesn't recognize the real path, so it
// loads from source — creating a duplicate instance.
// this plugin forces optimized SSR deps to resolve via node_modules.
ssrSymlinkDedupPlugin];
const nativeWebDevAndProdPlugsin = [(0, import_clientTreeShakePlugin.clientTreeShakePlugin)()];
if (!nativeDisabled) {
globalThis.__vxrnAddNativePlugins = [(0, import_clientTreeShakePlugin.clientTreeShakePlugin)({
runtime: "rolldown"
})];
}
globalThis.__vxrnAddWebPluginsProd = devAndProdPlugins;
const flags = {};
if (!nativeDisabled) {
globalThis.__vxrnNativeEntryConfig = {
routerRoot,
ignoredRouteFiles: options.router?.ignoredRouteFiles,
setupFile: options.setupFile,
flags
};
}
const inspectorPlugins = (() => {
const devtools = options.devtools ?? true;
const inspector = devtools === true || devtools !== false && (devtools.inspector ?? true);
const editor = devtools !== true && devtools !== false ? devtools.editor : void 0;
return inspector ? (0, import_sourceInspectorPlugin.sourceInspectorPlugin)({
editor
}) : [];
})();
return [...vxrnPlugins, ...devAndProdPlugins, ...inspectorPlugins, ...nativeWebDevAndProdPlugsin,
/**
* This is really the meat of one, where it handles requests:
*/
(0, import_fileSystemRouterPlugin.createFileSystemRouterPlugin)(options), (0, import_generateFileSystemRouteTypesPlugin.generateFileSystemRouteTypesPlugin)(options), (0, import_fixDependenciesPlugin.fixDependenciesPlugin)(options.patches), (0, import_virtualEntryPlugin.createVirtualEntry)({
...options,
flags,
root: routerRoot
}), {
name: "one-define-environment",
config() {
return {
define: {
...(nativeOptions?.key && {
"process.env.ONE_APP_NAME": JSON.stringify(nativeOptions.key),
"import.meta.env.ONE_APP_NAME": JSON.stringify(nativeOptions.key)
}),
"process.env.ONE_CACHE_KEY": JSON.stringify(import_constants.CACHE_KEY),
"import.meta.env.ONE_CACHE_KEY": JSON.stringify(import_constants.CACHE_KEY)
}
};
}
}, (0, import_SSRCSSPlugin.SSRCSSPlugin)({
entries: [import_virtualEntryConstants.virtualEntryId]
}),
// devtools (always includes refresh preamble for HMR, optionally includes UI)
...(() => {
const devtools = options.devtools ?? true;
const includeUI = devtools !== false;
return [
// always include devtools plugin for refresh preamble (required for HMR)
(0, import_devtoolsPlugin.createDevtoolsPlugin)({
includeUI
})];
})()];
}