Create React App 可用脚本全解析:深入 npm start / npm test / npm run build / npm run eject 的工作原理

发布时间:2026/9/18 7:50:39
Create React App 可用脚本全解析:深入 npm start / npm test / npm run build / npm run eject 的工作原理 Create React App 可用脚本全解析深入 npm start / npm test / npm run build / npm run eject 的工作原理【免费下载链接】create-react-appSet up a modern web app by running one command.项目地址: https://gitcode.com/gh_mirrors/cr/create-react-app在 Create React AppCRA创建的项目中package.json的scripts字段预置了四个核心命令start、test、build、eject。它们分别对应开发调试、单元测试、生产构建与配置弹出四大场景是日常开发与上线流程的主干。本文以官方文档 available-scripts.md 为主线逐条拆解这四个命令的行为、用法与底层实现并结合本仓库react-scripts包的真实源码帮助你理解每条命令背后发生了什么以及何时应该或不应该使用它们。一、这四个脚本从哪来react-scripts 与 package.json 的 scripts用create-react-app创建项目后模板会把以下四个脚本写入项目的package.json。生成逻辑位于 init.jsscripts: { start: react-scripts start, build: react-scripts build, test: react-scripts test, eject: react-scripts eject }这四个命令并非 npm 内置而是通过react-scripts包提供的命令行程序来执行。react-scripts包的bin字段见 package.json指向 bin/react-scripts.js该文件会识别build、eject、start、test四个子命令并把后续参数原样转发给 scripts 目录下对应的start.js、test.js、build.js、eject.js脚本。换句话说npm start最终等价于执行node scripts/start.js在弹出配置后则直接变成node scripts/start.js理解这一点后面分析每条命令的底层行为就顺理成章了。二、npm start启动开发服务器官方行为说明在项目目录下执行npm start应用将以开发模式运行。浏览器访问 http://localhost:3000 即可查看编辑代码后页面会自动刷新热重载控制台会同时显示 ESLint 检查错误。底层发生了什么npm start对应的 start.js 大致执行以下流程首先设置BABEL_ENV与NODE_ENV均为development并注册unhandledRejection处理器避免 Promise 异常被静默吞掉通过checkRequiredFiles校验public/index.html与src/index.js是否存在缺失则直接退出这也解释了为什么这两个文件必须保留原名详见 folder-structure.md默认端口取process.env.PORT未设置时回退到3000DEFAULT_PORT parseInt(process.env.PORT, 10) || 3000若端口被占用choosePort会提示使用下一个可用端口加载开发环境的 webpack 配置configFactory(development)创建WebpackDevServer监听文件变化实现热重载启动成功后自动调用openBrowser打开默认浏览器并在控制台输出 Starting the development server...若设置了HTTPStrue协议会切换为https若设置了HOST则会绑定到指定主机名而非默认的0.0.0.0代码中还会检查 React 版本与 Fast Refresh 的兼容性当FAST_REFRESH开启但 React 版本低于 16.10.0 时会打印警告提示升级。常用的相关环境变量开发模式下可通过环境变量调整行为完整参数表见 advanced-configuration.md这里列出与npm start最相关的几个变量说明BROWSER指定启动时打开的浏览器设为none可完全禁用自动打开PORT修改开发服务器端口默认 3000HOST指定监听的主机名默认绑定所有主机名localhost、局域网地址等HTTPS设为true时以 https 模式运行开发服务器CHOKIDAR_USEPOLLING设为true时文件监听改用轮询模式解决虚拟机内改动不生效的问题FAST_REFRESH设为false可关闭组件热更新Fast RefreshCI设为true时开发模式不再自动打开浏览器三、npm test交互式测试运行器官方行为说明npm test以**交互式监听模式watch mode**启动 Jest 测试运行器。与npm start重新编译代码类似每次保存文件后它都会自动重新运行相关测试。监听模式的判定逻辑在 test.js 中是否进入监听模式由以下逻辑决定环境变量CI存在时不进入监听模式跑一次即退出这是 CI 服务器的默认行为命令行显式传入--watchAll或--watchAllfalse时以显式参数为准其余情况下脚本会检测项目是否处于 Git 或 Mercurial 仓库中在仓库内则使用--watch只跑与最近一次提交相关的测试不在仓库内则使用--watchAll跑全部测试。监听模式下Jest 会提供一个交互式命令行界面按a运行全部测试输入搜索模式聚焦特定测试具体按键提示会在每次运行后打印 Watch Usage 说明。运行范围与默认配置默认情况下npm test只运行自上次提交以来发生变更的文件相关测试这是为了在测试数量增长后依然保持快速若项目不在 Git/Mercurial 仓库中或处于 CI 环境Jest 会运行全部测试测试环境默认是jsdomNode 中模拟浏览器全局变量window、document等。如果你的测试完全不依赖浏览器 API可以在package.json中把test改为react-scripts test --envnode以获得更快的运行速度需要 jsdom 的典型场景包括ReactDOM.render、React Testing Library 的render()、Enzyme 的mount()等。进阶用法与完整文档覆盖率报告npm test -- --coverage注意中间的--会输出代码覆盖率报告但覆盖率模式下测试明显变慢建议与日常工作分开运行聚焦/排除测试用fit()聚焦单个测试、xit()临时跳过某个测试初始化测试环境创建src/setupTests.js它会在每次测试运行前自动执行对应 Jest 配置中的setupFilesAfterEnv若已 eject则需要手动在package.json的jest.setupFilesAfterEnv中声明CI 环境设置CItrue后npm test只运行一次并退出不启动监听器。各平台设置方法Windows cmd 用set CItruenpm testPowerShell 用($env:CI true) -and (npm test)Linux/macOS 用CItrue npm testJest 配置覆盖CRA 在 createJestConfig.js 中预置了roots、testMatch、transform、moduleNameMapper、watchPlugins等默认配置并允许你在package.json的jest字段覆盖白名单内的键如collectCoverageFrom、coverageThreshold、snapshotSerializers、testMatch、transformIgnorePatterns等白名单之外的键会导致启动报错并提示你使用npm run eject。测试文件的命名约定__tests__目录、.test.js/.spec.js后缀、React Testing Library 的使用、快照测试、断言语料库Chai/Sinon等更完整的测试指南请阅读 running-tests.md。四、npm run build生产构建官方行为说明npm run build将应用构建到build目录产出面向生产环境、经优化的静态资源。构建过程会以生产模式打包 React压缩代码并为产物文件名添加内容哈希hash。必要时可启用类名与函数名保留以用于性能分析profiling。底层发生了什么build.js 的关键流程设置BABEL_ENV与NODE_ENV均为production加载生产环境 webpack 配置configFactory(production)校验必需文件后通过measureFileSizesBeforeBuild记录构建前build目录的文件大小用于构建后对比输出 gzip 体积变化fs.emptyDirSync(paths.appBuild)清空build目录保留目录本身随后copyPublicFolder()把public目录中除index.html外的文件复制进去运行 webpack 生产构建压缩产物、生成带哈希的文件名并在控制台打印各 bundle/chunk 的 gzip 后体积内置体积告警阈值单个 bundle 超过 512 KB、单个 chunk 超过 1 MB时打印警告见WARN_AFTER_BUNDLE_GZIP_SIZE/WARN_AFTER_CHUNK_GZIP_SIZE支持--stats参数npm run build -- --stats会在build目录额外输出bundle-stats.json构建统计文件构建完成后调用printHostingInstructions打印托管部署提示。CI 环境下警告即失败与npm test类似npm run build默认不因 ESLint 警告而失败但设置CItrue后构建遇到警告会直接失败源码中会过滤掉 Failed to parse source map 这类已知噪声。因此常见 CI 配置Travis CI 等都会同时执行script: - npm run build - npm test产物如何部署build目录是 CRA 唯一的构建输出里面是纯静态文件index.html加/static/js/main.hash.js等带哈希的资源。你可以用任意静态服务器托管它例如npm install -g serve serve -s build也可以集成进 Express 等现有服务端应用。需要注意如果使用了基于 HTML5pushState的客户端路由如 React Router 的 browserHistory静态服务器必须把所有未知路径都回退到index.html。完整部署方案静态服务器、Express 集成、相对路径部署、客户端路由回退见 deployment.md。生产构建相关环境变量与npm run build最相关的变量完整表格见 advanced-configuration.md变量说明BUILD_PATH修改产物输出目录相对于项目根目录的相对路径默认buildPUBLIC_URL强制静态资源引用到指定 URL含主机名适合 CDN 托管场景GENERATE_SOURCEMAP设为false时不生成生产 source map可缓解小机器上的 OOM 问题INLINE_RUNTIME_CHUNK默认把 runtime 脚本内联进index.html设为false则改为普通引入CSP 场景常用IMAGE_INLINE_SIZE_LIMIT控制小于 10,000 字节的图片是否以 base64 data URI 内联设为0完全禁用内联CI设为true时把构建警告视为错误DISABLE_ESLINT_PLUGIN设为true时完全禁用 eslint-webpack-plugin五、npm run eject单向的配置弹出官方行为说明eject是一次性操作一旦弹出就无法回退。当你对默认构建工具与配置不满意时可以随时执行它该命令会从项目中移除唯一的构建依赖react-scripts并把所有配置文件与传递依赖webpack、Babel、ESLint 等以项目内依赖的形式复制进package.json。底层发生了什么eject.js 的执行流程打印提示信息并通过prompts确认 Are you sure you want to eject? This action is permanent.确认后才继续检查 Git 状态若仓库存在未提交或未跟踪的改动直接报错退出避免覆盖丢失通过verifyAbsent检查config、scripts等目录是否已存在于项目内防止覆盖已有文件把react-scripts包内的config、config/jest、scripts、config/webpack/persistentCache目录下的文件复制到项目根目录并移除标记为remove-on-eject/remove-file-on-eject的代码段更新package.json删除react-scripts依赖把其 dependencies 全部搬进项目依赖把react-scripts start之类的脚本改写为node scripts/start.js等并写入预先生成的 Jest 配置、Babel 预设presets: [react-app]与 ESLint 配置extends: react-app最后自动运行npm install或 Yarn 用户运行yarn安装新依赖成功后提示 Ejected successfully!。弹出后的世界除了eject本身其余所有命令start、test、build依然可用但指向的是已复制到你项目中的脚本你可以自由修改它们弹出后package.json会包含完整的 Jest 配置例如setupFilesAfterEnv需要手动补上src/setupTests.js的引用webpack、Babel、ESLint 的配置文件全部落入项目根目录从此配置完全由你掌控官方文档也明确说明你完全不必使用 eject。CRA 精选的默认功能集已适合中小型部署场景不必觉得有义务弹出只有当确实需要深度自定义时才使用它。另外官方还从技术角度解释了为什么 eject 会把依赖统一放进dependencies而非devDependencies对于产出静态 bundle 的前端应用而言两者的区分本就比较随意而且过去部分托管平台不安装开发依赖导致无法在服务器上构建或测试。弹出后你可以按需重新整理package.json的依赖分组。六、总结四个命令的定位与决策建议命令场景产物/行为是否可逆npm start日常开发开发服务器 热重载 控制台 lint 报错—npm test单元测试Jest 交互式监听运行器默认只跑变更相关测试—npm run build生产发布build目录下的压缩、带哈希的静态产物—npm run eject深度定制复制全部构建配置到项目内移除react-scripts依赖不可逆选择建议绝大多数项目只需使用前三个命令即可完成开发、测试、部署闭环只有当你需要修改 webpack/Babel/ESLint 底层配置、且无法通过package.json的受支持覆盖项或 advanced-configuration.md 中的环境变量满足需求时才考虑执行npm run eject——并务必牢记这是一条单行道。【免费下载链接】create-react-appSet up a modern web app by running one command.项目地址: https://gitcode.com/gh_mirrors/cr/create-react-app创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询