Steps to create a npm project to develop an Reactjs app without create-react-app

Stanley Liang
7 min readApr 16, 2020
Photo by Joshua Aragon on Unsplash

It’s been 4 years from first time I use reactjs to be my major library on web SPA (single page application) developing. Recently due to covid-19, the business of the company I server is not so good. Good aspect is that now I have much time to record down my developing experience for the past 4 years.

First of all, why I would like to create a project without the help of create-react-app. Web app runs on all kinds of devices through browsers via internet. That means efficiency is very critical not only on certain low end devices but also in low bandwidth environment. By going through the process of configuration a npm project to develop an reactjs app, I can comprehensively understand what packages are necessary in my bundles and optimize my bundles. You will benefit from this process once metric by pagespeed-insight or business improvement by SEO are included in your tasks.

I split this process into the following sections by popular technical in reactjs eco-system:

  • create a npm project
  • webpack to modular bundles
  • reactjs here we go
  • styling with css / scss
  • adopt redux as the state management mechanism

You can find the sample code in my github or follow this article step by step.

https://github.com/StanleyLiang/reactjs/tree/master/appbase

Note: Later in all sections, I assume you already setup a nodejs environment. So I will not explain much about how to use npm manage your packages.

create a npm project

Let’s kick out a new npm project. It’s pretty easy to use create a npm project:

mkdir reactapp
cd reactapp
npm init

npm init runs into a text wizard that asking questions to help you create a project in short:

