React18 - 脚手架

1,198 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情

编程中提到的脚手架(Scaffold),其实是一种工具,帮我们可以快速生成项目的工程化结构,并且已经将我们所需的工程环境配置好

  • 每个项目作出完成的效果不同,但是它们的基本工程化结构是相似的
  • 既然相似,就没有必要每次都从零开始搭建,完全可以使用一些工具,帮助我们生产基本的工程化模板
  • 不同的项目,在这个模板的基础之上进行项目开发或者进行一些配置的简单修改即可
  • 这样也可以间接保证项目的基本架构的一致性,方便后期的维护

简而言之,脚手架让项目从搭建到开发,再到部署,整个流程变得快速和便捷

在React中也有自己的脚手架工具, 即create-react-app,也有人简写为CRA

创建项目

# 安装 
npm install create-react-app

# 查看版本
create-react-app --version

# 创建一个项目
# 创建完成后,进入对应的目录,就可以将项目跑起来
# 早期的react脚手架是基于yarn的,不过最新的脚手架工具是基于npm的

# react脚手架在创建项目的时候,要求项目的包名必须和node的包名规则保持一致
# 1. 不能存在大写字母
# 2. 单词和单词之间使用下划线或中划线连接,推荐使用中划线连接
# 启动的项目默认运行在3000端口上,如果开启了多个项目,端口号会依次递增1
create-react-app <项目名称>
"scripts": {
  // react脚手架内部依旧使用的是webpack进行构建
  // 并将对于的配置文件封装抽离到了react-scripts中来进行使用
  "start": "react-scripts start", // 启动项目
  "build": "react-scripts build", // 打包构建、
   // 暴露(弹射)出对应的webpack配置 - 该操作是不可逆的的,暴露后无法再次隐藏
   // 不推荐,如果需要修改对应的webpack相关配置,推荐使用craco来进行对应的修改
  "eject": "react-scripts eject"
}

目录结构

.
├── README.md # 项目说明文件
├── package-lock.json # 记录项目实际依赖包的版本和依赖包之间关系的文件
├── package.json # 对整个应用程序的描述:包括应用名称、版本号、一些依赖包、以及项目的启动、打包等等
├── public # 公共资源文件
│   ├── favicon.ico # 站点图标
│   ├── index.html # 应用的index.htm1,也是html-webpack-plugin对应的模板文件
│   ├── logo192.png # PWA 应用程序图标
│   ├── logo512.png # PWA 应用程序图标
│   ├── manifest.json # PWA 应用程序配置文件
│   └── robots.txt # 指定搜素引擎可以或者无法爬取哪些文件
└── src # 源代码
    ├── App.css # APP组件 样式文件
    ├── App.js # App组件 逻辑脚本文件
    ├── App.test.js # App组件 单元测试文件
    ├── index.css # 全局样式
    ├── index.js # 应用程序入口
    ├── logo.svg # logo
    ├── reportWebVitals.js # 性能检测文件
    └── setupTests.js # 进行单元测试的一些初始化操作的逻辑文件

PWA

PWA全称Progressive Web App,即渐进式WEB应用

一个 PWA 应用首先是一个网页, 可以通过 Web 技术编写出一个网页应用

随后添加上 App Manifest(PWA的配置文件) 和 Service Worker (PWA的逻辑脚本) 来实现 PWA 的安装和离线等功能

这种Web存在的形式,我们也称之为是 Web App

如果一个网页具有PWA功能的时候,该网页可以实现如下功能:

  1. 可以添加至主屏幕,点击主屏幕图标可以实现启动动画以及隐藏地址栏
  2. 实现离线缓存功能,即使用户手机没有网络,依然可以使用一些离线功能
  3. 实现了消息推送
  4. 等等一系列类似于Native App相关的功能

编写示例

src/index.jsx

// React18之前的写法
// import ReactDOM from 'react-dom'

// React18开始的写法
import ReactDOM from 'react-dom/client'

// 因为React脚手架基于webpack进行构建的,其内部进行了默认设置
// 所以如果导入的是文件夹下的名为index.xxx的文件,可以省略
// 在导入文件的时候,如果后缀名为json,js,jsx,也可以省略
import App from './App'

ReactDOM.createRoot(document.querySelector('#root')).render(<App />)

src/App/index.jsx

在react中使用js或jsx作为单文件组件后缀名都是可以的,但是使用jsx作为单文件组件后缀名的时候,vscode可以给予更友好的提示

import React from 'react'
// 导入时候 默认可以省略后缀名 jsx
import HelloReact from './components/HelloReact'

export default class App extends React.Component {
	render() {
		// 在react中,导入组件不需要注册,直接使用即可
		return <HelloReact />
	}
}

src/App/components/HelloReact.jsx

// react对Component类进行了单独导出,所以可以单独导入后进行使用
import { Component } from 'react'

// 在导出的组件中定义类名 在这里实质上是没有任何意义的 因为该组件是默认导出,具体使用什么名字是由导入组件决定的
// 但是默认导出一个匿名组件 可读性不强,且不符合ESLint规范,所以推荐在组件默认导出的时候,定义对应的类名
// 此外这里的类名有类似于vue options api中name配置项的功能,可以在react devtools中更友好的显示和区分对应的组件,方便我们进行调试
export default class HelloReact extends Component {
	render() {
		return <h2>Hello React</h2>
	}
}

修改配置

我们在实际开发中,必然需要涉及到修改webpack配置的部分,但是默认脚手架已经将对应的wenbpack配置给隐藏起来了

直接暴露webpack配置是不被推荐的,而且直接修改脚手架的webpack配置在某种程度上也是十分危险的

所以社区提供了一个第三方库,即craco (create react app config) 来帮助我们对react脚手架的配置进行修改

实际使用的时候 craco中的配置 会和默认的配置进行合并,craco中的配置会覆盖webpack中的相关配置

# 安装
# 对于最新的CRA而言,需要安装npm i @craco/craco@alpha
npm install @craco/craco
/* package.json */

"scripts": {
-   "start": "react-scripts start",
+   "start": "craco start",
-   "build": "react-scripts build",
+   "build": "craco build"
-   "test": "react-scripts test",
+   "test": "craco test"
}

/craco.config.js --- 功能和vue.config.js是一致的

// 这里以在CRA中使用less为例
// 默认情况下CRA中是没有配置less-loader的,所以无法解析less
// 如果需要解析less,需要安装craco-less
// ps: 如果是最新的CRA 下载的也是 craco-less@alpha
const CracoLessPlugin = require("craco-less");

module.exports = {
	// craco-less导出的一个插件
  plugins: [{ plugin: CracoLessPlugin }],
}