From 60d28ff6e797cae302600e35db60b3b7f68e742b Mon Sep 17 00:00:00 2001 From: Evan Bacon Date: Sat, 3 Jun 2023 14:41:03 -0500 Subject: [PATCH] feat(cli): Add support for Metro lazy bundling (#22724) # Why - Companion to https://github.com/expo/router/pull/622 # How - Add `lazy` query parameter for Metro requests and `EXPO_NO_METRO_LAZY` to disable the feature. Abiding by https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0605-lazy-bundling.md#__loadbundleasync-in-metro # Test Plan - Works when used with https://github.com/expo/router/pull/622 --------- Co-authored-by: Expo Bot <34669131+expo-bot@users.noreply.github.com> --- docs/pages/more/expo-cli.mdx | 1 + packages/@expo/cli/CHANGELOG.md | 1 + packages/@expo/cli/e2e/__tests__/start-test.ts | 2 +- .../cli/src/start/server/middleware/ManifestMiddleware.ts | 2 ++ .../middleware/__tests__/ManifestMiddleware-test.ts | 8 +++++--- packages/@expo/cli/src/utils/env.ts | 5 +++++ 6 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/pages/more/expo-cli.mdx b/docs/pages/more/expo-cli.mdx index 1acda1d2f2069..1f4e1506bcb67 100644 --- a/docs/pages/more/expo-cli.mdx +++ b/docs/pages/more/expo-cli.mdx @@ -372,6 +372,7 @@ From here, you can choose to generate basic project files like: | `EXPO_USE_CUSTOM_INSPECTOR_PROXY` | **boolean** |
Use a customized inspector proxy with improved support for the Chrome DevTools protocol.
This includes support for the network inspector. | | `EXPO_USE_TYPED_ROUTES` | **boolean** |
Generate TypeScript types for Expo Router.
This includes support for the network inspector. | | `EXPO_NO_CLIENT_ENV_VARS` | **boolean** |
Prevent inlining `EXPO_PUBLIC_` environment variables in client bundles. | +| `EXPO_NO_METRO_LAZY` | **boolean** | Prevent adding the `lazy=true` query parameter to Metro URLs (`metro@0.76.3` and greater). This disables `import()` support. | ## Telemetry diff --git a/packages/@expo/cli/CHANGELOG.md b/packages/@expo/cli/CHANGELOG.md index 13d56fc1cb232..66917728589f8 100644 --- a/packages/@expo/cli/CHANGELOG.md +++ b/packages/@expo/cli/CHANGELOG.md @@ -12,6 +12,7 @@ - Add `npx expo add` as an alias to `npx expo install`. ([#22510](https://github.com/expo/expo/pull/22510) by [@EvanBacon](https://github.com/EvanBacon)) - Add `--reset-cache` flag to `expo start` and `expo export` for interop with the Metro docs. ([#22589](https://github.com/expo/expo/pull/22589) by [@EvanBacon](https://github.com/EvanBacon)) - Add `--no-minify` flag to `npx expo export` to prevent minifying output JavaScript. ([#22544](https://github.com/expo/expo/pull/22544) by [@EvanBacon](https://github.com/EvanBacon)) +- Add `lazy` query parameter for Metro requests and `EXPO_NO_METRO_LAZY` to disable the feature. ([#22724](https://github.com/expo/expo/pull/22724) by [@EvanBacon](https://github.com/EvanBacon)) ### 🐛 Bug fixes diff --git a/packages/@expo/cli/e2e/__tests__/start-test.ts b/packages/@expo/cli/e2e/__tests__/start-test.ts index be25e1ffbcb5e..d8a7d86ca85c6 100644 --- a/packages/@expo/cli/e2e/__tests__/start-test.ts +++ b/packages/@expo/cli/e2e/__tests__/start-test.ts @@ -171,7 +171,7 @@ describe('server', () => { // URLs expect(manifest.launchAsset.url).toBe( - 'http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false' + 'http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&lazy=true' ); expect(manifest.extra.expoGo.debuggerHost).toBe('127.0.0.1:19000'); expect(manifest.extra.expoGo.logUrl).toBe('http://127.0.0.1:19000/logs'); diff --git a/packages/@expo/cli/src/start/server/middleware/ManifestMiddleware.ts b/packages/@expo/cli/src/start/server/middleware/ManifestMiddleware.ts index e0a61151ab9ad..28a5c993be669 100644 --- a/packages/@expo/cli/src/start/server/middleware/ManifestMiddleware.ts +++ b/packages/@expo/cli/src/start/server/middleware/ManifestMiddleware.ts @@ -82,6 +82,7 @@ export function createBundleUrlPath({ dev: String(mode !== 'production'), // TODO: Is this still needed? hot: String(false), + lazy: String(!env.EXPO_NO_METRO_LAZY), }); if (minify) { @@ -259,6 +260,7 @@ export abstract class ManifestMiddleware< dev: String(this.options.mode !== 'production'), // TODO: Is this still needed? hot: String(false), + lazy: String(!env.EXPO_NO_METRO_LAZY), }); if (this.options.minify) { diff --git a/packages/@expo/cli/src/start/server/middleware/__tests__/ManifestMiddleware-test.ts b/packages/@expo/cli/src/start/server/middleware/__tests__/ManifestMiddleware-test.ts index dd7dd73a68781..6872b8d4ef5a2 100644 --- a/packages/@expo/cli/src/start/server/middleware/__tests__/ManifestMiddleware-test.ts +++ b/packages/@expo/cli/src/start/server/middleware/__tests__/ManifestMiddleware-test.ts @@ -93,7 +93,7 @@ describe('checkBrowserRequestAsync', () => { // NOTE(EvanBacon): Browsers won't pass the `expo-platform` header so we need to // provide the `platform=web` query parameter in order for the multi-platform dev server // to return the correct bundle. - '/index.bundle?platform=web&dev=true&hot=false', + '/index.bundle?platform=web&dev=true&hot=false&lazy=true', ], }); expect(res.setHeader).toBeCalledWith('Content-Type', 'text/html'); @@ -138,7 +138,9 @@ describe('_getBundleUrl', () => { mainModuleName: 'index', platform: 'android', }) - ).toEqual('http://evanbacon.dev:8080/index.bundle?platform=android&dev=true&hot=false'); + ).toEqual( + 'http://evanbacon.dev:8080/index.bundle?platform=android&dev=true&hot=false&lazy=true' + ); expect(constructUrl).toHaveBeenCalledWith({ hostname: 'evanbacon.dev', scheme: 'http' }); }); @@ -155,7 +157,7 @@ describe('_getBundleUrl', () => { platform: 'ios', }) ).toEqual( - 'http://localhost:8080/node_modules/expo/AppEntry.bundle?platform=ios&dev=false&hot=false&minify=true' + 'http://localhost:8080/node_modules/expo/AppEntry.bundle?platform=ios&dev=false&hot=false&lazy=true&minify=true' ); expect(constructUrl).toHaveBeenCalledWith({ hostname: undefined, scheme: 'http' }); diff --git a/packages/@expo/cli/src/utils/env.ts b/packages/@expo/cli/src/utils/env.ts index 4706393a09c36..f7649da5d8abe 100644 --- a/packages/@expo/cli/src/utils/env.ts +++ b/packages/@expo/cli/src/utils/env.ts @@ -146,6 +146,11 @@ class Env { get EXPO_USE_TYPED_ROUTES() { return boolish('EXPO_USE_TYPED_ROUTES', false); } + + /** Disable lazy bundling in Metro bundler. */ + get EXPO_NO_METRO_LAZY() { + return boolish('EXPO_NO_METRO_LAZY', false); + } } export const env = new Env();