react-scripts流程及源码分析

react-scripts流程及源码分析

技术杂谈小彩虹2021-07-08 13:51:3390A+A-

相关版本

该版本直接fork官方的GitHub仓库,版本号为 v3.2.1

详细的源代码注释,请查看GitHub仓库

目录结构

├─bin
│  └─react-scripts.js                # 命令入口文件
├─config
│  └─jest                            # jest配置文件夹 
│  ├─env.js                          # 环境变量配置
│  ├─modules.js                      # 返回对应的JS或TS配置
│  ├─paths.js                        # 项目主要的入口文件配置项
│  ├─pnpTs.js                        # pnp相关配置项
│  ├─webpack.config.js               # webpack的配置
│  └─webpackDevServer.config.js      # webpack开发服务器的配置内容
├─fixtures                           # 暂不清楚用途
├─lib                                # TS定义
├─scripts                            # 对应的启动脚本
│  ├─build.js                        # run build的脚本
│  ├─eject.js                        # run eject的脚本
│  ├─init.js                         # create-react-app后的执行脚本
│  ├─start.js                        # run start的脚本
│  └─utils                           # 工具函数封装
├─template                           # 普通的js模板文件夹
│  ├─public
│  └─src
└─template-typescript                # typescript版的模板文件夹

流程分析

该源代码采用lerna工具管理依赖,主要的源码均位于packages目录下。在react-scripts目录下的package.json中,bin字段内容如下:

  "bin": {
    "react-scripts": "./bin/react-scripts.js"
  },

因此我们运行该react-scripts命令时,实际是执行该目录下的./bin/react-scripts.js。

bin/react-scripts.js

该文件在执行时,会读取命令行参数。主要源码如下:

const args = process.argv.slice(2);

在日常开发过程中,执行命令的主要格式是:yarn run start, 最终在命令行被转为换:node react-scripts路径 start。因此要读取有效的命令行参数,也应该是从第三个参数开始。

在读取到的参数中,查找出有效的命令build/eject/start/test对应的序号,如果没有查找到则取第一个参数作为默认值,但最终也会直接输出警告信息后退出程序。

查找到有效命令后,执行**../scripts**目录下对应的脚本文件,并传入除有效参数外的剩余参数。

scripts/init.js

该文件主要是在执行完create-react-app命令后,将项目模板文件复制到新建的项目目录。传入的参数列表如下:

{
  appPath, // 项目根目录
  appName, // 项目名称
  verbose, // 是否打印日志
  originalDirectory, // 命令执行目录
  template // create-react-app命令中传入的额外参数:指定的模板文件路径
}

scripts/start.js

对应的执行命令为:yarn run start。主要作用:启动开发服务器,执行流程如下:

  1. 设置环境变量:BABEL_ENV、NODE_ENV=“development”;
  2. 加载自定义的环境变量配置;
  3. 必要的入口文件检测:作为入口的index.html和js;
  4. 读取ip和port;
  5. 检测是否配置browserslist。如果最终都没有browserlist则直接退出;
  6. 查找可用端口:先确认默认端口是否可用,不可用则确认是否自动查找可用端口,不查找则直接退出,查找则返回一个可用端口;
  7. 配置createCompiler的options并执行,返回一个compiler;
  8. 载入代理配置,并配置代理服务prepareProxy;
  9. 创建开发服务配置,具体的配置代码放在webpackDevServer.config.js;
  10. 运行WebpackDevServer,传入compiler和proxyConfig,返回一个devServer
  11. 启动devServer服务,如果在交互模式下清理控制台,再打开浏览器

scripts/build.js

对应的执行命令为:yarn run build。主要作用:源代码构建,执行流程如下:

  1. 设置环境变量:BABEL_ENV、NODE_ENV=“production”;
  2. 加载自定义的环境变量配置;
  3. 必要的入口文件检测:作为入口的index.html和js;
  4. 生成webpack配置;
  5. 检测是否配置browserslist;
  6. 检测是否配置browserslist。如果最终都没有browserlist则直接退出
  7. 在构建前,检测出所有文件大小的map
  8. 清空构建的输出目录
  9. 复制待构建目录的public目录到构建目录:静态文件夹名——paths.appPublic
  10. 开始webpack构建
  11. 构建完成后,输出相关的构建信息:警告/警告/错误、文件大小信息、后续操作的提示

scripts/eject.js

对应的执行命令为:yarn run eject。主要作用:暴露webpack配置到项目目录中,让用户可以自行修改构建配置,执行流程如下:

  1. 确认是否需要继续当前操作——暴露webpack等配置信息?是——继续,否——退出
  2. 如果有git源代码管理工具?否——继续;是——是否有未保存的记录?是——退出,否继续
  3. 读取react-scripts待复制的文件夹及其下的文件,分别确认所有内容在项目根目录下是否存在,有一个存在则直接退出。检测的文件夹:['config', 'config/jest', 'scripts']
  4. 生成相关的jest配置:jestConfig
  5. 在项目目录下,创建待复制的文件夹
  6. 相关文件复制:相关文件复制:在文件复制文件时,删除文件内容@remove-on-eject-begin...@remove-on-eject-end
  7. package.json配置修改并保存:

devDependencies、dependencies中删除react-scripts dependencies依赖添加:react-scripts的dependencies中,除了也属于optionalDependencies的所有依赖,全部添加到项目依赖中 dependencies依赖是所有字段全部按依赖名称重新排列一次 scripts字段:用react-scripts的bin字段的key去匹配项目package.json的scripts中所有的value,将匹配到的结果全部替换为node scripts/[key].js scripts字段:删除eject项 添加其他字段:jest、babel、eslintConfig

  1. 如果类型声明的入口路径appTypeDeclarations:读取并替换react-scripts types后保存
  2. 移除node_modules/.bin/react-scripts命令
  3. 重新安装依赖
  4. 如果有git则直接提交git记录

流程图

scripts/start.js

scripts/build.js

scripts/eject.js

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1

联系我们