Skip to content

Commit 52455e0

Browse files
Alex Eaglealexeagle
authored andcommitted
feat(examples): show the create-react-app converted to bazel build
1 parent b7bdab7 commit 52455e0

6 files changed

Lines changed: 111 additions & 20 deletions

File tree

docs/examples.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,33 @@ Example: [examples/angular_view_engine](https://github.com/bazelbuild/rules_node
2525

2626
## React
2727

28-
There is a basic example at [examples/react_webpack](https://github.com/bazelbuild/rules_nodejs/tree/master/examples/react_webpack)
28+
Similar to the explanation above for Angular, Bazel is agnostic to what tools you choose to run on your project.
29+
However, the benefits of using Bazel are unlocked as you adopt it as your build system.
30+
We think the following examples show a typical migration of adopting Bazel:
2931

30-
We are likely to add more, as the rules_nodejs core maintainers are working on some React projects.
32+
**create-react-app**: If you run `create-react-app`, it will install a build system called `react-scripts`.
33+
As a first step into Bazel, you can simply ask Bazel to wrap the existing build system.
34+
This guarantees compatibility with your current code, and if your objective is just to include a frontend app into
35+
a bigger full-stack Bazel build, this might be the final step in the migration.
36+
However it will run `react-scripts` as a single Bazel action, which means that you gain no incrementality benefit.
37+
So we expect for most applications this is just a first step.
38+
39+
The [create-react-app example](https://github.com/bazelbuild/rules_nodejs/tree/master/examples/create-react-app)
40+
shows how this will look. We suggest reading the README in that example, and also look at the commit history to that
41+
directory as an illustration of how we started from create-react-app and added Bazel bits.
42+
43+
**cra-eject**: As a next step to make our Build more incremental and performant, we follow the create-react-app suggestion
44+
of "ejecting" the configuration. This means the `react-scripts` build system is gone, and Bazel can take its place.
45+
46+
TODO(alexeagle): build an example illustrating how this looks
47+
48+
**custom**: If you really know your JS build tools, Bazel is the perfect way to assemble all the myriad individual tools
49+
into a custom toolchain. This allows you to unlock any part of the JS ecosystem without waiting for it to be integrated
50+
for you by maintainers of a project like create-react-app, who have a very high bar for adding features since the
51+
maintenance and support burden falls on them. However you'll need to understand both the tools as well as Bazel to
52+
successfully build your own toolchain.
53+
54+
There is a basic example at [examples/react_webpack](https://github.com/bazelbuild/rules_nodejs/tree/master/examples/react_webpack) but it needs a lot more work to show everything that is possible!
3155

3256
## Vue
3357

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
load("@bazel_skylib//rules:write_file.bzl", "write_file")
2+
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
3+
load("@npm//react-scripts:index.bzl", "react_scripts")
4+
5+
# We don't want to teach react-scripts to include from multiple directories
6+
# So we copy everything it wants to read to the output "bin" directory
7+
copy_to_bin(
8+
name = "copy_static_files",
9+
srcs = glob([
10+
"public/*",
11+
"src/*",
12+
]) + [
13+
"package.json",
14+
"tsconfig.json",
15+
],
16+
)
17+
18+
# react-scripts can only work if the working directory is the root of the application.
19+
# So we'll need to chdir before it runs.
20+
write_file(
21+
name = "write_chdir_script",
22+
out = "chdir.js",
23+
content = ["process.chdir(__dirname)"],
24+
)
25+
26+
react_scripts(
27+
# Note: this must be named "build" since react-scripts hard-codes that as the output dir
28+
name = "build",
29+
args = [
30+
"--node_options=--require=./$(execpath chdir.js)",
31+
"build",
32+
],
33+
data = [
34+
"chdir.js",
35+
"copy_static_files",
36+
"@npm//@types",
37+
"@npm//react",
38+
"@npm//react-dom",
39+
],
40+
output_dir = True,
41+
)

examples/create-react-app/README.md

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2+
Then Bazel configuration was added in `WORKSPACE` and `BUILD.bazel`
3+
4+
See the [examples guide](https://bazelbuild.github.io/rules_nodejs/examples#react) for a comparison of the several
5+
approaches you can take to build and test your React app with Bazel.
26

37
## Available Scripts
48

@@ -27,18 +31,3 @@ Your app is ready to be deployed!
2731

2832
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
2933

30-
### `yarn eject`
31-
32-
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33-
34-
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35-
36-
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37-
38-
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39-
40-
## Learn More
41-
42-
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43-
44-
To learn React, check out the [React documentation](https://reactjs.org/).
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
workspace(
2+
name = "create_react_app",
3+
managed_directories = {"@npm": ["node_modules"]},
4+
)
5+
6+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
7+
8+
http_archive(
9+
name = "build_bazel_rules_nodejs",
10+
sha256 = "cb6d92c93a1769205d6573c21363bdbdcf5831af114a7fbc3f800b8598207dee",
11+
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.0.0-rc.2/rules_nodejs-2.0.0-rc.2.tar.gz"],
12+
)
13+
14+
http_archive(
15+
name = "bazel_skylib",
16+
sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44",
17+
urls = [
18+
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
19+
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
20+
],
21+
)
22+
23+
load("@build_bazel_rules_nodejs//:index.bzl", "yarn_install")
24+
25+
yarn_install(
26+
# Name this npm so that Bazel Label references look like @npm//package
27+
name = "npm",
28+
package_json = "//:package.json",
29+
yarn_lock = "//:yarn.lock",
30+
)

examples/create-react-app/package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
"react-scripts": "3.4.1",
1616
"typescript": "~3.7.2"
1717
},
18+
"devDependencies": {
19+
"@bazel/bazelisk": "^1.5.0"
20+
},
1821
"scripts": {
1922
"start": "react-scripts start",
20-
"build": "react-scripts build",
21-
"test": "react-scripts test",
22-
"eject": "react-scripts eject"
23+
"build": "bazel build //:build",
24+
"test": "react-scripts test"
2325
},
2426
"eslintConfig": {
2527
"extends": "react-app"

examples/create-react-app/yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,11 @@
10781078
lodash "^4.17.13"
10791079
to-fast-properties "^2.0.0"
10801080

1081+
"@bazel/bazelisk@^1.5.0":
1082+
version "1.5.0"
1083+
resolved "https://registry.yarnpkg.com/@bazel/bazelisk/-/bazelisk-1.5.0.tgz#61f583ed93be138b47be7180403938ea4057f54b"
1084+
integrity sha512-qhOGN1WmfZYNJXGrRL/0byii9hX5FBomMv3WWI2OEL2+Bxm4t/bR3zMxN3xwQX1C8meSSrAfKGSzxVOZfpJsOg==
1085+
10811086
"@cnakazawa/watch@^1.0.3":
10821087
version "1.0.4"
10831088
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"

0 commit comments

Comments
 (0)