Skip to content

fix: don't ship generated code with the library #819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 113 additions & 18 deletions docs/pages/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ npx react-native-builder-bob@latest init

This will ask you a few questions and add the required configuration and scripts for building the code. The code will be compiled automatically when the package is published.

> Note: the `init` command doesn't add the [`codegen` target](#codegen) yet. You can either add it manually or create a new library with `create-react-native-library`.

You can find details on what exactly it adds in the [Manual configuration](#manual-configuration) section.

## Manual configuration
Expand All @@ -46,9 +44,7 @@ To configure your project manually, follow these steps:
"output": "lib",
"targets": [
["module", { "esm": true }],
["commonjs", { "esm": true }],
"typescript",
"codegen"
]
}
```
Expand Down Expand Up @@ -120,18 +116,6 @@ To configure your project manually, follow these steps:

This makes sure that Jest doesn't try to run the tests in the generated files.

7. Configure [React Native Codegen](https://reactnative.dev/docs/the-new-architecture/what-is-codegen)

If your library supports the [New React Native Architecture](https://reactnative.dev/architecture/landing-page), you should also configure Codegen. This is not required for libraries that only support the old architecture.

You can follow the [Official Codegen Setup Guide](https://reactnative.dev/docs/the-new-architecture/using-codegen) to enable Codegen.

It's also recommended to ship your Codegen generated scaffold code with your library since it has numerous benefits. To see the benefits and implement this behavior, you can see the [Official Codegen Shipping Guide](https://reactnative.dev/docs/the-new-architecture/codegen-cli#including-generated-code-into-libraries).

See [How to opt-out of shipping the Codegen generated code](./faq.md#how-to-opt-out-of-shipping-codegen-generated-scaffold-code) if you don't want to ship the Codegen generated scaffold code.

> Note: If you enable Codegen generated code shipping, React Native won't build the scaffold code automatically when you build your test app. You need to rebuild the codegen scaffold code manually each time you make changes to your spec. If you want to automate this process, you can create a new project with `create-react-native-library` and inspect the example app.

And we're done 🎉

## Options
Expand Down Expand Up @@ -281,9 +265,120 @@ If you need to support legacy setups that use `moduleResolution: node10` or `mod

#### `codegen`

