如何用react脚手架在七天之内快速接手新项目?

2026-05-23 16:152阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2842个文字,预计阅读时间需要12分钟。

如何用react脚手架在七天之内快速接手新项目?

其他章节请看:+七天接手react项目+系列+react+脚手架创建项目+前端我直接通过script的方式学习react+基础知识,而实际项目通常是基于脚手架进行开发。+本章首先通过react+脚手架+创建+了解react基础知识。

其他章节请看:

七天接手react项目 系列

react 脚手架创建项目

前面我们一直通过 script 的方式学习 react 基础知识,而真实项目通常是基于脚手架进行开发。

本篇首先通过 react 脚手架创建项目,分析其目录结构,接着编写第一个组件、解决样式覆盖,最后配置代理 proxy 以及通过消息发布与订阅解决兄弟组件之间的通信问题。

Tip:我们要接手的 react 项目是:spug_web。

使用 react 脚手架创建项目 react-cli-demo

前面我们学习 vue 脚手架 vue-cli 创建一个项目是这样:

> vue create vue-hello-world

在 react 中创建项目是这样:

$ npx create-react-app react-cli-demo Creating a new React app in exercise\react-cli-demo. Installing packages. This might take a couple of minutes. Installing react, react-dom, and react-scripts with cra-template... added 1368 packages in 2m 169 packages are looking for funding run `npm fund` for details Initialized a git repository. Installing template dependencies using npm... npm WARN deprecated source-map-resolve@0.6.0: See github.com/lydell/source-map-resolve#deprecated added 38 packages in 9s 169 packages are looking for funding run `npm fund` for details Removing template package using npm... removed 1 package, and audited 1406 packages in 4s 169 packages are looking for funding run `npm fund` for details 6 moderate severity vulnerabilities To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. Created git commit. Success! Created react-cli-demo at exercise\react-cli-demo Inside that directory, you can run several commands: npm start Starts the development server. npm run build Bundles the app into static files for production. npm test Starts the test runner. npm run eject Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can't go back! We suggest that you begin by typing: cd react-cli-demo npm start Happy hacking!

Create React App 是一个用于学习 React 的舒适环境,也是用 React 创建新的单页应用最佳方式 —— 官网-Create React App

$ cd react-cli-demo/

本地启动项目:

