1# Expo Module Development Guide
2
3> **Warning:** This doc is outdated and will be updated soon.
4
5- [Generating a new module using `expo-cli` command](#generating-a-new-module-using-expo-cli-command)
6- [The Standard Configuration](#the-standard-configuration)
7  - [npm Scripts](#npm-scripts)
8  - [Auto-generated Configuration Files](#auto-generated-configuration-files)
9  - [Directory Structure](#directory-structure)
10  - [Compiling TypeScript](#compiling-typescript)
11  - [Fast Unit Tests](#fast-unit-tests)
12- [package.json Fields](#packagejson-fields)
13
14This guide explains the standard configuration and tools for working on modules in this repository. One of our goals is to write a coherent, high-quality SDK that is consistent across APIs and stays reliable in a way that is sustainable for the Expo team. Another goal is to reuse knowledge from working on one module and apply it to others by reducing disparity and fragmentation between modules. Expo has many modules and we need to keep Expo and working on Expo simple.
15
16# Generating a new module using `expo-cli` command
17
18`expo-cli` has specific command that would generate module that support TypeScript!
19Run:
20
21- `expo generate-module [new module directory]`
22  - optional `[new module directory]` parameter lets you specify module name (e.g. `expo generate-module expo-test-module` would create `expo-test-module`. If ommited, the script will prompt you about it.
23  - optional `--template <template directory>` will try to use provided `<template directory>` in module creation.
24
25# The Standard Configuration
26
27We use a shared set of configuration files and tools like TypeScript across modules. The `expo-module-scripts` package is the source of truth for much of the configuration. With Yarn workspaces, all modules use the same version of `expo-module-scripts`, helping us structurally ensure we use the same configuration across modules and uniformly use the same versions of Babel, TypeScript, Jest, and other tools.
28
29In a module, include `expo-module-scripts` as a development dependency in package.json:
30
31```json
32{
33  "devDependencies": {
34    "expo-module-scripts": "^<latest version>"
35  }
36}
37```
38
39## npm Scripts
40
41`expo-module-scripts` also defines several scripts that are useful during development or should run during the [npm lifecycle](https://docs.npmjs.com/misc/scripts). Define these common scripts in package.json:
42
43```json
44{
45  "scripts": {
46    "build": "expo-module build",
47    "clean": "expo-module clean",
48    "lint": "expo-module lint",
49    "test": "expo-module test",
50    "postinstall": "expo-module postinstall",
51    "prepare": "expo-module prepare",
52    "prepublishOnly": "expo-module prepublishOnly",
53    "expo-module": "expo-module"
54  }
55}
56```
57
58The `expo-module` program is provided by `expo-module-scripts`. You can run `yarn expo-module --help` to see all of the commands. Several of the scripts are interactive and start file watchers as they are intended for human developers rather than CI. To run the commands in non-interactive mode, set the environment variable `EXPO_NONINTERACTIVE=1`.
59
60## Auto-generated Configuration Files
61
62The `postinstall` script auto-generates configuration files in the package when necessary. For example, Babel looks for its configuration files in the package's directory. Commit these files to Git so we can track changes to these files. This also makes it possible to manually edit and commit those files if necessary.
63
64## Directory Structure
65
66`expo-module-scripts` expects modules to be written in TypeScript under a directory named `src` and will compile the modules to a directory named `build`. **In a module package, commit the `build` directory to Git.** Only the people working on a module need to compile it instead of everyone needing to run `tsc` in each package whenever their local Git repository changes.
67
68In package.json, define the main module of the package to be the compiled entry point under `build`:
69
70```json
71{
72  "main": "build/ExampleModule.js"
73}
74```
75
76Running `yarn clean` will delete the `build` directory.
77
78## Compiling TypeScript
79
80Run `yarn build` to compile the source code. This command starts a file watcher and compiles source files as they are edited and saved. You can also run `yarn expo-module tsc` to run `tsc` directly.
81
82The `postinstall` script generates a small tsconfig.json file that extends the main configuration file inside of `expo-module-scripts`.
83
84## Fast Unit Tests
85
86`expo-module-scripts` also defines a Jest preset. Add a Jest configuration section to package.json:
87
88```json
89{
90  "jest": {
91    "preset": "expo-module-scripts"
92  }
93}
94```
95
96This preset enables TypeScript support with `ts-jest`. It creates a custom tsconfig.json file for Jest tests and configures Jest to run both TypeScript and Babel with `babel-preset-expo` so we more accurately transform the code as if it were part of an app.
97
98Run `yarn test` to run Jest in watcher mode. By default, Jest will run tests affected by changed files and re-run tests when files are edited and saved. Since the unit tests run every time a file changes, we need to keep these tests fast and deterministic.
99
100# package.json Fields
101
102Inside of package.json, set the repository and bugs URLs to the Expo repository. For the homepage URL, link to the source of the module.
103
104```json
105{
106  "repository": {
107    "type": "git",
108    "url": "https://github.com/expo/expo.git"
109  },
110  "author": "Expo",
111  "license": "MIT",
112  "bugs": {
113    "url": "https://github.com/expo/expo/issues"
114  },
115  "homepage": "https://github.com/expo/expo/tree/main/packages/expo-sms"
116}
117```
118