Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: barrel optimization breaking native hmr #500

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/vxrn/src/plugins/reactNativeDevServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export function createReactNativeDevServerPlugin(options: VXRNOptionsFilled): Pl
}

// Handle React Native endpoints
// HMR fetching updates
server.middlewares.use('/file', async (req, res) => {
const url = new URL(req.url!, `http://${req.headers.host}`)
const file = url.searchParams.get('file')
Expand Down
19 changes: 17 additions & 2 deletions packages/vxrn/src/utils/getReactNativeBundle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { readFile } from 'node:fs/promises'
import { dirname, relative } from 'node:path'
import { createBuilder } from 'vite'
import { type BuildEnvironment, createBuilder } from 'vite'
// import { buildEnvironment } from './fork/vite/build'
import { resolvePath } from '@vxrn/resolve'
import { filterPluginsForNative } from './filterPluginsForNative'
Expand Down Expand Up @@ -102,7 +102,22 @@ export async function getReactNativeBundle(
// We are using a forked version of the Vite internal function `buildEnvironment` (which is what `builder.build` calls) that will return the Rollup cache object with the build output, and also with some performance improvements.
// disabled due to differences in vite 6 stable upgrade

const buildOutput = await builder.build(environment)
const buildEnvironment: BuildEnvironment = {
...environment,
init: environment.init,
options: environment.options,
getTopLevelConfig: environment.getTopLevelConfig,
plugins: (() => {
if (internal.mode !== 'prod') {
// Workaround of removing barrel optimization plugins in dev, as it will break HMR because we didn't handle barrel optimizations in HMR yet.
return environment.plugins.filter((p) => !p.name.startsWith('vite-plugin-barrel'))
}

return environment.plugins
})(),
}

const buildOutput = await builder.build(buildEnvironment)

if (process.env.ONE_DEBUG_BUILD_PERF) {
console.info(JSON.stringify(buildStats, null, 2))
Expand Down
3 changes: 3 additions & 0 deletions tests/hmr/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { View, Text, TextInput } from 'react-native'
import { TestComponent } from 'components/TestComponent'
import { TestComponentContainingRelativeImport } from 'components/TestComponentContainingRelativeImport'
import { TestComponentUsingHookThatHasNativeVersion } from 'components/TestComponentUsingHookThatHasNativeVersion'
import { TestComponentImportingBarrelFile } from 'components/TestComponentImportingBarrelFile'

// TODO
// import { TestComponentWithFlatList } from 'components/TestComponentWithFlatList'

Expand All @@ -16,6 +18,7 @@ export default function Page() {
<TestComponent />
<TestComponentContainingRelativeImport />
<TestComponentUsingHookThatHasNativeVersion />
<TestComponentImportingBarrelFile />
{/* <TestComponentWithFlatList /> */}
</View>
)
Expand Down
17 changes: 17 additions & 0 deletions tests/hmr/components/TestComponentImportingBarrelFile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { View, Text } from 'react-native'
import { Rocket } from '@tamagui/lucide-icons'
const IconComponent = Rocket
const text = 'Some text in TestComponentImportingBarrelFile'

export function TestComponentImportingBarrelFile() {
return (
<View>
<Text testID="TestComponentImportingBarrelFile-text-content">{text}</Text>
<Text>
{
IconComponent.toString() /* don't render the actual icon here since it require setting up Tamagui and will introduce additional complexity */
}
</Text>
</View>
)
}
16 changes: 9 additions & 7 deletions tests/hmr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@
"type": "module",
"scripts": {
"dev": "one dev",
"test-macos": "TEST_ONLY=dev vitest",
"test-ios": "TEST_ONLY=dev DEV_PORT=8081 vitest --config ./vitest.config.ios.ts"
},
"devDependencies": {
"playwright": "^1.49.1",
"vitest": "^3.0.5",
"webdriverio": "^9.5.4"
"test-ios": "TEST_ONLY=dev DEV_PORT=8081 vitest --config ./vitest.config.ios.ts",
"test-macos": "TEST_ONLY=dev vitest"
},
"dependencies": {
"@tamagui/lucide-icons": "^1.124.17",
"expo": "~52.0.17",
"expo-modules-core": "2.1.2",
"one": "workspace:*",
"react": "^19.0.0",
"react-native": "^0.76.5",
"react-native-screens": "4.4.0",
"react-native-svg": "^15.11.1",
"vite": "^6.1.0"
},
"devDependencies": {
"playwright": "^1.49.1",
"vitest": "^3.0.5",
"webdriverio": "^9.5.4"
}
}
23 changes: 23 additions & 0 deletions tests/hmr/tests/hmr.test.ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
const driver = await remote(getWebDriverConfig())

const textInput = driver.$('~text-input')
await textInput.waitForDisplayed({ timeout: 2 * 60 * 1000 })

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > route HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:76:3

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > component containing relative import HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:80:3

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > component containing relative import HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:80:3

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > component containing relative import HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:80:3

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > component using hook that have native version HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:92:5

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > component using hook that have native version HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:92:5

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > component using hook that have native version HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:92:5

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > component importing barrel file HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:108:3

Check failure on line 34 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > component importing barrel file HMR

Error: element ("~text-input") still not displayed after 120000ms ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ Element.elementErrorHandlerCallbackFn ../../node_modules/webdriverio/build/index.js:7769:24 ❯ Element.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:34:3 ❯ tests/hmr.test.ios.ts:108:3
await textInput.setValue('app did not reload')
expect((await textInput.getValue()).endsWith('did not reload')).toBe(true)

Expand All @@ -41,7 +41,7 @@
editFn()

try {
const result = await driver.waitUntil(

Check failure on line 44 in tests/hmr/tests/hmr.test.ios.ts

View workflow job for this annotation

GitHub Actions / Native iOS Tests (Dev)

tests/hmr.test.ios.ts > route HMR

Error: Changes did not seem to HMR: Changes did not seem to HMR (timeout) ❯ ../../node_modules/webdriverio/build/index.js:5415:15 ❯ Browser.wrapCommandFn ../../node_modules/@wdio/utils/build/index.js:893:23 ❯ testHMR tests/hmr.test.ios.ts:44:20 ❯ tests/hmr.test.ios.ts:76:3
async () => {
const element = await driver.$(`~${testId}`)
return element && (await element.getText()) === editedText
Expand Down Expand Up @@ -104,6 +104,29 @@
}
)

test('component importing barrel file HMR', { timeout: 5 * 60 * 1000, retry: 3 }, async () => {
await testHMR(
'TestComponentImportingBarrelFile-text-content',
'Some text in TestComponentImportingBarrelFile',
() => {
editFile(
path.join(root, 'components', 'TestComponentImportingBarrelFile.tsx'),
`
import { Rocket } from '@tamagui/lucide-icons'
const IconComponent = Rocket
const text = 'Some text in TestComponentImportingBarrelFile'
`.trim(),
`
import { Heart } from '@tamagui/lucide-icons' // import another icon, this is part of the test
const IconComponent = Heart
const text = 'Some edited text in TestComponentImportingBarrelFile'
`.trim()
)
},
'Some edited text in TestComponentImportingBarrelFile'
)
})

// TODO: make this pass
test.skip('layout HMR', { timeout: 5 * 60 * 1000, retry: 3 }, async () => {
await testHMR(
Expand Down
Loading
Loading