$ npm start > react-cli-demo@0.1.0 start > react-scripts start (node:3880) [DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option. (Use `node --trace-deprecation ...` to show where the warning was created) (node:3880) [DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option. Starting the development server... Compiled successfully! You can now view react-cli-demo in the browser. Local: localhost:3000 On Your Network: 192.168.85.1:3000 Note that the development build is not optimized. To create a production build, use npm run build. assets by path static/ 1.49 MiB asset static/js/bundle.js 1.48 MiB [emitted] (name: main) 1 related asset asset static/js/node_modules_web-vitals_dist_web-vitals_js.chunk.js 6.93 KiB [emitted] 1 related asset asset static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg 2.57 KiB [emitted] (auxiliary name: main) asset index.html 1.67 KiB [emitted] asset asset-manifest.json 546 bytes [emitted] cached modules 1.37 MiB (javascript) 31.3 KiB (runtime) [cached] 122 modules webpack 5.69.1 compiled successfully in 1867 ms

自动打开网页:

react-cli-demo 目录结构分析

exercise\react-cli-demo> dir Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2022/3/3 17:50 node_modules d----- 2022/3/3 17:48 public d----- 2022/3/18 19:22 src -a---- 1985/10/26 16:15 310 .gitignore -a---- 2022/3/3 17:49 1120931 package-lock.json -a---- 2022/3/3 17:49 817 package.json -a---- 1985/10/26 16:15 3359 README.md

一级目录结构很简单,我们主要分析一下 publicsrc 目录

public 目录

public> dir Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 1985/10/26 16:15 3870 favicon.ico -a---- 2022/3/4 16:06 1966 index.html -a---- 1985/10/26 16:15 5347 logo192.png -a---- 1985/10/26 16:15 9664 logo512.png -a---- 1985/10/26 16:15 492 manifest.json -a---- 1985/10/26 16:15 67 robots.txt

从中我们猜测主要文件应该是 index.html。内容如下:

// 注释已全部删除 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>React App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>

index.html核心就是 <div id="root"></div>,即挂载的根元素

Tiprobots.txt 即robots协议,只是约定俗成的,所以并不能保证网站的隐私

src 目录

src> dir Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2022/3/4 16:56 components -a---- 1985/10/26 16:15 564 App.css -a---- 2022/3/18 19:22 553 App.js -a---- 1985/10/26 16:15 246 App.test.js -a---- 1985/10/26 16:15 366 index.css -a---- 1985/10/26 16:15 500 index.js -a---- 1985/10/26 16:15 2632 logo.svg -a---- 1985/10/26 16:15 362 reportWebVitals.js -a---- 1985/10/26 16:15 241 setupTests.js index.js 和 App.js

哪个是入口文件?App.js 还是 index.js?我们先看一下这两个文件的内容:

// index.js 已删除注释 import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); reportWebVitals();

// App.js import logo from './logo.svg'; import './App.css'; function App() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> ); } export default App;

index.js 引用了 App.js

我们在回忆一下 vue-cli 生成的项目,也有 App.js 文件,不过是被 main.js 引用。内容如下:

// main.js import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app')

// App.js <template> <div id="app"> <div id="nav"> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> <router-view/> </div> </template>

对比发现,都是将 App 组件挂载到 dom 上 —— react 是 #root,vue 是 #app

至此,我们知道 index.js入口文件,而 App 应该是根组件。

App.css

上面我们启动 react-cli-demo 项目,网页中有这么一句话:

Edit src/App.js and save to reload. 编辑 src/App.js 并保存以重新加载。

App.js 中有 import './App.css';,笔者尝试修改一下 App.css

.App-header { - background-color: #282c34; + background-color: orange; ... }

保存后,发现页面背景自动变成橙色

于是我们知道 App.css 应该是 App 组件的样式。而 vue 中样式、html和 js 都在一个 .vue 文件中。

第一个组件 HelloWorld

组件创建有两种方式:函数组件以及类组件。

这里的 App.js 使用的是函数组件,我们也用函数的方式创建组件,然后让 App 加载。请看示例:

如何用react脚手架在七天之内快速接手新项目?

// App.js // webpack 中就可以省略 .js import HelloWorld from './HelloWorld.js'; export default function App() { return ( <div className="App"> < HelloWorld /> </div > ); }

// HelloWorld.js export default function HelloWorld() { return <div>hello world!</div> }

页面显示 hello world!

对应类组件的实现:

import { Component } from 'react' export default class HelloWorld extends Component { render() { return <div>hello world!</div> } } 后缀js/jsx

我们写的组件 HelloWorld 其实是 jsx 语法,所以可以将 HelloWorld.js 改为 HelloWorld.jsx,引入的后缀名也同步一下即可。

import HelloWorld from './HelloWorld.jsx';

Tip:纯逻辑的 js 可以用 .js 或小写(例如 127.0.0.1:8000', changeOrigin: true, ws: true, headers: {'X-Real-IP': '1.1.1.1'}, pathRewrite: { '^/api': '' } })) };

Tip:www.cnblogs.com/', // changeOrigin: true }, } } }

接下来我们就依葫芦画瓢:

新建 setupProxy.js

// src/setupProxy.js const { createProxyMiddleware } = require('www.cnblogs.com/', changeOrigin: true } ) ) }

// src/components/HelloWorld/index.jsx const axios = require('axios'); export default function HelloWorld() { axios.get('/pengjiali/p/14561119.html') .then(function (response) { // handle success console.log(response.data); }).catch(function (error) { // handle error console.log(error); }) return <div>hello world2!</div> }

重启服务,控制台输出博文内容。

http-proxy-middleware 有两点和 spug_web 不同:

  • 笔者这版的react脚手架默认已有 http-proxy-middleware,所以我们无需在下载。
    • vscode 中将鼠标移至 http-proxy-middleware 就会显示该文件路径。
  • 用法上从 proxy 改为 createProxyMiddleware
    • 我们的版本是 2.0.4,也是此刻官网最新版,其用法使用的就是 createProxyMiddleware

// 本地版本 react-cli-demo/node_modules/http-proxy-middleware (master) $ cat package.json |head -n 5 { "name": "http-proxy-middleware", "version": "2.0.4", "description": "The one-liner node.js proxy middleware for connect, express and browser-sync", "main": "dist/index.js", 消息订阅与发布

在 vue 中我们可以使用中央事件总线(或称 bus)来解决兄弟组件之间的通信。bus 相当于一个中介,组件可以在其上订阅消息,当触发时就会将消息通知到订阅者。其原理其实就是消息订阅与发布。

react 可以通过 pubsub-js 包来实现组件之间通信。

Tip:PubSubJS 是一个用 JavaScript 编写的基于主题的发布/订阅库 —— pubsub-js

下面我们定义两个组件,组件1订阅消息,组件2发布消息。请看实现:

首先按照依赖包:

react-cli-demo> npm i pubsub-js added 1 package, and audited 1408 packages in 5s 169 packages are looking for funding run `npm fund` for details 6 moderate severity vulnerabilities To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details.

接着定义两个组件:

// 组件1订阅消息 // src/components/HelloWorld/index.jsx import PubSub from 'pubsub-js' export default function HelloWorld() { // 订阅 message1 PubSub.subscribe('msg1', function (msg, data) { console.log(msg, data); }); return <div>hello world!</div> }

// 组件2发布消息 // src/components/HelloWorld2/index.jsx import PubSub from 'pubsub-js' export default function HelloWorld() { PubSub.publish('msg1', '旅游去'); return <div>hello world2!</div> }

页面控制台显示:msg1 旅游去

其他章节请看:

七天接手react项目 系列

本文共计2842个文字,预计阅读时间需要12分钟。

如何用react脚手架在七天之内快速接手新项目?

其他章节请看:+七天接手react项目+系列+react+脚手架创建项目+前端我直接通过script的方式学习react+基础知识,而实际项目通常是基于脚手架进行开发。+本章首先通过react+脚手架+创建+了解react基础知识。

其他章节请看:

七天接手react项目 系列

react 脚手架创建项目

前面我们一直通过 script 的方式学习 react 基础知识,而真实项目通常是基于脚手架进行开发。

本篇首先通过 react 脚手架创建项目,分析其目录结构,接着编写第一个组件、解决样式覆盖,最后配置代理 proxy 以及通过消息发布与订阅解决兄弟组件之间的通信问题。

Tip:我们要接手的 react 项目是:spug_web。

使用 react 脚手架创建项目 react-cli-demo

前面我们学习 vue 脚手架 vue-cli 创建一个项目是这样:

> vue create vue-hello-world

在 react 中创建项目是这样:

$ npx create-react-app react-cli-demo Creating a new React app in exercise\react-cli-demo. Installing packages. This might take a couple of minutes. Installing react, react-dom, and react-scripts with cra-template... added 1368 packages in 2m 169 packages are looking for funding run `npm fund` for details Initialized a git repository. Installing template dependencies using npm... npm WARN deprecated source-map-resolve@0.6.0: See github.com/lydell/source-map-resolve#deprecated added 38 packages in 9s 169 packages are looking for funding run `npm fund` for details Removing template package using npm... removed 1 package, and audited 1406 packages in 4s 169 packages are looking for funding run `npm fund` for details 6 moderate severity vulnerabilities To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. Created git commit. Success! Created react-cli-demo at exercise\react-cli-demo Inside that directory, you can run several commands: npm start Starts the development server. npm run build Bundles the app into static files for production. npm test Starts the test runner. npm run eject Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can't go back! We suggest that you begin by typing: cd react-cli-demo npm start Happy hacking!

Create React App 是一个用于学习 React 的舒适环境,也是用 React 创建新的单页应用最佳方式 —— 官网-Create React App

$ cd react-cli-demo/

本地启动项目:

$ npm start > react-cli-demo@0.1.0 start > react-scripts start (node:3880) [DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option. (Use `node --trace-deprecation ...` to show where the warning was created) (node:3880) [DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option. Starting the development server... Compiled successfully! You can now view react-cli-demo in the browser. Local: localhost:3000 On Your Network: 192.168.85.1:3000 Note that the development build is not optimized. To create a production build, use npm run build. assets by path static/ 1.49 MiB asset static/js/bundle.js 1.48 MiB [emitted] (name: main) 1 related asset asset static/js/node_modules_web-vitals_dist_web-vitals_js.chunk.js 6.93 KiB [emitted] 1 related asset asset static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg 2.57 KiB [emitted] (auxiliary name: main) asset index.html 1.67 KiB [emitted] asset asset-manifest.json 546 bytes [emitted] cached modules 1.37 MiB (javascript) 31.3 KiB (runtime) [cached] 122 modules webpack 5.69.1 compiled successfully in 1867 ms

自动打开网页:

react-cli-demo 目录结构分析

exercise\react-cli-demo> dir Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2022/3/3 17:50 node_modules d----- 2022/3/3 17:48 public d----- 2022/3/18 19:22 src -a---- 1985/10/26 16:15 310 .gitignore -a---- 2022/3/3 17:49 1120931 package-lock.json -a---- 2022/3/3 17:49 817 package.json -a---- 1985/10/26 16:15 3359 README.md

一级目录结构很简单,我们主要分析一下 publicsrc 目录

public 目录

public> dir Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 1985/10/26 16:15 3870 favicon.ico -a---- 2022/3/4 16:06 1966 index.html -a---- 1985/10/26 16:15 5347 logo192.png -a---- 1985/10/26 16:15 9664 logo512.png -a---- 1985/10/26 16:15 492 manifest.json -a---- 1985/10/26 16:15 67 robots.txt

从中我们猜测主要文件应该是 index.html。内容如下:

// 注释已全部删除 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>React App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>

index.html核心就是 <div id="root"></div>,即挂载的根元素

Tiprobots.txt 即robots协议,只是约定俗成的,所以并不能保证网站的隐私

src 目录

src> dir Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2022/3/4 16:56 components -a---- 1985/10/26 16:15 564 App.css -a---- 2022/3/18 19:22 553 App.js -a---- 1985/10/26 16:15 246 App.test.js -a---- 1985/10/26 16:15 366 index.css -a---- 1985/10/26 16:15 500 index.js -a---- 1985/10/26 16:15 2632 logo.svg -a---- 1985/10/26 16:15 362 reportWebVitals.js -a---- 1985/10/26 16:15 241 setupTests.js index.js 和 App.js

哪个是入口文件?App.js 还是 index.js?我们先看一下这两个文件的内容:

// index.js 已删除注释 import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); reportWebVitals();

// App.js import logo from './logo.svg'; import './App.css'; function App() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> ); } export default App;

index.js 引用了 App.js

我们在回忆一下 vue-cli 生成的项目,也有 App.js 文件,不过是被 main.js 引用。内容如下:

// main.js import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app')

// App.js <template> <div id="app"> <div id="nav"> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> <router-view/> </div> </template>

对比发现,都是将 App 组件挂载到 dom 上 —— react 是 #root,vue 是 #app

至此,我们知道 index.js入口文件,而 App 应该是根组件。

App.css

上面我们启动 react-cli-demo 项目,网页中有这么一句话:

Edit src/App.js and save to reload. 编辑 src/App.js 并保存以重新加载。

App.js 中有 import './App.css';,笔者尝试修改一下 App.css

.App-header { - background-color: #282c34; + background-color: orange; ... }

保存后,发现页面背景自动变成橙色

于是我们知道 App.css 应该是 App 组件的样式。而 vue 中样式、html和 js 都在一个 .vue 文件中。

第一个组件 HelloWorld

组件创建有两种方式:函数组件以及类组件。

这里的 App.js 使用的是函数组件,我们也用函数的方式创建组件,然后让 App 加载。请看示例:

如何用react脚手架在七天之内快速接手新项目?

// App.js // webpack 中就可以省略 .js import HelloWorld from './HelloWorld.js'; export default function App() { return ( <div className="App"> < HelloWorld /> </div > ); }

// HelloWorld.js export default function HelloWorld() { return <div>hello world!</div> }

页面显示 hello world!

对应类组件的实现:

import { Component } from 'react' export default class HelloWorld extends Component { render() { return <div>hello world!</div> } } 后缀js/jsx

我们写的组件 HelloWorld 其实是 jsx 语法,所以可以将 HelloWorld.js 改为 HelloWorld.jsx,引入的后缀名也同步一下即可。

import HelloWorld from './HelloWorld.jsx';

Tip:纯逻辑的 js 可以用 .js 或小写(例如 127.0.0.1:8000', changeOrigin: true, ws: true, headers: {'X-Real-IP': '1.1.1.1'}, pathRewrite: { '^/api': '' } })) };

Tip:www.cnblogs.com/', // changeOrigin: true }, } } }

接下来我们就依葫芦画瓢:

新建 setupProxy.js

// src/setupProxy.js const { createProxyMiddleware } = require('www.cnblogs.com/', changeOrigin: true } ) ) }

// src/components/HelloWorld/index.jsx const axios = require('axios'); export default function HelloWorld() { axios.get('/pengjiali/p/14561119.html') .then(function (response) { // handle success console.log(response.data); }).catch(function (error) { // handle error console.log(error); }) return <div>hello world2!</div> }

重启服务,控制台输出博文内容。

http-proxy-middleware 有两点和 spug_web 不同:

  • 笔者这版的react脚手架默认已有 http-proxy-middleware,所以我们无需在下载。
    • vscode 中将鼠标移至 http-proxy-middleware 就会显示该文件路径。
  • 用法上从 proxy 改为 createProxyMiddleware
    • 我们的版本是 2.0.4,也是此刻官网最新版,其用法使用的就是 createProxyMiddleware

// 本地版本 react-cli-demo/node_modules/http-proxy-middleware (master) $ cat package.json |head -n 5 { "name": "http-proxy-middleware", "version": "2.0.4", "description": "The one-liner node.js proxy middleware for connect, express and browser-sync", "main": "dist/index.js", 消息订阅与发布

在 vue 中我们可以使用中央事件总线(或称 bus)来解决兄弟组件之间的通信。bus 相当于一个中介,组件可以在其上订阅消息,当触发时就会将消息通知到订阅者。其原理其实就是消息订阅与发布。

react 可以通过 pubsub-js 包来实现组件之间通信。

Tip:PubSubJS 是一个用 JavaScript 编写的基于主题的发布/订阅库 —— pubsub-js

下面我们定义两个组件,组件1订阅消息,组件2发布消息。请看实现:

首先按照依赖包:

react-cli-demo> npm i pubsub-js added 1 package, and audited 1408 packages in 5s 169 packages are looking for funding run `npm fund` for details 6 moderate severity vulnerabilities To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details.

接着定义两个组件:

// 组件1订阅消息 // src/components/HelloWorld/index.jsx import PubSub from 'pubsub-js' export default function HelloWorld() { // 订阅 message1 PubSub.subscribe('msg1', function (msg, data) { console.log(msg, data); }); return <div>hello world!</div> }

// 组件2发布消息 // src/components/HelloWorld2/index.jsx import PubSub from 'pubsub-js' export default function HelloWorld() { PubSub.publish('msg1', '旅游去'); return <div>hello world2!</div> }

页面控制台显示:msg1 旅游去

其他章节请看:

七天接手react项目 系列