Skip to content

Commit

Permalink
feat: add esm build option for typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Aug 1, 2024
1 parent cc30f7f commit 012497a
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 91 deletions.
21 changes: 16 additions & 5 deletions docs/pages/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ yarn add --dev react-native-builder-bob
"targets": [
["commonjs", { "esm": true }],
["module", { "esm": true }],
"typescript",
["typescript", { "esm": true }]
]
}
```
Expand Down Expand Up @@ -76,12 +76,17 @@ yarn add --dev react-native-builder-bob
"source": "./src/index.tsx",
"main": "./lib/commonjs/index.js",
"module": "./lib/module/index.js",
"types": "./lib/typescript/src/index.d.ts",
"types": "./lib/typescript/commonjs/src/index.d.ts",
"exports": {
".": {
"types": "./typescript/src/index.d.ts",
"import": "./module/index.js",
"require": "./commonjs/index.js"
"import": {
"types": "./lib/typescript/module/src/index.d.ts",
"default": "./lib/module/index.js"
},
"require": {
"types": "./lib/typescript/commonjs/src/index.d.ts",
"default": "./lib/commonjs/index.js"
}
}
},
"files": [
Expand Down Expand Up @@ -224,6 +229,12 @@ Example:

The output file should be referenced in the `types` field or `exports['.'].types` field of `package.json`.

##### `esm`

Setting this option to `true` will output 2 sets of type definitions: one for the CommonJS build and one for the ES module build.

See the [ESM support](./esm.md) guide for more details.

## Commands

The `bob` CLI exposes the following commands:
Expand Down
18 changes: 12 additions & 6 deletions docs/pages/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ You can verify whether ESM support is enabled by checking the configuration for
"targets": [
["commonjs", { "esm": true }],
["module", { "esm": true }],
"typescript",
["typescript", { "esm": true }]
]
}
```

The `"esm": true` option enables ESM-compatible output by adding the `.js` extension to the import statements in the generated files.
The `"esm": true` option enables ESM-compatible output by adding the `.js` extension to the import statements in the generated files. For TypeScript, it also generates 2 sets of type definitions: one for the CommonJS build and one for the ES module build.

It's recommended to specify `"moduleResolution": "Bundler"` in your `tsconfig.json` file as well:

Expand All @@ -43,10 +43,16 @@ There are still a few things to keep in mind if you want your library to be ESM-
```json
"exports": {
".": {
"types": "./lib/typescript/src/index.d.ts",
"react-native": "./lib/modules/index.native.js",
"import": "./lib/modules/index.js",
"require": "./lib/commonjs/index.js"
"import": {
"types": "./lib/typescript/module/src/index.d.ts",
"react-native": "./lib/modules/index.native.js",
"default": "./lib/module/index.js"
},
"require": {
"types": "./lib/typescript/commonjs/src/index.d.ts",
"react-native": "./lib/commonjs/index.native.js",
"default": "./lib/commonjs/index.js"
}
}
}
```
2 changes: 1 addition & 1 deletion packages/create-react-native-library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import generateExampleApp, {
import { spawn } from './utils/spawn';
import { version } from '../package.json';

const FALLBACK_BOB_VERSION = '0.28.0';
const FALLBACK_BOB_VERSION = '0.29.0';

const BINARIES = [
/(gradlew|\.(jar|keystore|png|jpg|gif))$/,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
"source": "./src/index.tsx",
"main": "./lib/commonjs/index.js",
"module": "./lib/module/index.js",
"types": "./lib/typescript/src/index.d.ts",
"exports": {
".": {
"types": "./lib/typescript/src/index.d.ts",
"import": "./lib/module/index.js",
"require": "./lib/commonjs/index.js"
"import": {
"types": "./lib/typescript/module/src/index.d.ts",
"default": "./lib/module/index.js"
},
"require": {
"types": "./lib/typescript/commonjs/src/index.d.ts",
"default": "./lib/commonjs/index.js"
}
}
},
"files": [
Expand Down Expand Up @@ -178,7 +182,8 @@
[
"typescript",
{
"project": "tsconfig.build.json"
"project": "tsconfig.build.json",
"esm": true
}
]
]
Expand Down
64 changes: 41 additions & 23 deletions packages/react-native-builder-bob/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,29 @@ yargs
entries.main = entries.source;
}

const types: {
[key in 'require' | 'import']?: string;
} = {};

if (targets.includes('typescript')) {
entries.types = `./${path.join(
types.require = `./${path.join(
output,
'typescript',
'commonjs',
source,
'index.d.ts'
)}`;

types.import = `./${path.join(
output,
'typescript',
'module',
source,
'index.d.ts'
)}`;

entries.types = types.require;

if (!(await fs.pathExists(path.join(root, 'tsconfig.json')))) {
const { tsconfig } = await prompts({
type: 'confirm',
Expand Down Expand Up @@ -258,9 +273,14 @@ yargs

const exports = {
'.': {
...(entries.types ? { types: entries.types } : null),
...(entries.module ? { import: entries.module } : null),
...(entries.main ? { require: entries.main } : null),
import: {
...(types.import ? { types: types.import } : null),
...(entries.module ? { default: entries.module } : null),
},
require: {
...(types.require ? { types: types.require } : null),
...(entries.main ? { default: entries.main } : null),
},
},
};

Expand Down Expand Up @@ -318,25 +338,23 @@ yargs
pkg.scripts.prepare = prepare;
}

if (
pkg.files &&
JSON.stringify(pkg.files.slice().sort()) !==
JSON.stringify(files.slice().sort())
) {
const { update } = await prompts({
type: 'confirm',
name: 'update',
message: `Your package.json already has a 'files' field.\n Do you want to update it?`,
initial: true,
});
if (pkg.files) {
const pkgFiles = pkg.files;

if (update) {
pkg.files = [
...files,
...pkg.files.filter(
(file: string) => !files.includes(file.replace(/\/$/g, ''))
),
];
if (files?.some((file) => !pkgFiles.includes(file))) {
const { update } = await prompts({
type: 'confirm',
name: 'update',
message: `Your package.json already has a 'files' field.\n Do you want to update it?`,
initial: true,
});

if (update) {
pkg.files = [
...files,
...pkg.files.filter((file: string) => !files.includes(file)),
];
}
}
} else {
pkg.files = files;
Expand All @@ -350,7 +368,7 @@ yargs
return [t, { copyFlow: true }];
}

if (t === 'commonjs' || t === 'module') {
if (t === 'commonjs' || t === 'module' || t === 'typescript') {
return [t, { esm }];
}

Expand Down
Loading

0 comments on commit 012497a

Please sign in to comment.