Expo 프로젝트를 통해 소스 코드 구성 변경

17530 단어 React NativeExpotech
지금까지의 줄거리는...
저번 보도 초기 상태의 Expo 프로젝트에서 Jest 테스트를 추가했습니다.TypeScript의 경우 공식 안내서의 프로그램 외에 약간의 수정이 필요하다.그리고 이 파일의 구성은 다음과 같다.
$ tree -L 1 .
.
├── App.test.tsx
├── App.tsx
├── app.json
├── assets
├── babel.config.js
├── jest.config.ts
├── node_modules
├── package-lock.json
├── package.json
└── tsconfig.json

2 directories, 8 files
이번에 이 서류의 구성을 다음과 같이 변경하고자 합니다.
  • 소스 코드를 src 디렉터리와 test 디렉터리로 나눈다
  • 접수지를 src/App.tsx
  • 로 변경
    또한 srctest를 분리하는 구조에 익숙해져 있기 때문에 Jest - TypeScript Deep Dive에서 src 아래에 모든 Type Script 파일을 설정하는 것을 추천합니다.Type Script Deep Dive의 구조는 다음과 같습니다.
    for a clean project setup.
    다행히 Expo 프로젝트도 기초가 있어 srctest를 분리해도 복잡한 설정이 되지 않는다.

    src 디렉터리와test 디렉터리로 나뉘기


    그러면 즉시 src 디렉터리와 test 디렉터리를 만들고 파일을 이동합니다.
    $ mkdir src test
    $ mv assets App.tsx ./src
    $ mv App.test.tsx ./test
    
    이때 파일 구조는 다음과 같습니다.
    $ tree -L 2 .
    .
    ├── app.json
    ...
    ├── package-lock.json
    ├── package.json
    ├── src
    │   ├── App.tsx
    │   └── assets
    ├── test
    │   └── App.test.tsx
    └── tsconfig.json
    
    물론 파일 경로가 변경되어 Relative import이 움직이지 않습니다.
    $ npx tsc
    test/App.test.tsx:4:17 - error TS2307: Cannot find module './App' or its corresponding type declarations.
    
    4 import App from "./App";
                      ~~~~~~~
    
    import App from "../src/App";로 수정할 수도 있지만 어쨌든 tsconfig입니다.Non-relative import에서 가져올 jsonbaseUrl을 설정합니다.[1]
    tsconfig.json
    {
      "compilerOptions": {
        ...
        "baseUrl": "./src"
      }
    }
    
    이것이 바로 앱이다.test.tsx측import은 다음과 같습니다.
    App.test.tsx
    import App from "App";
    
    하지만 실수를 찾지 못했다.
    $ npx tsc
    

    시험에 붙다


    그럼, 타입 스크립트의 형 검사는 통과했으니 다음에 테스트를 해보자.
    $ npm test
    
    FAIL  test/App.test.tsx
      ● Test suite failed to run
    
        Cannot find module 'App' from 'test/App.test.tsx'
    
        However, Jest was able to find:
        	'./App.test.tsx'
    
        You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['ts', 'tsx', 'js', 'jsx'].
    
        See https://jestjs.io/docs/en/configuration#modulefileextensions-arraystring
    
          2 | import renderer from "react-test-renderer";
          3 |
        > 4 | import App from "App";
            | ^
    
    App모듈을 찾지 못했다는 욕을 먹었어요.TypeScript의 컴파일러는 이미 통과되었는데, 왜 그럴까요?
    실제로 Expo(React Native) 항목에서 Type Script의 변환은 Type Script 컴파일러tsc가 아니라 조개를 사용하다입니다.또한 Babel의 Type Script 변환 플러그인@babel/plugin-transform-typescript은 tsconfig입니다.제이슨을 읽지 않습니다.[2]
    따라서 babel-plugin-module-resolver를 사용하여 루트를 src 디렉터리로 설정합니다.[3]
    babel.config.js
    module.exports = function (api) {
      api.cache(true);
      return {
        presets: ["babel-preset-expo"],
        plugins: [
          [
            "module-resolver",
            {
              root: ["./src/"],
              extensions: [".ts", ".tsx", ".mjs", ".js", ".jsx"],
            },
          ],
        ],
      };
    };
    
    시험은 이렇게 통과되었다.
    $ npm test
    
    PASS  test/App.test.tsx
      <App />
        ✓ has 1 child (2568 ms)
    

    Expo 설정 변경


    그럼 expo start Expo의 개발 서버를 시작하고 응용 프로그램을 엽니다.
    Failed to compile.
    ENOENT: no such file or directory, open '/Users/takanori_is/Developer/Workspace/my-zenn-content/.work/my-expo-app/assets/favicon.png'
    Unable to resolve asset "./assets/icon.png" from "icon" in your app.json or app.config.js
    (node:73125) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated
    Error: Problem validating asset fields in app.json. See https://docs.expo.io/
     • Field: splash.image - cannot access file at './assets/splash.png'.
     • Field: android.adaptiveIcon.foregroundImage - cannot access file at './assets/adaptive-icon.png'.
     • Field: icon - cannot access file at './assets/icon.png'.
    Failed building JavaScript bundle.
    Unable to resolve "../../App" from "node_modules/expo/AppEntry.js"
    
    assets 및 App 모듈에서 찾을 수 없는 오류가 발생했습니다.우선, 앱.json에서 assets로 미리 수정된 경로입니다.
    app.json
    {
      "expo": {
        ...
        "icon": "./src/assets/icon.png",
        "splash": {
          "image": "./src/assets/splash.png",
          ...
        },
        ...
        "android": {
          "adaptiveIcon": {
            "foregroundImage": "./src/assets/adaptive-icon.png",
            ...
          }
        },
        "web": {
          "favicon": "./src/assets/favicon.png"
        }
      }
    }
    
    다음은 App 모듈을 신청 지점으로 등록해야 합니다.패키지입니다.json에서 필드"main"와 앱 모듈 측면에서 호칭registerRootComponent()을 변경해야 한다.[4]
    package.json
    {
      "main": "src/App.tsx",
      ...
    }
    
    App.tsx
    import { registerRootComponent } from "expo";
    ...
    export default function App() {
      ...
    }
    ...
    registerRootComponent(App);
    
    이렇게 하면 프로그램을 순조롭게 열 수 있다.
    각주
    Relative 및 Non-relative importsTypeScript: Documentation - Module Resolution↩︎ 정보
    Caveats의 섹션 참조@babel/plugin-transform-typescript · Babel↩︎
    이 플러그인은 babel-preset-expo에 포함되어 있습니다.또한 React Native 마법사도 같은 방법Using TypeScript with React Native · React Native↩︎을 사용했습니다.
    registerRootComponent - Expo Documentation ↩︎

    좋은 웹페이지 즐겨찾기