Table of Contents
Introduction
In Ultimate way create your First React Application Tutorial we created fully working react application with Zero configuration, but sometime if you are advanced developer you may want to customise the default configuration that comes with this project.
For example, let’s say you want to customise the web-pack configuration that when you use eject command
So in this tutorial I am going to give you step by step details on you can work with custom configuration in React Application.
If you don’t have React application created with create-react-app package then you should read Ultimate way create your First React Application tutorial first before continuing with this application.
I assume that you have application ready and open in your favourite code editor.
Default Configuration:
Open up package.json file from the react app and into your editor, it should look like as bellow screen if you have not installed any additional packages yet.
{
"name": "first-react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
If you look at the above package.json file now, here under script section we have four script or command written, we already used the start command to start our development web server.
After start command we also have build command, for building the application for production so will get an optimise package we also test command for running Unit Test in this particular project.
And finally we have eject command we can run this command to eject from create-react-app and customise all the tools and configuration that come with this project.
Next if you look at the dependencies section section you can see that we have only three dependencies.
So we have dependency called react which is the main react library we also have dependency to react-dom which is the library for working the DOM In my last tutorial on Hello World Application we used the render method to render the react element inside the browser DOM
We also have react-scripts which is another library that takes care of starting, building, testing and ejecting a create react app project
So the interesting thing here is that under dependencies you don’t see any references to tools like webpack , Babel and so on, you see this is the beauty of using create-react-app package to create react project.
Ejecting from Create react App
If you eject from create react app you will see all the dependencies will appear under the decencies section.
Let’s start ejecting
Now go back to the terminal and navigate to your react project folder and execute following command:
npm run eject
Note the warning on the thermal it says Are you sure you want to eject? This action is permanent. basically ejecting is one way street you can not revert back so don’t execute this command on working react project unless your an advance developer and you know what your doing.
So type in y to say yes for ejecting then you will following process:
once ejecting process is complete, it will show following message:
Now after ejecting back to our project and look at the package.json file:
{
"name": "first-react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@babel/core": "7.4.3",
"@svgr/webpack": "4.1.0",
"@typescript-eslint/eslint-plugin": "1.6.0",
"@typescript-eslint/parser": "1.6.0",
"babel-eslint": "10.0.1",
"babel-jest": "^24.8.0",
"babel-loader": "8.0.5",
"babel-plugin-named-asset-import": "^0.3.2",
"babel-preset-react-app": "^9.0.0",
"camelcase": "^5.2.0",
"case-sensitive-paths-webpack-plugin": "2.2.0",
"css-loader": "2.1.1",
"dotenv": "6.2.0",
"dotenv-expand": "4.2.0",
"eslint": "^5.16.0",
"eslint-config-react-app": "^4.0.1",
"eslint-loader": "2.1.2",
"eslint-plugin-flowtype": "2.50.1",
"eslint-plugin-import": "2.16.0",
"eslint-plugin-jsx-a11y": "6.2.1",
"eslint-plugin-react": "7.12.4",
"eslint-plugin-react-hooks": "^1.5.0",
"file-loader": "3.0.1",
"fs-extra": "7.0.1",
"html-webpack-plugin": "4.0.0-beta.5",
"identity-obj-proxy": "3.0.0",
"is-wsl": "^1.1.0",
"jest": "24.7.1",
"jest-environment-jsdom-fourteen": "0.1.0",
"jest-resolve": "24.7.1",
"jest-watch-typeahead": "0.3.0",
"mini-css-extract-plugin": "0.5.0",
"optimize-css-assets-webpack-plugin": "5.0.1",
"pnp-webpack-plugin": "1.2.1",
"postcss-flexbugs-fixes": "4.1.0",
"postcss-loader": "3.0.0",
"postcss-normalize": "7.0.1",
"postcss-preset-env": "6.6.0",
"postcss-safe-parser": "4.0.1",
"react": "^16.8.6",
"react-app-polyfill": "^1.0.1",
"react-dev-utils": "^9.0.1",
"react-dom": "^16.8.6",
"resolve": "1.10.0",
"sass-loader": "7.1.0",
"semver": "6.0.0",
"style-loader": "0.23.1",
"terser-webpack-plugin": "1.2.3",
"ts-pnp": "1.1.2",
"url-loader": "1.1.2",
"webpack": "4.29.6",
"webpack-dev-server": "3.2.1",
"webpack-manifest-plugin": "2.0.4",
"workbox-webpack-plugin": "4.2.0"
},
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts"
],
"setupFiles": [
"react-app-polyfill/jsdom"
],
"setupFilesAfterEnv": [],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
],
"testEnvironment": "jest-environment-jsdom-fourteen",
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
"^.+\\.module\\.(css|sass|scss)$"
],
"modulePaths": [],
"moduleNameMapper": {
"^react-native$": "react-native-web",
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"web.js",
"js",
"web.ts",
"ts",
"web.tsx",
"tsx",
"json",
"web.jsx",
"jsx",
"node"
],
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
]
},
"babel": {
"presets": [
"react-app"
]
}
}
You will see under dependencies section every single dependency that used in this project.
Config Folder
Now that after executing eject command, you see that there is additional tow folder created config and scripts, as showing below:
So if you want to make any configuration changes related to webpack for your development environment, you can open webpackDevServer.config.js file from config folder to make any necessary tweaks you want and similarly you can use webpack.config.js file production environment changes.
Scripts Folder:
So the script is basically has necessary files to handle starting, building and testing this application command.
if you see the scripts section of package.json file you notice that react-scripts library got replaced with files from this scripts folder:
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
},
Important Note:
Overall important note understand here so before ejecting the project from create-react-app everything is getting handle behind the scene from create-react-app library so use eject only if you know and completely necessary for your project otherwise stick with the default configuration.