Build a react application with create-react-app

This article mainly explains the practical process of SPA construction. After having a preliminary understanding of react, redux, and react-router, we will use these technologies to build a simple single-page application. The app includes a side navigation bar and a main content area. Below is a brief list of some of the frameworks and tools that will be used.

  • create-react-app: Scaffolding
  • react: responsible for page component construction
  • react-router: responsible for the control of the routing part of the single page application
  • redux: responsible for managing the data flow of the entire application
  • react-redux: Combining the two parts of react and redux
  • redux-thunk: A middleware for redux. You can make the action creator return one function(not just object), and make the dispatch method accept one functionas a parameter, making the action support asynchronous (or deferred) operations through this transformation
  • redux-actions: An FSA toolkit for redux that simplifies and standardizes actions and reducers accordingly

create-react-app is a global command-line tool for creating a new project

react-scripts is a development dependency required by a generated project

  
      Generally, when we start to create a react web application, we need to install all the dependencies of the project through npm or yarn, and then write webpack.config.js, a series of complex configurations, and write the src source code after setting up the development environment.
Now if you are setting up the react runtime environment, use create-react-app to automatically build your app. There is no configuration file in the folder where your project is located. react-scripts are the only additional build dependencies in your package.json that your runtime will have every single one you need to build a modern React app. The dependencies you need and the configuration code written in the configuration file are all written by react-scripts for you. For example: react-scripts automatically downloads the required webpack-dev-server dependencies for you, and then react-scripts writes one by itself The script code start.js of the nodejs server instantiates WebpackDevServer, and starts an Http server using express. Now you only need to concentrate on writing the src source code. It saves a lot of energy and is most suitable for getting started with a demo quickly.

react-scripts has the following support, all configured for you:
React, JSX, ES6, and Flow syntax support.
Language extras beyond ES6 like the object spread operator.
Import CSS and image files directly from JavaScript.
Autoprefixed CSS, so you don 't need -webkit or other prefixes.
A build script to bundle JS, CSS, and images for production, with sourcemaps.
A dev server that lints for common errors.

Scaffolding with create-react-app

create-react-app is the official scaffolding produced by Facebook. With it, you only need one line of instructions to skip the cumbersome configuration of webpack, the numerous introductions of npm, etc., and quickly build a react project.

Install

npm install -g create-react-app  

Create an application 

create-react-app my-app  
cd my-app  

Generated directory structure

my-app/  
  README.md  
  node_modules/  
  package.json  
  .gitignore  
  public/  
    favicon.ico  
    index.html  
  src/  
    App.css  
    App.js  
    App.test.js  
    index.css  
    index.js  
    logo.svg  

run the application

npm run start   

open in browser

http://localhost:3000  

Now let's look at the source code of public/index.html and src/index.js in the my-app folder, we can write the project code here, but note that public/index.html is the home page to start the http server, src/index. js is the compiled entry file, it can only be called the name index, and it is not possible to change the name.
Open http://localhost:3000/index.html home page, f12 to view the source code of the webpage, you will see 

<script type="text/javascript" src="/static/js/bundle.js"></script>  

/static/js/bundle.js
In your project my-app, you cannot see this file path, and you have not written the configuration file webpack.config.js,
http server configuration, automatically open the browser window, react, es6 syntax compilation, babel-core, webpack, etc. you have not downloaded and configured.
React-scripts does all these tasks for you.

Looking back  at
npm run start
, we started the service running the project like this at the beginning.
Open your my-app\package.json

"scripts": {  
    "start": "react-scripts start",  
      ...  
  }  

So what is executed is react-scripts start 
to open the react-scripts.js file in the bin folder of your my-app\node_modules\react-scripts folder

#!/usr/bin/env node  
var spawn = require('cross-spawn');  
var script = process.argv[2];  
var args = process.argv.slice(3);  
  
