Skip to content

Commit

Permalink
fix(vxrn): fix prod builds for react 19
Browse files Browse the repository at this point in the history
  • Loading branch information
natew committed Jan 7, 2025
1 parent fce4026 commit e9930b9
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 69 deletions.
2 changes: 1 addition & 1 deletion apps/onestack.dev/data/docs/routing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Routing
---

The `app` directory is where One handles universal file system routing. Every file you create in it will be turned into a route, except for files named `_layout`. One only supports file system routes at this time, but we have a [discussion](https://github.com/onejs/one/discussions/108) for those who want to help us figure out a configuration-based approach.
The `app` directory is where One handles universal file system routing. Every file you create in it will be turned into a route, except for files named `_layout` or `_middleware`. One only supports file system routes at this time, but we have a [discussion](https://github.com/onejs/one/discussions/108) for those who want to help us figure out a configuration-based approach.

Here's an example:

Expand Down
1 change: 0 additions & 1 deletion packages/one/src/useScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ export function getQualifiedRouteComponent(value: RouteNode) {
}: any,
ref: any
) => {
console.log('route', route)
const loadable = getLoadable(props, ref)
return (
<Route route={route} node={value}>
Expand Down
30 changes: 18 additions & 12 deletions packages/react-native-prebuilt/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,24 @@ export async function buildReactJSX(options: BuildOptions = {}) {
}).then(async () => {
// manual force exports
const bundled = await readFile(options.outfile!, 'utf-8')

const outCode = `
const run = () => {
${mustReplace(bundled, [
isProd
? {
find: `module.exports = require_react_jsx_runtime_production_min();`,
replace: `return require_react_jsx_runtime_production_min();`,
}
: {
find: `module.exports = require_react_jsx_dev_runtime_development();`,
replace: `return require_react_jsx_dev_runtime_development();`,
},
...(isProd
? [
{
// react 18 and 19 (18 has _min)
find: /module\.exports = require_react_jsx_runtime_production([a-z_]*)\(\);/,
replace: `return require_react_jsx_runtime_production$1();`,
},
]
: [
{
find: `module.exports = require_react_jsx_dev_runtime_development();`,
replace: `return require_react_jsx_dev_runtime_development();`,
},
]),
{ find: `process.env.VXRN_REACT_19`, replace: 'false', optional: true },
{
find: `Object.assign(exports, eval("require('@vxrn/vendor/react-jsx-19')"));`,
Expand Down Expand Up @@ -101,11 +107,11 @@ export async function buildReact(options: BuildOptions = {}) {
${mustReplace(bundled, [
isProd
? {
find: /module\.exports = require_react_production_min(\d*)\(\);/,
replace: 'return require_react_production_min$1();',
find: /module\.exports = require_react_production([a-z_]*)\(\);/,
replace: 'return require_react_production$1();',
}
: {
find: /module\.exports = require_react_development(\d*)\(\);/,
find: /module\.exports = require_react_development([a-z_]*)\(\);/,
replace: 'return require_react_development$1();',
},
{
Expand Down
13 changes: 9 additions & 4 deletions packages/vxrn/src/exports/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,15 @@ export const build = async (optionsIn: VXRNOptions, buildArgs: BuildArgs = {}) =
const old = await FSExtra.readFile(serverEntry, 'utf-8')
await FSExtra.writeFile(
serverEntry,
old.replace(
`import { hydrate as hydrate$1, unmountComponentAtNode, render as render$1 } from "react-dom";`,
''
)
old
.replace(
`import { hydrate as hydrate$1, unmountComponentAtNode, render as render$1 } from "react-dom";`,
''
)
.replace(
`import ReactDOM__default, { render as render$2, unmountComponentAtNode as unmountComponentAtNode$1, hydrate as hydrate$1 } from "react-dom";`,
'import ReactDOM__default from "react-dom";'
)
)
}

Expand Down
83 changes: 43 additions & 40 deletions packages/vxrn/src/exports/prebuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,52 +123,55 @@ export const prebuild = async ({
)
}

// huh... i needed this, then i didnt, for no apparent reason
// automatically fix build scripts for monorepos
const reactNativeRoot = resolvePath('react-native', root)
// in a monorepo if react-native is at root and current app is at apps/app
// then this value will be "../..", if not it will be ""
const monorepoRelativeRoot = relative(root, reactNativeRoot)
.split(sep)
.filter((x) => x === '..')
.join(sep)
// const reactNativeRoot = resolvePath('react-native', root)
// // in a monorepo if react-native is at root and current app is at apps/app
// // then this value will be "../..", if not it will be ""
// const monorepoRelativeRoot = relative(root, reactNativeRoot)
// .split(sep)
// .filter((x) => x === '..')
// .join(sep)

if (monorepoRelativeRoot) {
if (existsSync('ios')) {
const projectName = findXcworkspaceName('ios')?.replace('.xcworkspace', '')
if (projectName) {
await replaceInUTF8File(
`ios/${projectName}.xcodeproj/project.pbxproj`,
'../node_modules/react-native/scripts/',
`${monorepoRelativeRoot}/../node_modules/react-native/scripts/`
)
}
}
// if (monorepoRelativeRoot) {
// if (existsSync('ios')) {
// const projectName = findXcworkspaceName('ios')?.replace('.xcworkspace', '')
// if (projectName) {
// // note: this is for older react-native, needs testing
// await replaceInUTF8File(
// `ios/${projectName}.xcodeproj/project.pbxproj`,
// '../node_modules/react-native/scripts/',
// `${monorepoRelativeRoot}/../node_modules/react-native/scripts/`
// )
// await replaceInUTF8File(
// `ios/Pods/Pods.xcodeproj/project.pbxproj`,
// `RCT_SCRIPT_POD_INSTALLATION_ROOT/../../../node_modules/react-native`,
// `RCT_SCRIPT_POD_INSTALLATION_ROOT/${monorepoRelativeRoot}/../../../node_modules/react-native`
// )
// }
// }

if (existsSync('android')) {
await replaceInUTF8File(
'android/app/build.gradle',
'../../node_modules/',
`${monorepoRelativeRoot}/../../node_modules/`
)
await replaceInUTF8File(
'android/settings.gradle',
'../node_modules/',
`${monorepoRelativeRoot}/../node_modules/`
)
}
}
// if (existsSync('android')) {
// // TODO test this, leaving commented out since its likely not working
// // await replaceInUTF8File(
// // 'android/app/build.gradle',
// // '../../node_modules/',
// // `${monorepoRelativeRoot}/../../node_modules/`
// // )
// // await replaceInUTF8File(
// // 'android/settings.gradle',
// // '../node_modules/',
// // `${monorepoRelativeRoot}/../node_modules/`
// // )
// }

// console.info(`Note: detected monorepo and build adjusted scripts.`)
// }
}

export async function replaceInUTF8File(
filePath: string,
projectName: string,
templateName: string
) {
export async function replaceInUTF8File(filePath: string, findThis: string, replaceWith: string) {
const fileContent = await FSExtra.readFile(filePath, 'utf8')
const replacedFileContent = fileContent
.replace(new RegExp(templateName, 'g'), projectName)
.replace(new RegExp(templateName.toLowerCase(), 'g'), projectName.toLowerCase())

const replacedFileContent = fileContent.replace(findThis, replaceWith)
if (fileContent !== replacedFileContent) {
await FSExtra.writeFile(filePath, replacedFileContent, 'utf8')
}
Expand Down
2 changes: 2 additions & 0 deletions packages/vxrn/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ export * from './plugins/rollupRemoveUnusedImports'
export * from './plugins/autoPreBundleDepsForSsrPlugin'

export * from './types'

export { prebuildReactNativeModules } from './utils/swapPrebuiltReactModules'
11 changes: 3 additions & 8 deletions packages/vxrn/src/utils/getReactNativeBundle.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import FSExtra, { ensureFile } from 'fs-extra'
import FSExtra from 'fs-extra'
import { readFile } from 'node:fs/promises'
import { dirname, join, relative } from 'node:path'
import type { RollupCache } from 'rollup'
import { createBuilder } from 'vite'
// import { buildEnvironment } from './fork/vite/build'
import { resolvePath } from '@vxrn/resolve'
import { filterPluginsForNative } from './filterPluginsForNative'
import type { VXRNOptionsFilled } from './getOptionsFilled'
import { getReactNativeConfig } from './getReactNativeConfig'
import { isBuildingNativeBundle, setIsBuildingNativeBundle } from './isBuildingNativeBundle'
import { prebuildReactNativeModules } from './swapPrebuiltReactModules'
import { resolvePath } from '@vxrn/resolve'
import { filterPluginsForNative } from './filterPluginsForNative'

const { pathExists } = FSExtra

// used for normalizing hot reloads
export let entryRoot = ''
Expand All @@ -22,8 +19,6 @@ export function clearCachedBundle() {
cachedReactNativeBundles = {}
}

const cache: Record<string, RollupCache> = {}

export async function getReactNativeBundle(
options: VXRNOptionsFilled,
platform: 'ios' | 'android',
Expand Down
2 changes: 1 addition & 1 deletion packages/vxrn/types/exports/prebuild.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ export declare const prebuild: ({ root, platform, expo, }: {
platform?: "ios" | "android" | string;
expo: boolean;
}) => Promise<void>;
export declare function replaceInUTF8File(filePath: string, projectName: string, templateName: string): Promise<void>;
export declare function replaceInUTF8File(filePath: string, findThis: string, replaceWith: string): Promise<void>;
//# sourceMappingURL=prebuild.d.ts.map
1 change: 1 addition & 0 deletions packages/vxrn/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export * from './utils/getServerEntry';
export * from './plugins/rollupRemoveUnusedImports';
export * from './plugins/autoPreBundleDepsForSsrPlugin';
export * from './types';
export { prebuildReactNativeModules } from './utils/swapPrebuiltReactModules';
//# sourceMappingURL=index.d.ts.map
2 changes: 1 addition & 1 deletion packages/vxrn/types/plugins/clientInjectPlugin.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Plugin, UserConfig } from 'vite';
export declare function getServerConfigPlugin(): {
name: string;
configResolved(this: void, conf: Readonly<Omit<UserConfig, "dev" | "server" | "plugins" | "css" | "json" | "assetsInclude" | "optimizeDeps" | "worker" | "build" | "environments" | "preview"> & {
configResolved(this: void, conf: Readonly<Omit<UserConfig, "dev" | "server" | "build" | "plugins" | "css" | "json" | "assetsInclude" | "optimizeDeps" | "worker" | "environments" | "preview"> & {
configFile: string | undefined;
configFileDependencies: string[];
inlineConfig: import("vite").InlineConfig;
Expand Down
2 changes: 1 addition & 1 deletion packages/vxrn/types/utils/getReactNativeConfig.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export declare function getReactNativeConfig(options: VXRNOptionsFilled, interna
};
};
}>;
export declare function getReactNativeResolvedConfig(): Readonly<Omit<UserConfig, "dev" | "server" | "plugins" | "css" | "json" | "assetsInclude" | "optimizeDeps" | "worker" | "build" | "environments" | "preview"> & {
export declare function getReactNativeResolvedConfig(): Readonly<Omit<UserConfig, "dev" | "server" | "build" | "plugins" | "css" | "json" | "assetsInclude" | "optimizeDeps" | "worker" | "environments" | "preview"> & {
configFile: string | undefined;
configFileDependencies: string[];
inlineConfig: InlineConfig;
Expand Down

0 comments on commit e9930b9

Please sign in to comment.