Enable generating the [React Native Codegen](https://reactnative.dev/docs/the-new-architecture/what-is-codegen) scaffold code, which is used with the New React Native Architecture.
Enable generating the [React Native Codegen](https://reactnative.dev/docs/the-new-architecture/what-is-codegen) scaffold code when building the library.

If you use this `target`, you'll also want to use `"includesGeneratedCode": true` to ship the generated code with your library. Before you do so, make sure to [read the official docs](https://reactnative.dev/docs/the-new-architecture/codegen-cli#including-generated-code-into-libraries) to understand the advantages and tradeoffs of this approach.

If you want to ship codegen generated code with your library, you can do the following steps to integrate it with the library's workflow:

1. Add the `codegen` target to the `react-native-builder-bob` field in your `package.json` or `bob.config.js`:

```diff
"source": "src",
"output": "lib",
"targets": [
// …
+ "codegen"
]
```

This will enable the codegen script to run when you publish the library (if `bob build` is configured to be run on publish).

2. Add `@react-native-community/cli` as a `devDependency` in your `package.json`:

```diff
"devDependencies": {
// …
+ "@react-native-community/cli": "^x.x.x"
}
```

For the `@react-native-community/cli` version, refer to the `example/package.json` file. The version should be the same as the one used in the `example` app.

3. Add `"includesGeneratedCode": true` and `"outputDir"` to the `codegenConfig` field in your `package.json`:

```diff
"codegenConfig": {
// …
+ "outputDir": {
+ "ios": "ios/generated",
+ "android": "android/generated"
+ },
+ "includesGeneratedCode": true
}
```

4. Update imports in your ios code to use the new paths for the generated code:

- If you have a Turbo Module, replace `YourProjectNameSpec.h` with `YourProjectName/YourProjectNameSpec.h`:

```diff
- #import <YourProjectNameSpec/YourProjectNameSpec.h>
+ #import <YourProjectName/YourProjectNameSpec.h>
```

- If you have a Fabric View, replace `react/renderer/components/YourProjectNameViewSpec/` with `YourProjectName/`:

```diff
- #import <react/renderer/components/YourProjectNameViewSpec/ComponentDescriptors.h>
- #import <react/renderer/components/YourProjectNameViewSpec/EventEmitters.h>
- #import <react/renderer/components/YourProjectNameViewSpec/Props.h>
- #import <react/renderer/components/YourProjectNameViewSpec/RCTComponentViewHelpe
rs.h>
+ #import <YourProjectName/ComponentDescriptors.h>
+ #import <YourProjectName/EventEmitters.h>
+ #import <YourProjectName/Props.h>
+ #import <YourProjectName/RCTComponentViewHelpers.h>
```

5. Add a `react-native.config.js` at the root with the correct `cmakeListsPath`:

```js
/**
* @type {import('@react-native-community/cli-types').UserDependencyConfig}
*/
module.exports = {
dependency: {
platforms: {
android: {
cmakeListsPath: 'generated/jni/CMakeLists.txt',
},
},
},
};
```

This makes sure that gradle will pickup the `CMakeLists.txt` file generated by the codegen script on Android.

6. Add a gradle task to `example/android/app/build.gradle` to automatically run the codegen script when building the example app:

```groovy
tasks.register('invokeLibraryCodegen', Exec) {
workingDir "$rootDir/../../"

def isWindows = System.getProperty('os.name').toLowerCase().contains('windows')

if (isWindows) {
commandLine 'cmd', '/c', 'npx bob build --target codegen'
} else {
commandLine 'sh', '-c', 'npx bob build --target codegen'
}
}

preBuild.dependsOn invokeLibraryCodegen
```

7. Add a `pre_install` hook to `example/ios/Podfile` to automatically run the codegen script when installing pods:

```ruby
pre_install do |installer|
system("cd ../../ && npx bob build --target codegen")
end
```

This will likely be inside the `target 'YourAppName' do` block.

You can ensure your Codegen generated scaffold code is stable through different React Native versions by shipping it with your library. You can find more in the [React Native Official Docs](https://reactnative.dev/docs/the-new-architecture/codegen-cli#including-generated-code-into-libraries).
And you're done! Make sure to run `pod install` in the `example/ios` folder and then run the example app to make sure everything works.

#### `custom`

Expand Down
40 changes: 0 additions & 40 deletions docs/pages/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,46 +124,6 @@ For more accurate testing, there are various other approaches:

You can find installation and usage instructions in the [Verdaccio documentation](https://verdaccio.org/docs/en/installation).

## How to opt out of shipping codegen generated code?

We recommend shipping the generated scaffold code with your library due to [the benefits mentioned in React Native docs](https://reactnative.dev/docs/the-new-architecture/codegen-cli#including-generated-code-into-libraries). The new architecture libraries generated by `create-react-native-library` include the generated scaffold code by default.

If you have a reason to not ship Codegen generated scaffold code with your library, you need do the following steps:

1. Add `"includesGeneratedCode": false` to the `codegenConfig` field in your `package.json`:

```diff
"codegenConfig": {
// …
- "includesGeneratedCode": true
+ "includesGeneratedCode": false
}
```

2. Remove the [`codegen` target](#codegen) from the `react-native-builder-bob` field in your `package.json` or `bob.config.js`:

```diff
"source": "src",
"output": "lib",
"targets": [
// …
- "codegen"
]
```

3. If you have an `exports` field in your `package.json`, ensure that it contains `./package.json`:

```diff
"exports": {
".": {
// …
},
+ "./package.json": "./package.json"
},
```

This is required for React Native Codegen to read the `codegenConfig` field from your library's `package.json`. You can find the related issue [here](https://github.com/callstack/react-native-builder-bob/issues/637).

## Users get a warning when they install my library

If users are using Yarn 1, they may get a warning when installing your library:
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import path from 'path';
import fs from 'fs-extra';
import type { TemplateConfiguration } from '../template';
import sortObjectKeys from '../utils/sortObjectKeys';

type PackageJson = {
Expand All @@ -9,8 +8,7 @@ type PackageJson = {

export async function alignDependencyVersionsWithExampleApp(
pkg: PackageJson,
folder: string,
config: TemplateConfiguration
folder: string
) {
const examplePackageJson = await fs.readJSON(
path.join(folder, 'example', 'package.json')
Expand All @@ -23,16 +21,6 @@ export async function alignDependencyVersionsWithExampleApp(
'@react-native/babel-preset',
];

if (
config.example === 'vanilla' &&
(config.project.moduleConfig === 'turbo-modules' ||
config.project.viewConfig === 'fabric-view')
) {
// React Native doesn't provide the community CLI as a dependency.
// We have to read the version from the example app and put to the root package json
PACKAGES_TO_COPY.push('@react-native-community/cli');
}

const devDependencies: Record<string, string> = {};

PACKAGES_TO_COPY.forEach((name) => {
Expand Down
15 changes: 1 addition & 14 deletions packages/create-react-native-library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import kleur from 'kleur';
import ora from 'ora';
import path from 'path';
import yargs from 'yargs';
import { addCodegenBuildScript } from './exampleApp/addCodegenBuildScript';
import { alignDependencyVersionsWithExampleApp } from './exampleApp/dependencies';
import generateExampleApp from './exampleApp/generateExampleApp';
import { printErrorHelp, printNextSteps, printUsedRNVersion } from './inform';
Expand Down Expand Up @@ -120,19 +119,7 @@ async function create(_argv: yargs.Arguments<Args>) {
const rootPackageJson = await fs.readJson(path.join(folder, 'package.json'));

if (config.example !== 'none') {
await alignDependencyVersionsWithExampleApp(
rootPackageJson,
folder,
config
);
}

if (
config.example === 'vanilla' &&
(config.project.moduleConfig === 'turbo-modules' ||
config.project.viewConfig === 'fabric-view')
) {
addCodegenBuildScript(folder);
await alignDependencyVersionsWithExampleApp(rootPackageJson, folder);
}

const libraryMetadata = createMetadata(answers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "<%- project.description %>",
"main": "src/index",
"codegenConfig": {
"name": "RN<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
"name": "<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
"type": <%- project.viewConfig !== null ? '"all"': '"modules"' %>,
"jsSrcsDir": "src"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,6 @@
"clean": "nitrogen/"
}
],
<% } -%>
<% if (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view') { -%>
"codegen",
<% } -%>
[
"module",
Expand All @@ -191,13 +188,9 @@
<% if (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view') { -%>
},
"codegenConfig": {
"name": "RN<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
"name": "<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
"type": "<%- project.viewConfig !== null ? 'all': 'modules' -%>",
"jsSrcsDir": "src",
"outputDir": {
"ios": "ios/generated",
"android": "android/generated"
},
"android": {
"javaPackageName": "com.<%- project.package %>"
<% if (example === 'vanilla') { -%>
Expand All @@ -208,9 +201,6 @@
"<%- project.name -%>View": "<%- project.name -%>View"
}
<% } -%>
},
"includesGeneratedCode": true
<% } else { -%>
}
<% } -%>
<% } -%>
Expand Down

This file was deleted.

Loading
Loading