평화로이 React Native 프로젝트를 생성하여 프로젝트 진행을 하던 도중, JSX 문법을 사용하는 화면마다 Can't find variable: React
에러가 발생했다 !
React 17 이후로 React를 직접 import하지 않아도 JSX 문법을 사용할 수 있도록 React 컴파일러 react/jsx-runtime
을 업데이트 했기 때문이다.
React Native 버전 0.64 이후부터 React 17 버전을 지원하고, 내 프로젝트의 React Native 버전은 0.69이기 때문에 해당 기능을 사용할 수 있었다.
구글링을 통해 해결책을 찾았다. 참고
react-native-cli
의 프로젝트 기본 설정값으로는 새로운 JSX 변환 기능을 사용하지 않도록 설정되므로 이 기능을 활성화하기 위해 프로젝트의 babel.config.js
파일을 수정해야 한다.
기존 babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
새 babel.config.js
module.exports = {
presets: [
['module:metro-react-native-babel-preset', { useTransformReactJSXExperimental: true }]
],
plugins: [
['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }]
]
];
그리고 다음과 같이 babel plugin 의존성도 추가해주어야 한다.
yarn add @babel/plugin-transform-react-jsx
기본적으로 metro-react-native-babel-preset
은 @babel/plugin-transform-react-jsx
를 포함한다.
그런데 왜 plugins에 또 babel 플러그인을 추가해야 할까?
이유는 metro-react-native-babel-preset
모듈의 useTransformReactJSXExperimental
옵션을 true로 변경하는 것 뿐만 아니라 runtime 옵션값도 추가적으로 변경해줘야 하기 때문이다.
@babel/plugin-transform-react-jsx
플러그인의 runtime 옵션은 기본값이 'classic'이고, 이는 예전 JSX 변환 기능에서 사용하는 옵션값이다.
이 옵션을 'automatic'으로 변경해야 하기 때문에, plugins 부분에도 추가해야 하는 것이다.
참고
babel 옵션 형식
위 글에서 babel 옵션 값을 이렇게 설정하신 분이 계시다.
// 간소화된 예시
module.exports = {
presets: [
'module:metro-react-native-babel-preset',
{
'useTransformReactJSXExperimental': true,
},
]
};
babel은 위 코드를 useTransformReactJSXExperimental
옵션 값이 metro-react-native-babel-preset
모듈과 별개의 옵션 값이라고 해석한다.
따라서 해당 옵션은 무시된다.
cache 값 초기화
또한, yarn이나 npm과 같은 Package Manager는 성능, 자원등의 이유로 자주 변경되지 않는 설정 값 등은 캐시에 저장하고 캐시에서 설정 값을 불러오는 기능을 제공하기 때문에, babel 설정 값이 변경된 후에 캐시를 초기화하는 커맨드를 입력해주는 게 좋다.
yarn cache clean / npm cache clean --force