package name: (reactjs)
version: (1.0.0)
description: my react js app
entry point: (index.js)
test command:
git repository: (https://github.com/StanleyLiang/reactjs.git)
keywords: react redux css scss
author: Your name
license: (ISC)

If you have no idea what you should enter, easily press enter to complete all steps, it’s harmless and you can make modification later by editing package.json. Now check the dictionary reactapp and you can find package.json is generated via the information given by the wizard. Easy right?

webpack to modular bundles

What is webpack? What is bundles? Before we start this section, let’s talk about what happen as a website is accessed by browsers. As url is entered, browsers visit the server by the url. Browsers will download all assets including css files and javascript files required to execute the html responsed by the server. Part of these css and javascript files are generated by the web developers. Basically you can generate and manage all these assets in old school way. The capability of webpack is a automatic mechanism to optimize file size , split the chunk, generate all these assets. All you gonna do is setup the config how you would like these assets to be generated. The resulting file of webpack I called bundles.

We’ll spend much time in this section to setup webpack. Webpack is a powerful but complicated in configuration tool. The goals I would like webpack to achieve are as the following:

  1. process js, jsx files and transform them from modern es6, es7 syntax to es5 syntax.
  2. process css, scss files

Here we go. I adopt the latest version 4.42.1 when I’m documenting. To install webpack, runs the following:

npm install --save-dev webpack webpack-cli

Several webpack loaders are required in order to achieve goal 1, 2 listed above.

For the goal 1, a new stuff again is revealed here: babel. I will explain more about babel in another article. The version of babel ref here is babel 7. To make it faster, run the following command to install packages that we can process js, jsx files in webpack by babel:

npm install --save-dev @babel/cli @babel/core @babel/preset-env @babel/preset-react babel-loader

Then create the configuration file of babel named .babelrc in your project dictionary with the following content:

{    "presets": [        "@babel/preset-env",        "@babel/preset-react"    ]}

Then, in order to use webpack build the bundles of my reactjs app, I’m going to setup the configuration of webpack. Create a file named webpack.config.js in your project dictionary. The content is as the following:

const path = require('path');const babelSettings = {    cacheDirectory: true};module.exports = {    mode: 'development',    devtool: 'cheap-module-eval-source-map',    entry: {        landing: './src/landing.jsx'    },    output: {        path: path.join(__dirname, '/static/build/'),        filename: '[name].js',        libraryTarget: 'umd'    },    module: {        rules: [            {                test: /\.j(s|sx)/,                use: `babel-loader?${JSON.stringify(babelSettings)}`            }        ]    },    resolve: {        extensions: ['*', '.js', '.jsx']    },    plugins: []};

So far the structure of your project dictionary is like the following:

reactapp
|- .babelrc
|- package.json
|- webpack.config.js

Edit package.json to run webpack by npm script command:

"scripts": {    "build": "webpack --config webpack.config.js"}

By adding this script command, we can run webpack by npm run build later. Next section I will start create source codes for the reactjs based app.

reactjs here we go

(Applause Applause) Let’s create html / js source codes. Reactjs realted packages are required as well:

npm install --save react react-dom prop-types

Create dictionaries and files in the project and the structure is as the following:

reactapp
|- src
|- containers
|- App
|- index.jsx
|- landing.jsx
|- index.html
|- .babelrc
|- package.json
|- webpack.config.js

The followings shows the content of those creations.

index.html:

<!doctype html>
<html>
<head>
<title>myapp</title>
</head>
<body>
<div id="content">
<script type="text/javascript" src="./static/build/landing.js"></script>
</body>
</html>

src/landing.jsx:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './containers/App';
function root() {
return (
<App />
);
}
ReactDOM.render(
root(),
document.getElementById('content'),
() => {}
);

src/containers/App/index.jsx

import React from 'react';const propTypes = {}const App = () => {
return (
<div>
<h1>Hello React</h1>
</div>
);
}
App.propTypes = propTypes;export default App;

Here we build our codes by run the build cmd we already define in package.json:

npm run build

Now open index.html with browsers:

Hello React

styling with css / scss

I used to style the app by css / scss. Despite reactjs support inline style in components, css / scss is still a good mechanism for styling the app. To use css / scss with reactjs, webpack plays an critical role. As well as babel-loader is required to handle babeling by webpack, there comes several loaders in handling css / scss: style-loader, css-loader, and sass-loader. Run the following command to install the loaders:

npm install --save-dev css-loader style-loader sass-loader node-sass

Then, apply these loaders to work in webpack.config.js:

module: {    rules: [        ...
{
test: /\.(sa|sc|c)ss$/, use: [ 'style-loader', 'css-loader', 'sass-loader' ], } ]},resolve: { extensions: ['*', '.js', '.jsx', '.css', '.scss']},

Then, add style file to App component. create style.scss under App folder and assign the className property in App component:

src/containers/App/style.scss:

.app {    color: #fca311;    text-align: center;}

src/containers/App/index.jsx:

import React from 'react';
import './style.scss';
const propTypes = {}const App = () => {
return (
<div className='app'>
<h1>Hello React</h1>
</div>
);
}
App.propTypes = propTypes;export default App;

Run npm build and refresh browser to reload index.html. Now you can see the color of text is orange.

adopt redux as the state management mechanism

Redux is a popular state container, especially working perfect with reactjs. I will create another article to demostrate why it’s so good you should not miss it. Following in this section let’s step by step to integrate redux with reactjs.

To have redux working in the app, the following packages are required:

npm install --save redux react-redux

The step we will go through are as the following:

  1. create reducers
  2. create stores
  3. connect the app with the stores

Reducers and stores are part of redux conpcepts. The basic concept of redux is a data stream in single direction. We get to make changes in the project dictionary to construct the reducers and stores. The result is as the following:

reactapp
|- src
|- redux
|- actions
|- todoActions.js
|- constants
|- todoTypes.js
|- reducers
|- todo.js
|- index.js

|- containers
|- App
|- index.jsx
|- landing.jsx
|- index.html
|- .babelrc
|- package.json
|- webpack.config.js

So far skip the content of todoActions.js and todoTypes.js. Here I just want to show you guys how to access the state of redux stores.

src/redux/reducers/todo.js

const initialState = {    tasks: [        'house clean',        'loundry service',        'work out'    ]};const todo = (state = initialState, action) => {return state;};export default todo;

src/redux/reducers/index.js

import { combineReducers } from 'redux';import todo from './todo';const reducers = combineReducers({    todo});export default reducers;

src/landing.jsx

...import { Provider } from 'react-redux';import { createStore } from 'redux';...import reducers from './redux/reducers';
const store = createStore(reducers);
function root() { return ( <Provider store={store}> <App /> </Provider> );}...

so, how can I access the stores in component App? Pretty simple, react-redux provide a connect function to connect react component with the store. To connect App with the store, have changes as the following:

src/containers/App/index.jsx

import React from 'react';import { connect } from 'react-redux';import './style.scss';const propTypes = {}const App = (props) => {    const { tasks } = props;    return (        <div className="app">            <h1>Hello React</h1>            <ul>                {                    tasks.map((t, index) => {                        return <li key={index}>{t}</li>;                    })                 }             </ul>        </div>    );};App.propTypes = propTypes;
function mapStateToProps(state) { return { tasks: state.todo.tasks };}export default connect(mapStateToProps)(App);

Run the build command and refresh index.html in browsers. The content of the tasks property are shown now. This is just a simple demo of react + redux, so I don’t include much tasks here. The power of redux is not released totaly in the sample. Talk more about it in the future.

Photo by Jeremy Bishop on Unsplash

By the end you should build a project to develop reactjs app. Hope this article helps.

ref

--

--

Stanley Liang

Located in Tawian, loving web development to help any kind of business. Surfing, Beer, Coffee, who could reject them!!??