switch (script) {  
case 'build':  
case 'eject':  
case 'start':  
case 'test':  
  var result = spawn.sync(  
    'node',  
    [require.resolve('../scripts/' + script)].concat(args),  
  .......  

The variable value of script in the above code is start,
so execute the start.js file in the my-app\node_modules\react-scripts\scripts folder. The code excerpts are as follows

var webpack = require('webpack');  
var WebpackDevServer = require('webpack-dev-server');  // 启动http服务器  
var paths = require('../config/paths');  //要编译的文件路径与生成路径等  
var config = require('../config/webpack.config.dev');  
var DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; //这就是为什么 端口号 不是8080 而是 3000 的原因,在这里可以改成8080,重新npm run start 生效   
detect(DEFAULT_PORT).then(port => {  
  if (port === DEFAULT_PORT) {  
    run(port); //这里开始运行  
    return;  
  }  
......  
  
function run(port) {   
// 这里可以设置 http协议, 或者可以在 npm run start 之前 cmd命令窗口中执行 set HTTPS=true&&npm start 改成https 安全协议  
  var protocol = process.env.HTTPS === 'true' ? "https" : "http";   
  var host = process.env.HOST || 'localhost';     
  setupCompiler(host, port, protocol);  // 编译源码 ,生成路径  
  runDevServer(host, port, protocol);  //启动 http服务器  
}  
  
  
//配置http服务器  
function runDevServer(host, port, protocol) {  
  var devServer = new WebpackDevServer(compiler, {  
   compress: true,     
    clientLogLevel: 'none',  
    contentBase: paths.appPublic,   //根据导入的paths 指定应用根目录(即index.html所在目录)  
    hot: true,  
  
    publicPath: config.output.publicPath, //根据导入的 config 变量,指定 虚拟目录,自动指向path编译目录(/assets/ => /build/js/)。html中引用js文件时,  
                                             //必须引用此虚拟路径(但实际上引用的是内存中的文件,既不是/build/js/也不是/assets/)。  
   
    quiet: true,  
  
  
    watchOptions: {  
      ignored: /node_modules/  
    },  
    // Enable HTTPS if the HTTPS environment variable is set to 'true'  
    https: protocol === "https",  
    host: host  
  });  
  /**  
   * 省略其他代码  
   */  
    openBrowser(protocol + '://' + host + ':' + port + '/');    // 打开浏览器 向服务器发送请求  
  });  
}  
  
  
function setupCompiler(host, port, protocol) {  
  
  compiler = webpack(config, handleCompile);  //  根据导入的 config 变量  指向的 webpack.config.dev 配置文件  运行  
     /**  
   * 省略其他代码  
   */  
} 

 The start.js file code imports webpack.config.dev.js and paths.js paths.js in the my-app\node_modules\react-scripts\config folder. The
code excerpts are as follows:

var appDirectory = fs.realpathSync(process.cwd());   // 获取npm run start 运行所在的路径  
function resolveApp(relativePath) {  
  return path.resolve(appDirectory, relativePath);  
}  
  
module.exports = {  
  appPath: resolveApp('.'),  
  ownPath: resolveApp('node_modules/react-scripts'),  
  appBuild: resolveApp('build'),  
  appPublic: resolveApp('public'),  
  appHtml: resolveApp('public/index.html'),   //  这就是  一开始  我们的项目 要使用public/index.html作为 默认首页   
                //  这里写什么文件名,项目中就要使用什么文件名  包括 也要有public文件夹  
  appIndexJs: resolveApp('src/index.js'),   //编译的入口文件的文件名  项目中要包括src文件夹  
  appPackageJson: resolveApp('package.json'),  
  appSrc: resolveApp('src'),  
  yarnLockFile: resolveApp('yarn.lock'),  
  testsSetup: resolveApp('src/setupTests.js'),  
  appNodeModules: resolveApp('node_modules'),  
  // this is empty with npm3 but node resolution searches higher anyway:  
  ownNodeModules: resolveOwn('node_modules'),  
  nodePaths: nodePaths,  
  publicUrl: getPublicUrl(resolveApp('package.json')),  
  servedPath: getServedPath(resolveApp('package.json'))  
};  
 /**  
   * 省略其他代码  
   */

The webpack.config.dev.js code excerpt is as follows:

var paths = require('./paths');  //也导入了 同文件夹下的 paths.js  
module.exports = {  entry: [    require.resolve('react-dev-utils/webpackHotDevClient'),    require.resolve('./polyfills'),    paths.appIndexJs     // 编译的入口文件  ],  output: {    path: paths.appBuild,    pathinfo: true,       filename: 'static/js/bundle.js', // 只是编译后生成的目标文件 ,这就是一开始我们 打开浏览器按f12看到的index.html导入的           //  <script type="text/javascript" src="/static/js/bundle.js"></script>    publicPath: publicPath  },  
 /**  
   * 省略其他代码  
   */  
  
}  

The running environment has been set up, how to develop the app next

Importing components

This project supports es6 modules due to babel dependencies.
While you still use require() and module.exports, we encourage you to use import and export instead.
For example: 
Button.js

import React, { Component } from 'react';  
  
class Button extends Component {  
  render() {  
    // ...  
  }  
}  
export default Button; // 不要忘记去使用 export default!

DangerButton.js

import React, { Component } from 'react';  
import Button from './Button'; //从另一个文件导入一个组件  
  
  
class DangerButton extends Component {  
  render() {  
    return <Button color="red" />;  
  }  
}  
export default DangerButton;  

Add style
Button.css

.Button {  
  padding: 20px;  
}  

Button.js

import React, { Component } from 'react';  
import './Button.css'; // 告诉webpack Button.js 使用这些样式  
  
  
class Button extends Component {  
  render() {  
    // You can use them as regular CSS styles  
    return <div className="Button" />;  
  }  
}  

Autoprefix

react-scripts automatically adds browser-compatible prefixes to your css files through Autoprefixer
For example:

.App {  
  display: flex;  
  flex-direction: row;  
  align-items: center;  
}  

become

.App {  
  display: -webkit-box;  
  display: -ms-flexbox;  
  display: flex;  
  -webkit-box-orient: horizontal;  
  -webkit-box-direction: normal;  
      -ms-flex-direction: row;  
          flex-direction: row;  
  -webkit-box-align: center;  
      -ms-flex-align: center;  
          align-items: center;  
}  

Add CSS preprocessor

First install node-sass in the my-app/ directory to compile scss into css

npm install node-sass --save-dev  

Open my-app/package.json and add the following code to scripts

   "scripts": {  
+    "build-css": "node-sass src/ -o src/",  
+    "watch-css": "npm run build-css && node-sass src/ -o src/ --watch",  
     "start": "react-scripts start",  
     "build": "react-scripts build",  
     ......  
    }  

Now you can rename my-app/ src/App.css to my-app/ src/App.scss and run    npm run watch-css
or you can change to

"scripts": {  
    "build-css": "node-sass src/ -o src/",  
    "start": "npm run build-css && react-scripts start",  //先执行 build-css 再执行 react-scripts start  
    "build": "react-scripts build",  
    "test": "react-scripts test --env=jsdom",  
    "eject": "react-scripts eject"  
  }  

Direct npm run start

add pictures

import React from 'react';  
import logo from './logo.png'; // 告诉webpack 这个js文件使用这张图片  
  
console.log(logo); // /logo.84287d09.png  会改变图片的名字  
  
function Header() {  
  //导入结果是这个图片的url地址  
  return <img src={logo} alt="Logo" />;  
}  
  
export default Header;  

When the project is built, Webpack will correctly move the image to the build folder, providing us with the correct path

The same way in css work

.Logo {  
  background-image: url(./logo.png);  
}  

webpack finds all relative modules starting with ./

Add bootstrap
in react+es6 moudle+bootstrap
You don't have to use React Bootstrap with React, but it is a popular library to integrate bootstrap and react applications, if you need it, you can integrate it through Create React App, through the following few steps

First install React Bootstrap and Bootstrap from npm, React Bootstrap doesn't include Bootstrap CSS, so you need to install it
under my-app/ directory

npm install react-bootstrap --save  
npm install bootstrap@3 --save 

Modify my-app/src/index.js

At the top of your src/index.js file content, import the Bootstrap CSS and optional Bootstrap theme CSS

import React from 'react';  
import ReactDOM from 'react-dom';  
import 'bootstrap/dist/css/bootstrap.css';  // 必须的  
import 'bootstrap/dist/css/bootstrap-theme.css';  //  可选的  
import App from './App';  
import './index.css';  
  
ReactDOM.render(  
  <App />,  
  document.getElementById('root')  
);  

Modify my-app/src/App.js

import React, { Component } from 'react';  
import { Grid, Navbar, Jumbotron, Button } from 'react-bootstrap';  
  
class App extends Component {  
  render() {  
    return (  
      <div>  
        <Navbar inverse fixedTop>  
          <Grid>  
            <Navbar.Header>  
              <Navbar.Brand>  
                <a href="/">React App</a>  
              </Navbar.Brand>  
              <Navbar.Toggle />  
            </Navbar.Header>  
          </Grid>  
        </Navbar>  
        <Jumbotron>  
          <Grid>  
            <h1>Welcome to React</h1>  
            <p>  
              <Button  
                bsStyle="success"  
                bsSize="large"  
                href="http://react-bootstrap.github.io/components.html"  
                target="_blank">  
                View React Bootstrap Docs  
              </Button>  
            </p>  
          </Grid>  
        </Jumbotron>  
      </div>  
    );  
  }  
}  
  
export default App;  

last run

npm run start  

Reference link  https://github.com/facebookincubator/create-react-app

Reference: https://blog.csdn.net/github_squad/article/details/57452333

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325369463&siteId=291194637