Skip to content

Commit

Permalink
feat(examples): show the create-react-app converted to bazel build
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Eagle authored and alexeagle committed Jul 14, 2020
1 parent b7bdab7 commit 52455e0
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 20 deletions.
28 changes: 26 additions & 2 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,33 @@ Example: [examples/angular_view_engine](https://github.com/bazelbuild/rules_node

## React

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

We are likely to add more, as the rules_nodejs core maintainers are working on some React projects.
**create-react-app**: If you run `create-react-app`, it will install a build system called `react-scripts`.
As a first step into Bazel, you can simply ask Bazel to wrap the existing build system.
This guarantees compatibility with your current code, and if your objective is just to include a frontend app into
a bigger full-stack Bazel build, this might be the final step in the migration.
However it will run `react-scripts` as a single Bazel action, which means that you gain no incrementality benefit.
So we expect for most applications this is just a first step.

The [create-react-app example](https://github.com/bazelbuild/rules_nodejs/tree/master/examples/create-react-app)
shows how this will look. We suggest reading the README in that example, and also look at the commit history to that
directory as an illustration of how we started from create-react-app and added Bazel bits.

**cra-eject**: As a next step to make our Build more incremental and performant, we follow the create-react-app suggestion
of "ejecting" the configuration. This means the `react-scripts` build system is gone, and Bazel can take its place.

TODO(alexeagle): build an example illustrating how this looks

**custom**: If you really know your JS build tools, Bazel is the perfect way to assemble all the myriad individual tools
into a custom toolchain. This allows you to unlock any part of the JS ecosystem without waiting for it to be integrated
for you by maintainers of a project like create-react-app, who have a very high bar for adding features since the
maintenance and support burden falls on them. However you'll need to understand both the tools as well as Bazel to
successfully build your own toolchain.

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!

## Vue

Expand Down
41 changes: 41 additions & 0 deletions examples/create-react-app/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
load("@npm//react-scripts:index.bzl", "react_scripts")

# We don't want to teach react-scripts to include from multiple directories
# So we copy everything it wants to read to the output "bin" directory
copy_to_bin(
name = "copy_static_files",
srcs = glob([
"public/*",
"src/*",
]) + [
"package.json",
"tsconfig.json",
],
)

# react-scripts can only work if the working directory is the root of the application.
# So we'll need to chdir before it runs.
write_file(
name = "write_chdir_script",
out = "chdir.js",
content = ["process.chdir(__dirname)"],
)

react_scripts(
# Note: this must be named "build" since react-scripts hard-codes that as the output dir
name = "build",
args = [
"--node_options=--require=./$(execpath chdir.js)",
"build",
],
data = [
"chdir.js",
"copy_static_files",
"@npm//@types",
"@npm//react",
"@npm//react-dom",
],
output_dir = True,
)
19 changes: 4 additions & 15 deletions examples/create-react-app/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
Then Bazel configuration was added in `WORKSPACE` and `BUILD.bazel`

See the [examples guide](https://bazelbuild.github.io/rules_nodejs/examples#react) for a comparison of the several
approaches you can take to build and test your React app with Bazel.

## Available Scripts

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

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

### `yarn eject`

**Note: this is a one-way operation. Once you `eject`, you can’t go back!**

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.

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.

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.

## Learn More

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).
30 changes: 30 additions & 0 deletions examples/create-react-app/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
workspace(
name = "create_react_app",
managed_directories = {"@npm": ["node_modules"]},
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "cb6d92c93a1769205d6573c21363bdbdcf5831af114a7fbc3f800b8598207dee",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.0.0-rc.2/rules_nodejs-2.0.0-rc.2.tar.gz"],
)

http_archive(
name = "bazel_skylib",
sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
],
)

load("@build_bazel_rules_nodejs//:index.bzl", "yarn_install")

yarn_install(
# Name this npm so that Bazel Label references look like @npm//package
name = "npm",
package_json = "//:package.json",
yarn_lock = "//:yarn.lock",
)
8 changes: 5 additions & 3 deletions examples/create-react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
"react-scripts": "3.4.1",
"typescript": "~3.7.2"
},
"devDependencies": {
"@bazel/bazelisk": "^1.5.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"build": "bazel build //:build",
"test": "react-scripts test"
},
"eslintConfig": {
"extends": "react-app"
Expand Down
5 changes: 5 additions & 0 deletions examples/create-react-app/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,11 @@
lodash "^4.17.13"
to-fast-properties "^2.0.0"

"@bazel/bazelisk@^1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@bazel/bazelisk/-/bazelisk-1.5.0.tgz#61f583ed93be138b47be7180403938ea4057f54b"
integrity sha512-qhOGN1WmfZYNJXGrRL/0byii9hX5FBomMv3WWI2OEL2+Bxm4t/bR3zMxN3xwQX1C8meSSrAfKGSzxVOZfpJsOg==

"@cnakazawa/watch@^1.0.3":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"
Expand Down

0 comments on commit 52455e0

Please sign in to comment.