# Web-ReactSetup-Guided-Project
**Repository Path**: mirrors_LambdaSchool/Web-ReactSetup-Guided-Project
## Basic Information
- **Project Name**: Web-ReactSetup-Guided-Project
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-09-25
- **Last Updated**: 2026-07-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# How to Run this App
* Clone repository.
* Run `npm install`.
* Run `npm run webpack` to bundle the app with a watcher.
* Run `npm run server` to launch the development web server.
* Run `npm test` to run tests.
# Objectives
* Learn to set up a React project from scratch.
* Learn about Eslint, Jest, Enzyme, Babel and Webpack.
* Appreciate the things Create React App does for us.
* Feel warm and fuzzy that we don't _need_ CRA to start a project.
# Requirements
We need `node` version 8.1+ & `npm` version 5.2+. VSCode's `eslint` extension is recommended. Commands are run inside the project folder.
# Steps
## 1. Project Structure
* We need the following dev-dependencies:
* live-server
* Run `npm add -D live-server`.
* Create `index.html` and `index.js` files at the root of the project.
* Inside `index.html`, scaffold a basic html document and create a script tag pointing to a non-existing (for now!) bundle file:
* ``````
* Inside `index.html`, create a div element with an `id` of `target`, which we'll use to attach our React application to the DOM.
* Initialize the project by running `npm init -y`.
* Open the generated `package.json` and edit the `scripts` property:
```javascript
// etc
"scripts": {
"server": "live-server",
"webpack": "webpack --watch",
"test": "jest --watchAll"
},
// etc
```
## 2. Configuring the Linter
* **Talking points:** the importance of linting. The eslint webpage.
* Initialize using the command: `npx eslint --init`. You'll be presented with choices.
* Choose `Use a popular style guide` option.
* Choose `Airbnb`, with `React`, and `JSON` format.
* Allow required dependencies to be installed with npm.
* Edit the automatically created `.eslintrc.json` file to look like this (intellisense helps):
```javascript
{
"extends": "airbnb",
"env": {
"es6": true,
"browser": true,
"node": true,
"jest": true
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true,
"spread": true
}
},
"rules": {
"semi": 2
}
}
```
## 3. Configuring Testing with Jest
* **Talking points:** the importance of testing. Untested code is legacy code.
* Install `jest` using the command `npm add -D jest`.
* Run `npx jest --init` to get an automatically generated jest configuration file. You will be asked some questions.
* When asked, choose environment to use: `jsdom` (browser).
* Create a top-level folder named `setup_tests`.
* Inside `setup_tests`, create a `__mocks__` folder.
* Inside `__mocks__` folder, create `fileMock.js` and `styleMock.js` files.
* Inside `fileMock.js` place the following code:
```javascript
module.exports = 'test-file-stub';
```
* Inside `styleMock.js` place the following code:
```javascript
module.exports = {};
```
* Find the `jest.config.js` file at the root of the project. This was generated automatically.
* Uncomment `moduleNameMapper` and add the following value:
```javascript
moduleNameMapper: {
"\\.(css|less|sass|scss)$": "/setup_tests/__mocks__/styleMock.js",
"\\.(gif|ttf|eot|svg)$": "/setup_tests/__mocks__/fileMock.js"
},
```
## 4. Configuring UI Testing with Enzyme
* We need the following dev-dependencies:
* enzyme
* enzyme-adapter-react-16
* Run `npm add -D enzyme enzyme-adapter-react-16`.
* Create a `setupTests.js` file inside the `setup_tests` top-level folder.
* Add the following code to `setupTests.js`:
```javascript
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
```
* Find the `jest.config.js` file at the root of the project.
* Uncomment `setupFilesAfterEnv` and add the following value:
```javascript
setupFilesAfterEnv: [
'setup_tests/setupTests.js',
],
```
## 5. Configuring Babel
* **Talking points:** transcompiling, the babel website.
* We need the following dev-dependencies:
* @babel/core
* @babel/preset-env
* @babel/preset-react
* Run `npm add -D @babel/core @babel/preset-env @babel/preset-react`.
* Create a `babel.config.js` file at the root of the project.
* Put this configuration inside `babel.config.js`:
```javascript
module.exports = {
presets: [
["@babel/preset-env", { "targets": { "chrome": "60" } }],
"@babel/preset-react"
]
}
```
* `@babel/preset-env` will configure itself according to the desired targets. Edit browser name and version to get more or less aggressive transpiling of the code. Without this `{ "targets": etc etc } ` configuration object, all the JavaScript code will get transpiled down to ES5, which might be overkill depending on project requirements.
## 6. Configuring Webpack
* **Talking points:** concatenation, minification, uglification, the problem of fetching many assets over http.
* We need the following dev-dependencies:
* webpack
* webpack-cli
* babel-loader
* Run `npm add -D webpack webpack-cli babel-loader`.
* Create a `webpack.config.js` file at the root of the project.
* Edit `webpack.config.js` file to add a mode of operation, entry and output points, and extensions:
```javascript
var path = require('path');
module.exports = {
// 'production' mode would minify and uglify the code, and use React's production code
mode: 'development',
// entry is the starting point for the web made by our files through imports and exports
entry: path.resolve(__dirname, 'index.js'),
// all code will get concatenated into a single bundle.js inside a bundle folder
output: {
path: path.resolve(__dirname, 'bundle'),
filename: 'bundle.js',
},
// types of files we want Webpack to bundle
resolve: {
extensions: ['.js', '.jsx'],
},
};
```
* Add a new `module` key to `webpack.config.js` file:
```javascript
var path = require('path');
module.exports = {
// etc
// mode, entry, output, resolve
// etc
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
]
}
}
```
## 7. Creating a Barebones React App
* **Talking points:** difference between React and React DOM.
* Install React and React DOM: `npm add react react-dom`
* Edit index.js as follows:
```javascript
import React from 'react';
import ReactDOM from 'react-dom';
function App() {
return (
Hello World
);
}
ReactDOM.render(
, document.querySelector('#target'),
);
```
* Run Webpack: `npm run dev`
* Run Live Server in a separate terminal: `live-server`
* Run tests in a separate terminal: `npm test`
## 8. Adding Support for CSS and LESS
* We need the following dev-dependencies:
* less
* less-loader
* css-loader
* style-loader
* Run `npm add -D less less-loader css-loader style-loader`.
* Edit the `extensions` part inside `webpack.config.js` to look for `.less` files:
```javascript
{
// etc
resolve: {
extensions: ['.js', '.jsx', '.less', '.css']
},
// etc
}
```
* Add the following objects to the `rules` array inside `webpack.config.js`:
```javascript
{
test: /\.less$/,
exclude: /node_modules/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'less-loader' }
]
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' }
]
}
```
* Create an `index.less` file at the root, add some styles and import it into `index.js` using the following syntax:
* `import './index.less';`
* Remember to restart webpack in order to get the configuration changes.
## 9. Adding Support for Class Properties in React Components
* Run `npm add -D @babel/plugin-proposal-class-properties`.
* Add a `plugins` key to `babel.config.js`:
```javascript
module.exports = {
presets: [
["@babel/preset-env", { "targets": { "chrome": "60" } }],
"@babel/preset-react"
],
plugins: [
'@babel/plugin-proposal-class-properties'
]
}
```
## 10. Removing Linting Error with Arrow Functions in React Components
* With arrow functions we don't need to bind `this` in the constructor.
* Run `npm add -D babel-eslint`.
* Inside `.eslintrc` add a `parser` key:
```javascript
{
"extends": "airbnb",
"parser": "babel-eslint",
// etc
}
```
## 11. Have the Bundler Generate a Source Map
* Add the following field to the configuration in `webpack.config.js`:
```javascript
devtool: 'source-map',
```
## 12. Use Webpack Bundle Analyzer Plugin
* This allows to visually inspect the weight of our npm dependencies.
* Install Webpack Bundle Analyzer by running `npm add -D webpack-bundle-analyzer`.
* Pull the analyzer in at the top of `webpack.config.js`.
```javascript
var BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
```
* Create a plugins property on the module.exports object in `webpack.config.js`.
```javascript
plugins: [
new BundleAnalyzer()
],
```
## 13. Final Touches
* Initialize git repository.
* Add `node_modules` and `bundle` folders to `.gitignore`.
* Prevent configuration files from being linted by creating a top-level `.eslintignore` file.
* Add annoying Airbnb rules to the `eslintrc.json` file with a value of `0` (1 means warning, 2 means error):
```javascript
{
// etc
"rules": {
"semi": 2,
"annoying-rule-we-want-disabled": 0,
// etc
}
}
```