Skip to content

Latest commit

 

History

History
142 lines (99 loc) · 4.15 KB

Migrating Universal Modules to TypeScript.md

File metadata and controls

142 lines (99 loc) · 4.15 KB

Migrating Universal Modules to TypeScript

Change Import

To optimize our libraries for dead code elimination we should migrate our exports to be imported as such:

- import { FileSystem } from 'expo-file-system';

+ import * as FileSystem from 'expo-file-system';

Ideally we would make the main entry-point of a module be a file named like the module like build/FileSystem.js

package.json

- "main": "index.js",

+ "main": "build/<MODULE NAME>.js",
+ "types": "build/<MODULE NAME>.d.ts",

To migrate from libraries using different imports, we should add a deprecation notice.

A lot of libraries are just import from Expo, in these cases we can just the deprecation. Ensure you change all imports across packages/, apps/, and docs/.

src/index.ts

import * as FileSystem from './FileSystem';
export * from './FileSystem';

let wasImportWarningShown = false;
// @ts-ignore: Temporarily define an export named "FileSystem" for legacy compatibility
Object.defineProperty(exports, 'FileSystem', {
  get() {
    if (!wasImportWarningShown) {
      console.warn(
        `The syntax "import { FileSystem } from 'expo-file-system'" is deprecated. Use "import * as FileSystem from 'expo-file-system'" or import named exports instead. Support for the old syntax will be removed in SDK 34.`
      );
      wasImportWarningShown = true;
    }
    return FileSystem;
  },
});

Then eventually remove the index in favor of the named file. (src/FileSystem.ts)

Testing

Migration should include the addition of a src/__tests__ which can be run with yarn test in the root directory of the package.

  1. If the package is using the old structure of test/ for utilities, they should migrate to using jest-expo.

src/__tests__/<MODULE NAME>-test.ts

- import { mockPlatformWeb } from '../../test/mocking';

+ import { mockPlatformWeb } from 'jest-expo';
  1. Add a jest object to the package.json

package.json

"jest": {
  "preset": "expo-module-scripts"
},
  1. Run yarn test to run the tests.

Add the tests to CI

In the root .circleci/config.yaml add a step to the job named expo_sdk. This should be in alphabetic order with the other testing steps.

.circleci/config.yaml

- yarn:
    command: test --maxWorkers 1
    working_directory: ~/expo/packages/expo-sms

Move native dependencies to peerDependencies

In order to prevent overlapping native code in node_modules, we should move any dependencies containing native code to peerDependencies.

Add module scripts

package.json

"scripts": {
    "build": "expo-module build",
    "clean": "expo-module clean",
    "test": "expo-module test",
    "prepare": "expo-module prepare",
    "prepublishOnly": "expo-module prepublishOnly",
    "expo-module": "expo-module"
}

Generate a tsconfig.json file with expo-module-scripts

To get the tsconfig that we use in all of our modules, run expo-module prepare or the yarn script yarn prepare (given the script is defined in a module's package.json)

/tsconfig.json

// @generated by expo-module-scripts
{
  "extends": "expo-module-scripts/tsconfig.base",
  "compilerOptions": {
    "outDir": "./build"
  },
  "include": ["./src"],
  "exclude": ["**/__mocks__/*", "**/__tests__/*"]
}

Various Other Changes

  • Remove babel-preset-expo
  • Remove flow
  • For reusing types across the web implementation's native layer and API layer, types should be moved to a named file with the .types.ts extension. There are cases (expo-av for example) where you should separate types into smaller files.