Welcome to ReHacked! By the end of this lab, you will have:
- Created a "ground up" React SPA using Webpack and Babel (for JSX and ES2015 support)
- Implemented some React components
- Implemented a simple routing system
- Implemented a service to talk to a Web API for simple authentication
- Deployed the React SPA to Firebase
- SourceTree (If not using WebStorm)
-
Signup for a GitHub account
-
Install git
-
Install Node Version Manager (Windows NVM)
-
Install Node 4.4.5 (using
nvm install 4.4.5
) -
Execute
nvm alias default 4.4.5
-
Execute
npm install -g npm3
-
Signup for a Firebase account
- Go to a directory of your choice and create a
rehacked-spa-basics
folder
- bash:
mkdir rehacked-spa-basics && $_
- Create a
README.md
file
- bash:
echo "# rehacked-spa-basics" >> README.md
- Create a
.gitignore
file
- bash:
printf "# node\nnode_modules\n\n# IDE\n.idea\n\n# webpack\nbuild" >> .gitignore
- Execute
npm init
(Interactively creates a package.json file)
- name: rehacked-spa-basics
- version: 1.0.0
- description: A React SPA with basic functionality
- entry point: ./src/app.js
- test command:
- git repository:
- keywords:
- author: [Enter your name]
- license:
- Execute
npm3 install -g webpack webpack-dev-server
- Execute
npm3 install react react-dom react-router isomorphic-fetch material-design-lite classnames babel-polyfill babel-preset-es2015 babel-preset-react --save
- Execute
npm3 install babel-core babel-loader css-loader extract-text-webpack-plugin file-loader node-sass null-loader open-browser-webpack-plugin sass-loader source-map-loader static-loader style-loader webpack webpack-dev-server --save-dev
-
Execute
git init
-
Execute
git add .
-
Execute
git commit -m "initial commit"
-
Create a new empty repo on GitHub
-
Execute
git remote add origin [https link to your Git repo]
-
Execute
git push -u origin master
- Create a
webpack.config.js
file
- bash:
touch webpack.config.js
-
Copy contents of pre-defined webpack config
-
Create a
config
directory and alocal.js
file in it
- bash:
mkdir config && cd $_ && touch local.js && cd -
- Copy contents of pre-defined local environment config to
local.js
- Create an
index.html
,app.js
, anddependencies.js
for your SPA
- bash:
mkdir src && cd $_ && touch app.js && touch index.html && touch dependencies.js && cd -
-
Copy contents of pre-defined index.html to
index.html
-
Copy contents of pre-defined app.js to
app.js
-
Copy contents of predefined dependencies.js
-
Create a
components
subdirectory under thesrc
folder. -
Create
StartScreen/index.js
undercomponents
- bash (from the root of the project):
mkdir -p src/components/StartScreen && cd $_ && touch index.js && cd -
-
Add basic class with render function that returns hello from react div
-
Create
Dashboard/index.js
- bash (from the root of the project):
mkdir -p src/components/Dashboard && cd $_ && touch index.js && cd -
-
Add basic class with render function that returns My Dashboard div
-
Start app by going to the root of your repo and executing one of the following:
- *nix Environments:
webpack-dev-server --config webpack.config.js --content-base build/ --inline --hot
- Windows Environments
webpack-dev-server --progress --colors --inline --content-base build/
- Create
src/common/services/user.js
- bash (from the root of the project):
mkdir -p src/common/services && cd $_ && touch user.js && cd -
- Create
src/common/constants/environment.js
- bash (from the root of the project):
mkdir -p src/common/constants && cd $_ && touch environment.js && cd -
- Export API_PATH from
environment.js
export const ENVIRONMENT = { API_PATH: 'https://baseline-sails-api.herokuapp.com' };
- Create
src/common/constants/endpoints.js
- bash (from the root of the project):
mkdir -p src/common/constants && cd $_ && touch endpoints.js && cd -
- Export USER const from
endpoints.js
export const USER = { LOGIN: '/user/login' };
-
Import 'isomorphic-fetch', {ENVIRONMENT} and {USER} in
user.js
-
Export
login
function in/src/common/services/user.js
-
Import
* as UserService
inStartScreen/index.js
- Create
src/components/Login/index.js
- bash (from the root of the project):
mkdir -p src/components/Login && cd $_ && touch index.js && cd -
- Create
src/components/Loading/index.js
- bash (from the root of the project):
mkdir -p src/components/Loading && cd $_ && touch index.js && cd -
-
Copy contents of pre-defined Login Component
-
Copy contents of pre-defined Loading Component
Reference: src/components/StartScreen/index.js
-
Import Login component in StartScreen and replace hello from react div
-
Establish two functions:
_handleFieldChange
and_handleLogin
-
Establish
componentDidMount
andcomponentDidUpdate
functions and add this line to each:
componentHandler.upgradeDom();
- Add a constructor for
src/components/StartScreen/index.js
which creates a state for StartScreen and also properly bind the_handleFieldChange
and_handleLogin
functions. React Autobinding
constructor(props) {
// call the constructor of a parent class
super(props);
this.state = {
status: 'initial',
email: '',
password: ''
};
// create bound function to set the context of this - in JavaScript classes, functions are not automatically bound to the class
this._handleFieldChange = this._handleFieldChange.bind(this);
this._handleLogin = this._handleLogin.bind(this);
}
- Pass required attributes to
<Login />
<Login email={this.state.email}
password={this.state.password}
handleFieldChange={this._handleFieldChange}
handleLogin={this._handleLogin}
loading={this.state.status === 'logging_in'} />
- Add
_showSnackBar
function
_showSnackBar(message) {
var data = {
message: message,
timeout: 2500
};
var snackbarContainer = document.querySelector('#login-snack-bar');
snackbarContainer.MaterialSnackbar.showSnackbar(data);
}
-
Add email/password check in
_handleLogin
. InvokeUserService.login
if it passes validation. -
Set app state to display loading during login process
-
Add stringify'd
USER_PROFILE
to localStorage on success, or invoke_showSnackBar
on login error (incorrect email or pw) -
Log parsed
USER_PROFILE
to console to demonstrate API response payload
-
While still in
src/components/StartScreen/index.js
, add this line of code to the top:import {hashHistory} from 'react-router';
-
On a successful login in the
_handleLogin
function, addhashHistory.push('/dashboard');
-
TEST: Navigate back to Login and Forward to Dashboard -
delete localStorage['USER_PROFILE']
- can no longer nav forward
- Create
src/assets/styles/main.scss
- bash (from the root of the project):
mkdir -p src/assets/styles && cd $_ && touch main.scss && cd -
-
Uncomment Stylesheets require in
src/dependencies.js
-
Copy contents of pre-defined main.scss
-
Create
src/assets/style/dashboard.scss
-
Copy contents of pre-defined dashboard.scss
-
@Import
./dashboard.scss
insrc/assets/styles/main.scss
-
Copy contents of pre-defined
Dashboard/index.js
-
Under React tab - find StartScreen component and demonstrate setting state loading = true
-
Build SPA bundle with Webpack -
webpack --config webpack.config.js
-
Open the Firebase Console
-
Create a new Firebase project
-
Click on
Hosting
in the left sidebar -
Install firebase-tools -
npm install -g firebase-tools
-
firebase login
- a browser will open to authenticate with Google -
firebase init
- select Hosting, hit spacebar next to Database to de-select
build
for your public directoryY
for SPA- Select your newly created project on Firebase
-
firebase deploy
-
Open the deployed app and login