diff --git a/crates/aube-settings/settings.toml b/crates/aube-settings/settings.toml index d17e128d6..1b64c70a2 100644 --- a/crates/aube-settings/settings.toml +++ b/crates/aube-settings/settings.toml @@ -1183,7 +1183,7 @@ examples = [ [disableGlobalVirtualStoreForPackages] description = "Package names whose presence in any importer forces per-project materialization." type = "list" -default = "[\"next\", \"nuxt\", \"parcel\"]" +default = "[\"next\", \"nuxt\", \"parcel\", \"expo\", \"react-native\", \"metro\"]" docs = """ aube's global virtual store makes `node_modules/.aube/` an absolute symlink into `~/.cache/aube/virtual-store/`. Tools whose @@ -1197,11 +1197,15 @@ When `aube install` finds one of these names in any importer's forces per-project materialization for that install and prints a one-line warning naming the trigger. -The default list — `next`, `nuxt`, `parcel` — -covers the tools with concrete walk-up failures: Next.js's Turbopack +The default list — `next`, `nuxt`, `parcel`, `expo`, `react-native`, `metro` — +covers the tools with concrete filesystem-root failures: Next.js's Turbopack canonicalizes through symlinks and walks up for app-router/monorepo detection, Nuxt plugins walk up for config discovery, and Parcel's resolver walks up for -`.parcelrc`. Vite and VitePress are compatible with the global virtual store: +`.parcelrc`. Metro's file map requires symlink targets to stay within the project +root or configured watch folders; Expo and React Native use Metro but normally +declare their framework package rather than `metro` directly. + +Vite and VitePress are compatible with the global virtual store: aube writes `node_modules/.modules.yaml` with the store location, which Vite 8.1+ reads when constructing its filesystem allow-list. For older Vite versions, aube materializes only the Vite dependency path locally and backports diff --git a/docs/settings/index.md b/docs/settings/index.md index f74000b47..00977159c 100644 --- a/docs/settings/index.md +++ b/docs/settings/index.md @@ -1245,7 +1245,7 @@ Examples: Package names whose presence in any importer forces per-project materialization. - Type: `list` -- Default: `["next", "nuxt", "parcel"]` +- Default: `["next", "nuxt", "parcel", "expo", "react-native", "metro"]` - Environment: `npm_config_disable_global_virtual_store_for_packages`, `NPM_CONFIG_DISABLE_GLOBAL_VIRTUAL_STORE_FOR_PACKAGES`, `AUBE_DISABLE_GLOBAL_VIRTUAL_STORE_FOR_PACKAGES` - .npmrc keys: `disableGlobalVirtualStoreForPackages`, `disable-global-virtual-store-for-packages` - Workspace YAML keys: `disableGlobalVirtualStoreForPackages` @@ -1262,11 +1262,15 @@ When `aube install` finds one of these names in any importer's forces per-project materialization for that install and prints a one-line warning naming the trigger. -The default list — `next`, `nuxt`, `parcel` — -covers the tools with concrete walk-up failures: Next.js's Turbopack +The default list — `next`, `nuxt`, `parcel`, `expo`, `react-native`, `metro` — +covers the tools with concrete filesystem-root failures: Next.js's Turbopack canonicalizes through symlinks and walks up for app-router/monorepo detection, Nuxt plugins walk up for config discovery, and Parcel's resolver walks up for -`.parcelrc`. Vite and VitePress are compatible with the global virtual store: +`.parcelrc`. Metro's file map requires symlink targets to stay within the project +root or configured watch folders; Expo and React Native use Metro but normally +declare their framework package rather than `metro` directly. + +Vite and VitePress are compatible with the global virtual store: aube writes `node_modules/.modules.yaml` with the store location, which Vite 8.1+ reads when constructing its filesystem allow-list. For older Vite versions, aube materializes only the Vite dependency path locally and backports diff --git a/test/nextjs_gvs_autodisable.bats b/test/nextjs_gvs_autodisable.bats index 0f09f8779..e16b86ead 100644 --- a/test/nextjs_gvs_autodisable.bats +++ b/test/nextjs_gvs_autodisable.bats @@ -4,7 +4,10 @@ # `disableGlobalVirtualStoreForPackages` is present in an importer's # deps. Next.js's Turbopack canonicalizes every `node_modules/` # symlink and rejects targets outside the project root, which aube's -# gvs layout produces by default. Vite is deliberately absent because +# gvs layout produces by default. Metro's file map likewise requires +# external symlink targets to be included in `watchFolders`; Expo and +# React Native use Metro but normally declare their framework package. +# Vite is deliberately absent because # 8.1+ reads the `.modules.yaml` metadata aube writes. The setting is # the extension point: add any tool with the same restriction, or set # to `[]` to disable the heuristic. @@ -86,6 +89,26 @@ JSON assert_output --partial "\`next\`" } +@test "Metro ecosystem packages disable the global virtual store by default" { + for package in expo react-native metro; do + _make_fake_dep "$package" + mkdir "app-$package" + ( + cd "app-$package" + cat >package.json <