Skip to content

Commit 5260f9f

Browse files
committed
fix: don't ship generated code with the library
1 parent bc1b53e commit 5260f9f

File tree

11 files changed

+122
-192
lines changed

11 files changed

+122
-192
lines changed

docs/pages/build.md

+113-18
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ npx react-native-builder-bob@latest init
2424

2525
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.
2626

27-
> 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`.
28-
2927
You can find details on what exactly it adds in the [Manual configuration](#manual-configuration) section.
3028

3129
## Manual configuration
@@ -46,9 +44,7 @@ To configure your project manually, follow these steps:
4644
"output": "lib",
4745
"targets": [
4846
["module", { "esm": true }],
49-
["commonjs", { "esm": true }],
5047
"typescript",
51-
"codegen"
5248
]
5349
}
5450
```
@@ -120,18 +116,6 @@ To configure your project manually, follow these steps:
120116

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

123-
7. Configure [React Native Codegen](https://reactnative.dev/docs/the-new-architecture/what-is-codegen)
124-
125-
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.
126-
127-
You can follow the [Official Codegen Setup Guide](https://reactnative.dev/docs/the-new-architecture/using-codegen) to enable Codegen.
128-
129-
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).
130-
131-
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.
132-
133-
> 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.
134-
135119
And we're done 🎉
136120

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

282266
#### `codegen`
283267

284-
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.
268+
Enable generating the [React Native Codegen](https://reactnative.dev/docs/the-new-architecture/what-is-codegen) scaffold code when building the library.
269+
270+
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.
271+
272+
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:
273+
274+
1. Add the `codegen` target to the `react-native-builder-bob` field in your `package.json` or `bob.config.js`:
275+
276+
```diff
277+
"source": "src",
278+
"output": "lib",
279+
"targets": [
280+
// …
281+
+ "codegen"
282+
]
283+
```
284+
285+
This will enable the codegen script to run when you publish the library (if `bob build` is configured to be run on publish).
286+
287+
2. Add `@react-native-community/cli` as a `devDependency` in your `package.json`:
288+
289+
```diff
290+
"devDependencies": {
291+
// …
292+
+ "@react-native-community/cli": "^x.x.x"
293+
}
294+
```
295+
296+
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.
297+
298+
3. Add `"includesGeneratedCode": true` and `"outputDir"` to the `codegenConfig` field in your `package.json`:
299+
300+
```diff
301+
"codegenConfig": {
302+
// …
303+
+ "outputDir": {
304+
+ "ios": "ios/generated",
305+
+ "android": "android/generated"
306+
+ },
307+
+ "includesGeneratedCode": true
308+
}
309+
```
310+
311+
4. Update imports in your ios code to use the new paths for the generated code:
312+
313+
- If you have a Turbo Module, replace `YourProjectNameSpec.h` with `YourProjectName/YourProjectNameSpec.h`:
314+
315+
```diff
316+
- #import <YourProjectNameSpec/YourProjectNameSpec.h>
317+
+ #import <YourProjectName/YourProjectNameSpec.h>
318+
```
319+
320+
- If you have a Fabric View, replace `react/renderer/components/YourProjectNameViewSpec/` with `YourProjectName/`:
321+
322+
```diff
323+
- #import <react/renderer/components/YourProjectNameViewSpec/ComponentDescriptors.h>
324+
- #import <react/renderer/components/YourProjectNameViewSpec/EventEmitters.h>
325+
- #import <react/renderer/components/YourProjectNameViewSpec/Props.h>
326+
- #import <react/renderer/components/YourProjectNameViewSpec/RCTComponentViewHelpe
327+
rs.h>
328+
+ #import <YourProjectName/ComponentDescriptors.h>
329+
+ #import <YourProjectName/EventEmitters.h>
330+
+ #import <YourProjectName/Props.h>
331+
+ #import <YourProjectName/RCTComponentViewHelpers.h>
332+
```
333+
334+
5. Add a `react-native.config.js` at the root with the correct `cmakeListsPath`:
335+
336+
```js
337+
/**
338+
* @type {import('@react-native-community/cli-types').UserDependencyConfig}
339+
*/
340+
module.exports = {
341+
dependency: {
342+
platforms: {
343+
android: {
344+
cmakeListsPath: 'generated/jni/CMakeLists.txt',
345+
},
346+
},
347+
},
348+
};
349+
```
350+
351+
This makes sure that gradle will pickup the `CMakeLists.txt` file generated by the codegen script on Android.
352+
353+
6. Add a gradle task to `example/android/app/build.gradle` to automatically run the codegen script when building the example app:
354+
355+
```groovy
356+
tasks.register('invokeLibraryCodegen', Exec) {
357+
workingDir "$rootDir/../../"
358+
359+
def isWindows = System.getProperty('os.name').toLowerCase().contains('windows')
360+
361+
if (isWindows) {
362+
commandLine 'cmd', '/c', 'npx bob build --target codegen'
363+
} else {
364+
commandLine 'sh', '-c', 'npx bob build --target codegen'
365+
}
366+
}
367+
368+
preBuild.dependsOn invokeLibraryCodegen
369+
```
370+
371+
7. Add a `pre_install` hook to `example/ios/Podfile` to automatically run the codegen script when installing pods:
372+
373+
```ruby
374+
pre_install do |installer|
375+
system("cd ../../ && npx bob build --target codegen")
376+
end
377+
```
378+
379+
This will likely be inside the `target 'YourAppName' do` block.
285380

286-
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).
381+
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.
287382

288383
#### `custom`
289384

docs/pages/faq.md

-40
Original file line numberDiff line numberDiff line change
@@ -124,46 +124,6 @@ For more accurate testing, there are various other approaches:
124124

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

127-
## How to opt out of shipping codegen generated code?
128-
129-
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.
130-
131-
If you have a reason to not ship Codegen generated scaffold code with your library, you need do the following steps:
132-
133-
1. Add `"includesGeneratedCode": false` to the `codegenConfig` field in your `package.json`:
134-
135-
```diff
136-
"codegenConfig": {
137-
// …
138-
- "includesGeneratedCode": true
139-
+ "includesGeneratedCode": false
140-
}
141-
```
142-
143-
2. Remove the [`codegen` target](#codegen) from the `react-native-builder-bob` field in your `package.json` or `bob.config.js`:
144-
145-
```diff
146-
"source": "src",
147-
"output": "lib",
148-
"targets": [
149-
// …
150-
- "codegen"
151-
]
152-
```
153-
154-
3. If you have an `exports` field in your `package.json`, ensure that it contains `./package.json`:
155-
156-
```diff
157-
"exports": {
158-
".": {
159-
// …
160-
},
161-
+ "./package.json": "./package.json"
162-
},
163-
```
164-
165-
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).
166-
167127
## Users get a warning when they install my library
168128

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

packages/create-react-native-library/src/exampleApp/addCodegenBuildScript.ts

-58
This file was deleted.

packages/create-react-native-library/src/exampleApp/dependencies.ts

+1-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import path from 'path';
22
import fs from 'fs-extra';
3-
import type { TemplateConfiguration } from '../template';
43
import sortObjectKeys from '../utils/sortObjectKeys';
54

65
type PackageJson = {
@@ -9,25 +8,14 @@ type PackageJson = {
98

109
export async function alignDependencyVersionsWithExampleApp(
1110
pkg: PackageJson,
12-
folder: string,
13-
config: TemplateConfiguration
11+
folder: string
1412
) {
1513
const examplePackageJson = await fs.readJSON(
1614
path.join(folder, 'example', 'package.json')
1715
);
1816

1917
const PACKAGES_TO_COPY = ['react', 'react-native', '@types/react'];
2018

21-
if (
22-
config.example === 'vanilla' &&
23-
(config.project.moduleConfig === 'turbo-modules' ||
24-
config.project.viewConfig === 'fabric-view')
25-
) {
26-
// React Native doesn't provide the community CLI as a dependency.
27-
// We have to read the version from the example app and put to the root package json
28-
PACKAGES_TO_COPY.push('@react-native-community/cli');
29-
}
30-
3119
const devDependencies: Record<string, string> = {};
3220

3321
PACKAGES_TO_COPY.forEach((name) => {

packages/create-react-native-library/src/index.ts

+1-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import kleur from 'kleur';
33
import ora from 'ora';
44
import path from 'path';
55
import yargs from 'yargs';
6-
import { addCodegenBuildScript } from './exampleApp/addCodegenBuildScript';
76
import { alignDependencyVersionsWithExampleApp } from './exampleApp/dependencies';
87
import generateExampleApp from './exampleApp/generateExampleApp';
98
import { printErrorHelp, printNextSteps, printUsedRNVersion } from './inform';
@@ -120,19 +119,7 @@ async function create(_argv: yargs.Arguments<Args>) {
120119
const rootPackageJson = await fs.readJson(path.join(folder, 'package.json'));
121120

122121
if (config.example !== 'none') {
123-
await alignDependencyVersionsWithExampleApp(
124-
rootPackageJson,
125-
folder,
126-
config
127-
);
128-
}
129-
130-
if (
131-
config.example === 'vanilla' &&
132-
(config.project.moduleConfig === 'turbo-modules' ||
133-
config.project.viewConfig === 'fabric-view')
134-
) {
135-
addCodegenBuildScript(folder);
122+
await alignDependencyVersionsWithExampleApp(rootPackageJson, folder);
136123
}
137124

138125
const libraryMetadata = createMetadata(answers);

packages/create-react-native-library/templates/common-local/$package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "<%- project.description %>",
55
"main": "src/index",
66
"codegenConfig": {
7-
"name": "RN<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
7+
"name": "<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
88
"type": <%- project.viewConfig !== null ? '"all"': '"modules"' %>,
99
"jsSrcsDir": "src"
1010
},

packages/create-react-native-library/templates/common/$package.json

+1-11
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,6 @@
170170
"clean": "nitrogen/"
171171
}
172172
],
173-
<% } -%>
174-
<% if (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view') { -%>
175-
"codegen",
176173
<% } -%>
177174
[
178175
"module",
@@ -190,13 +187,9 @@
190187
<% if (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view') { -%>
191188
},
192189
"codegenConfig": {
193-
"name": "RN<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
190+
"name": "<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec",
194191
"type": "<%- project.viewConfig !== null ? 'all': 'modules' -%>",
195192
"jsSrcsDir": "src",
196-
"outputDir": {
197-
"ios": "ios/generated",
198-
"android": "android/generated"
199-
},
200193
"android": {
201194
"javaPackageName": "com.<%- project.package %>"
202195
<% if (example === 'vanilla') { -%>
@@ -207,9 +200,6 @@
207200
"<%- project.name -%>View": "<%- project.name -%>View"
208201
}
209202
<% } -%>
210-
},
211-
"includesGeneratedCode": true
212-
<% } else { -%>
213203
}
214204
<% } -%>
215205
<% } -%>

packages/create-react-native-library/templates/native-library-new/react-native.config.js

-16
This file was deleted.

0 commit comments

Comments
 (0)