In this short post, I will show you how you can integrate React applications created using create-react-app
with Gradle build tool. We will cover how to build and run the tests as part of the Gradle build.
We will start by creating a sample application using create-react-app
. To do that you need to have Nodejs 8.0+ installed on your machine.
npx create-react-app myapp
npx comes with nam 5.2+ and higher.
It will take few minutes to download and install all the dependencies. Once installed, your React app will be inside the myapp
directory. Change directory to it.
cd myapp
Once inside the myapp
, directory we will initialise a Gradle project using the init command as shown below.
gradle init --type basic --dsl groovy --project-name myapp
You need to have Gradle installed on your machine to run the above command. You can use SDKMAN to do that.
The above command will add Gradle build scripts and wrapper files.
Now, we have both React applications and Gradle scripts.
Next step that we have to do is to configure our build script to run React npm scripts.
For example, to build the project, you will use npm run build
project.
Copy and paste the following contents to the build.gradle
file.
plugins { id "com.moowork.node" version "1.2.0" } apply plugin: 'base' apply plugin: "com.moowork.node" node { version = "10.15.0" download = true } task bundle(type: NpmTask, dependsOn: npmInstall) { args = ['run', 'build'] } assemble.dependsOn(bundle)
In the script file above, we have done following:
- We used
com.moowork.node
plugin and applied in line 6 - We applied
base
plugin that gives us the base set of tasks that we can use in the build file. Theassemble
task used in line 17 comes frombase
plugin - Next, we configure
node
plugin to use latest version of node. We asked it to download it if it is not presented. - Next, we created a new task called
bundle
that executes thenpm run build
command. We made it extendNpmTask
and made it dependent onnpmInstall
. ThedependsOn
ensures add dependency of one task on another. So,npm install
will run before build the bundle - Finally, we made assemble depend on
bundle
. This means when Gradle tries to runassemble
task it will first run the custom taskbundle
.
You can run the build using Gradle now by executing following command.
If you are on Mac or Linux machine then you can run following
./gradlew clean build
If on Windows, then you can use
gradlew.bat clean build
The above will build the project and create bundle in the build
directory.
You might be wondering how to execute React application tests in the build.
To do that, you have to create a new task in the build.gradle
file.
task test(type: NpmTask) { environment = ['CI': 'true'] args = ['run', 'test'] } check.dependsOn(test)
One important thing to note is the use of environment variable CI
. The line 3 environment = ['CI': 'true']
creates an environment variable CI
and set its value to true
. This is required because it makes tests run once and process to exit. If you don’t set this environment variable then tests will run in the watch mode and your build will not finish.
Once, you have added test
task and made check
task depend on it then you can run the full build with tests.
./gradlew clean build
The output of the above will be as shown below.
> Task :bundle > myapp@0.1.0 build myapp > react-scripts build Creating an optimized production build... Compiled successfully. File sizes after gzip: 34.73 KB build/static/js/1.0a7a1053.chunk.js 763 B build/static/js/runtime~main.229c360f.js 712 B build/static/js/main.e60ceb44.chunk.js 510 B build/static/css/main.a8b098db.chunk.css ... > Task :test > myapp@0.1.0 test myapp > react-scripts test PASS src/App.test.js ✓ renders without crashing (23ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.858s Ran all test suites. BUILD SUCCESSFUL in 14s 5 actionable tasks: 3 executed, 2 up-to-date
The Github repository for the project is here https://github.com/shekhargulati/gradle-react-app.
For npm package releases you might want to check https://github.com/wooga/atlas-node-release