现代的前端项目已经越来越复杂了:
-
我们可能会使用一些比较方便的方式去编写代码,但是这些代码浏览器并不能直接识别
需要使用对应的工具,将其编译为原生的HTML,CSS,JS后才可以交给浏览器来进行解析
例如: 使用less,scss来写css样式,使用TS来编写JS代码
-
JS的文件采用模块化的方式进行开发,这就意味着JavaScript代码不再只是编写在几个文件中
而是通过模块化的方式,被组成在成百上千个文件中,所以我们需要通过模块化的技术来管理它们之间的相互依赖
并且在打包的时候,将他们模块化文件打包在一起,形成一个或几个大的JS文件
-
项目所依赖的第三方库越来越多,且第三方库可能还依赖了别的第三方库,我们需要一种更好的方式去管理
这些库的版本,以及库和库之间的依赖
为了,解决上述的问题,前端出现了类似于vite,webpack,babel在内的一系列工具,但是这些工具都需要进行相应的配置
而每个项目作出完成的效果不同,但是它们的基本工程化结构是相似的,每次都从零开始编写项目目录和对应配置是完全没有意义的
所以就出现了一个CLI(command line interface )工具,通过这个工具我们可以生成我们所需要的项目模板
我们只需要在这个模板的基础之上进行项目开发或者进行一些配置的简单修改即可
这样也可以间接保证项目的基本机构一致性,方便后期的维护
而这个工具就被称之为脚手架(scaffold)工具
简而言之,脚手架是一个CLI工具。可以帮我们创建已经配置好打包工具和项目目录结构的工程化项目模板
脚手架让项目从搭建到开发,再到部署,整个流程变得快速和便捷
# 安装react脚手架
$ npm i create-react-app -g
# react脚手架使用
# 项目名称遵循node的包名
# 即 全部使用小写英文字母,多个单词之间使用中划线或下划线进行连接
$ create-react-app <项目名称>
# 创建完成后,需要进入对应的目录
$ cd <项目名称>
# 启动项目
# 默认情况下,项目会运行在3000端口
# 如果3000端口被占用,就会使用3001端口,依次类推
$ npm start
脚手架对应的目录结构
package.json中配置的script脚本
脚本 | 功能 |
---|---|
npm start | react-scripts start |
npm run build | react-scripts build |
npm run reject | react-scripts reject |
React scaffold中的配置使用react提供的工具
react-scripts
来进行管理该工具会帮助我们调用react scaffold内部配置的webpack
我们可以私有reject脚本,将封装起来的webpack配置暴露出来
从而查看对应的webpack配置
注意: reject脚本是不可逆操作
Hello React
App,js
// reactv16, 在react中使用jsx,需要手动引入react
// 但是自reactv17开始,react单文件组件在编译的时候,会自动在编译的时候,引入JSX, 无需手动引入
import { Component } from 'react'
// 一般组件的导出使用的都是默认导出
export default class App extends Component {
render() {
return (
// <></> -> <React.Fragment></React.Fragment>
// 但是使用Fragment简写的时候,是不需要引入react的
// 因为其在编译的时候会自动引入react
<>
<h2>Hello World</h2>
</>
)
}
}
index.js
// src/index.js --- react scaffold 的默认入口文件
import React from 'react'
// 从React18开始,导入的是react-dom/client
// reactv17 之前 导入的是react-dom
import ReactDOM from 'react-dom/client'
// 1. react scaffold是基于webpack进行打包的
// 所以默认情况下, 可以省略js后缀 默认文件夹的入口也是index.js
// 2. react的单文件组件的后缀一般为js,也可以为jsx(老版本),两者之间没有任何区别
import App from './App'
// 不同于vue的挂载点是div#app
// react scaffold的默认挂载点为div#root
// Reactv17 之前的写法
// ReactDOM.render(<App />, document.getElementById('root'))
// React18开始的写法
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<App />)
补充
// 引入react的方式
import React from 'react'
但是在react源码中,react模块的导出方式
// 可见react默认是使用export进行导出的,没有使用export default 单独对内容进行导出
export {
// ...
Component,
Fragment,
PureComponent,
StrictMode,
// ...
} from './src/React';
但是为什么我们在react scaffold中使用react的时候,可以直接使用默认导入呢
这是因为react scaffold脚手架是基于webpack搭建的,因此其实基于node环境运行的
所以对应的包在打包到生产环境的时候,其是会编译成使用CJS模块的代码
node_module/react/index.js
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react.production.min.js');
} else {
module.exports = require('./cjs/react.development.js');
}
而cjs导出的内容,本质上是一个对象,其可以直接导出,也可以直接接收整个对象后再进行使用