Обновление react-native
связано с большой болью у разработчиков, часто это занимает много рабочего времени и сил, особенно если проект использует большое количество библиотек или имеет нестандартную структуру.
В этой статье я расскажу с чем мне пришлось столкнуться в проекте c монорепозиторием NX
и что мне помогло решить эту проблему.
Переход по гайду на новую версию React Native
Изначальные версии зависимостей:
"nx": "16.4.0",
"react-native": "0.71.10",
Имея монорепозиторий нужно было перейти на последний React Native
. При переезде на 0.72.3 версию по React Native Helper проекты собираются, но в итоге мы получаем ошибку:
react-native could not be found within the project or in these directories:
../../node_modules
> 1 | import { AppRegistry } from 'react-native'
Проблема в том, что Metro
собрал проект не совсем корректно, сборка через Metro
проходит в несколько этапов:
-
Metro
строит граф всех модулей, - транспилирует модуля в формат, понятный React Native
- и сериализует их, объединяя модули для создания одного или нескольких bundle
Но так как проект использует NX
, его структура отличается от базовой и мы имеем разные конфигурационные файлы на разных уровнях проекта.
Рассмотрим структуру репозитория на NX
:
monorepo-name/
├── apps/ // список наших приложений
│ └── mobile/
│ ├── app.json
│ ├── metro.config.js
│ ├── package.json
│ ├── project.json
│ └── mobile-e2e/
├── libs/ // общие библиотеки, которые мы можем подключать к приложениям
│ └── shared-ui-layout/
│ ├── src/
│ │ └── index.ts
│ ├── .babelrc
│ ├── jest.config.js
│ ├── project.json
│ ├── README.md
│ ├── test-setup.ts
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ └── tsconfig.spec.json
├── tools/
├── babel.config.json
├── jest.config.js
├── jest.preset.js
├── nx.json
├── package-lock.json
├── package.json
└── tsconfig.base.json
Изменение конфига
В данной структуре проекта каждое приложение имеет свой набор конфигурационных файлов, таких как metro.config.js
, package.json
и другие. Однако помимо этих конфигов, существуют также файлы в корневой директории репозитория, которые также необходимо учесть в процессе сборки. У самого NX
есть withNxMetro - эта функция, которая позволяет объединить конфиги NX
и пользовательские в одну. В итоге, для достижения необходимого конфига в файле metro.config.js
, мы внесем следующие изменения:
- Начнем со слияния дефолтных и пользовательских конфигов с помощью функции mergeConfig, следуя рекомендациям из гайда
React Native
. - Затем, результат этого слияния передадим в функцию withNxMetro для объединения с конфигом
NX
.
const { withNxMetro } = require('@nx/react-native')
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
const exclusionList = require('metro-config/src/defaults/exclusionList')
const defaultConfig = getDefaultConfig(__dirname)
const { assetExts, sourceExts } = defaultConfig.resolver
/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const customConfig = {
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
},
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg'],
blockList: exclusionList([/^(?!.*node_modules).*\/dist\/.*/]),
unstable_enableSymlinks: true,
unstable_enablePackageExports: true,
},
}
module.exports = withNxMetro(mergeConfig(defaultConfig, customConfig), {
// Change this to true to see debugging info.
// Useful if you have issues resolving modules
debug: false,
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json'
extensions: [],
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
watchFolders: [],
})
После такого апгрейда metro.config.js
проект запуститься и мы увидим первый экран приложения, который мы так долго хотели увидеть снова. 🎉
Финальные весии библиотек:
"nx": "16.6.0",
"react-native": "0.72.3",
Подытожим:
- Апдейтимся по гайду
- Апгрейдим версии библиотек с
NX
- Меняем
metro.config.js
Заключение
Надеюсь, что это статья помогла решить проблему тех, кто столкнулся с такой ошибкой или все еще сидит на старых версиях NX
и React Native
.
Top comments (1)
Excellent post!