前言
前段时间,一直在研究 react 技术栈,对于项目的构建方面,又有一定的特殊需求,通过 npx create-react-app [filename] 安装以后,发现没有 webpack 相关的配置的目录,在读了 react 官方文档后,发现通过 yarn eject 可以弹出相关的配置,进行自定义配置。
于是,我就想知道 eject 到底做了什么,发现里面涉及到很多的知识点,也有很多是我之前没有接触到的地方,自从看了 eject 和 build 的源码,我觉得,我们其实还可以做很多事。
初始化声明
其实,里面绝大部分内容都是基于 node 去实现的:
如果是 node 小白,可以学习到有关 node 的一些知识点;
如果是 node 大佬,也可以看看是否有可以学习的思想。
如果觉得哪里写的不对的,或者解释不够清晰,还请大佬们指出
复制代码
订阅 promise 的 reject
process.on("unhandledRejection", err => {
throw err;
});
复制代码在初始化执行 yarn reject 的时候,会先发布一个 unhandledRejection 的订阅,这个订阅是在如果在事件循环的一次轮询中,一个 Promise 被 rejected,并且此 Promise 没有绑定错误处理器, unhandledRejection 事件会被触发。
这里直接 throw err 的目的,是为了在发生 rejected 的时候,直接崩溃,而不是忽略;
由于这里订阅了,将来一旦发生了 rejected ,就会直接退出 node 进程。
声明要使用的方法 (初始化)
const fs = require('fs-extra'); // node中fs的扩展,在支持fs所有api的基础上,还支持promise写法
const path = require('path'); // 用来获取目录模块
const execSync = require('child_process').execSync; // 执行同步命令
const chalk = require('react-dev-utils/chalk'); // 用来修改log字体颜色
const paths = require('../config/paths'); // 对于路径的处理
const createJestConfig = require('./utils/createJestConfig'); // 创建单元测试配置
const inquirer = require('react-dev-utils/inquirer'); // 常用交互式命令行用户界面的集合
const spawnSync = require('react-dev-utils/crossSpawn').sync; // 跨平台执行系统命令
const os = require('os'); // 用来操作系统的方法
const green = chalk.green; // 绿色
const cyan = chalk.cyan; // 青色
function getGitStatus() { // 获取git状态
try {
let stdout = execSync(`git status --porcelain`, {
stdio: ['pipe', 'pipe', 'ignore'],
}).toString();
return stdout.trim();
} catch (e) {
return '';
}
}
function tryGitAdd(appPath) { // 用来提交根目录下config和scripts文件夹下修改或者更新的内容,但是不包括删除部分
try {
spawnSync(
'git',
['add', path.join(appPath, 'config'), path.join(appPath, 'scripts'