freeCodeCamp技术干货凝果开源社

深入浅出 Create React App

2020-01-10  本文已影响0人  hylerrix

本文差点难产而死。因为总结的过程中,多次怀疑本文是对官方文档的直接翻译和简单罗列;同时官方文档很全面,全范围的介绍无疑加深了写作的心智负担。但在最终的梳理中,发现走出了一条与众不同的路,于是坚持分享出来。

希望本文除了能带领我们再次了解 Create React App(后文简称 CRA) 外,还能提供一种不同的知识组织结构和技术视角,加深我们对整个 React 技术生态的理解。

本文可能是多篇博客的综合体,整理和写作时间 15h+,仔细阅读时间 30min+,请慢用。

本文面向的读者是:

其次,本文在对官方文档进行一定的重新编排下,加上了如下创新点以完善整体的阅读学习体验:

最终,本文不涉及源码的解读,想要阅读源码的同学可以移步官方源码仓库,整体设计思路并不是很难,具体实现原理可以细细品嚼;且本文对与 CRA 不直接相关的技术点会略略而过,欢迎从点到面主动学习更多。以下是官方源码仓库以及官方文档地址:

项目的文件结构

通过命令行的构建,我们初始化了第一个 CRA 项目,其中帮我们生成的项目目录结构如下(只有 src 下的文件才会被 Webpack 处理,只有 public 下的文件才能被 public/index.html 使用):

my-app
├── .git # 隐藏文件夹,会初始化第一个 Commit 记录
├── README.md
├── node_modules
├── package.json # 依赖配置文件
├── .gitignore
├── [floder_name] # 根目录下可以建立其他文件夹,但不会被用在生产环境中
├── public # 只有 public 下的文件才能被 public/index.html 使用
│   ├── favicon.ico
│   ├── index.html # public/index.html 页面模板
│   └── manifest.json
└── src # 只有 src 下的文件才会被 Webpack 处理
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── [floder_name] # 可以建立其他文件夹,以被 Webpack 成功导入
    ├── index.css
    ├── index.js # JavaScript 打包入口文件
    ├── logo.svg
    └── serviceWorker.js

关于 package.json、index.js 和 public/index.html 文件夹,我们通过“实战 2”已经有所了解。前者是 JavaScript 打包入口文件,通常链接整个业务代码;后者是页面模板,是打包后整个静态页面的总入口。

这里对以下两个文件的出现进行简要的意义概括。<br />_

运行 CRA 项目

CRA 默认提供了运行、测试、打包、部署以及弹出项目的命令。其中的一些贴士:

# ---- 运行 ----
$ npm start
$ open http://localhost:3000
# ---- 测试 ----
$ npm test
# ---- 打包 ----
$ npm run builds
# ---- 弹出配置 ----
$ npm run eject

搭建 CRA 生态

根据官方文档的思路,我们还能从更多角度拓展 CRA 的使用边界,下面进行概要介绍。

这里无法深入展开,每一个点都可以是一个新的实战,当我们需要某个功能时便可以查阅相关文档来主动探索。其中“分析打包文件”的解读见“实战 4”。

实战 4:使用 Source Map Explorer 分析打包文件

# 安装文件分析工具 source-map-explorer
$ sudo npm install --save source-map-explorer
# 打包项目
$ npm run build
# 将如下命令放入 package.json 中并生成快捷方式 npm run analyze
# $ source-map-explorer 'build/static/js/*.js'
# 注意此命令直接在命令行输入会提示找不到相关命令
$ npm run analyze

对于一个刚被 CRA 生成的 React App 来说,分析的结果如下,包大总计 129.38k。

实战 5:在已有的 React 项目中引入/升级 CRA

回到刚才“实战 2”建立的 react-webpack-steper 项目中,当我们已经编写了一部分业务时,能否直接在当前项目中无痛引入 CRA?

解决思路便是:在大多数情况下,更改 package.json 中的 react-scripts 版本并删除不必要文依赖配置,接着在此文件夹中运行 npm install 就足够了,但最好参考更改日志以了解潜在的重大更改。CRA 致力于将重大更改保持在最低限度,以便可以轻松升级 React 脚本。

# 卸载 CRA 本身已经提供的依赖
$ sudo npm uninstall --save webpack webpack-cli webpack-dev-server
$ sudo npm uninstall --save-dev @babel/cli @babel-core @babel/preset-env @babel/preset-react
$ sudo npm uninstall --save-dev babel-loader babel-plugin-module-resolver html-webpack-plugin
# 删除 CRA 不需要使用的文件
$ rm webpack.config.js .babelrc
# 删除 node_modules
$ rm -rf node_modules
# 手动安装 React Script
$ sudo npm install --save react-scripts@latest
# 由于 CRA 默认规则,将 src/index.html 移至 public/index.html
$ mkdir public
$ mv src/index.html public
# 在 package.json 中添加 React Script 启动命令
$ vim package.json

package.json 中添加/覆盖如下指令。

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",

再次执行即可。由于每个人的具体配置不一定一致,可根据自身所遇问题进行搜索。升级原理类似。

# 当没有 BrowsersList 时,CRA 会进行询问并帮助我们生成
$ npm start

实战 6:使用 React App Rewired 注入新配置

CRA 官方并不推荐使用 npm run eject 弹出配置,这会增加更多的 Webpack 维护工作。对于实在想改的 Webpack 配置来说,我们可以使用 React App Rewired 库进行配置注入,这里来做个小例子。

此工具可以在不 'eject' 也不创建额外 react-scripts 的情况下修改 create-react-app 内置的 webpack 配置,然后你将拥有 create-react-app 的一切特性,且可以根据你的需要去配置 webpack 的 plugins, loaders 等。

继续使用 react-webpack-steper 项目,我们的简易目标是增加 devServer 本地代理。

第一步:安装依赖并进行基础配置

# 安装依赖
$ sudo npm install --save-dev react-app-rewired customize-cra
# 根目录建立 config-overrides.js
$ touch config-overrides.js
# 修改 package.json
$ vim package.json
# 运行项目
$ npm start

其中,config-overrides.js 的初始代码为:

/* config-overrides.js */
module.exports = function override(config, env) {
  //do stuff with the webpack config...
  return config;
}

package.json 的修改思路为:

/* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test --env=jsdom",
+ "test": "react-app-rewired test --env=jsdom",
  "eject": "react-scripts eject"
}

第二步:编写配置,进行代理

# 新增配置文件
$ mkdir config
$ touch config/proxy.js
# 修改 config-overrides.js
$ vim config-overrides.js

其中,config/proxy.js 源码是:

module.exports = {
  '/api/**': {
      target: 'http://110.114.120.120:8080',
      secure: false,
      changeOrigin: false,
  },
}

config-overrides.js 修改为:

const { overrideDevServer } = require('customize-cra')
const proxy = require('./config/proxy')

module.exports = {
  devServer: overrideDevServer((config) => {
      config.proxy = proxy
      return config
  }),
}

此时,本地的所有 api 开头的接口请求都会被转发到 http://110.114.120.120:8080 的模拟后端 IP 上。

对 CRA 未来版本的简单展望

截止目前(2020-01-10),CRA 的最新版本是 v3.3.0,我们可以从 Github 的 MileStone 中看到未来可能会改善的功能,其中整理并如下所述。

让我们一起持续关注。

结语

回顾文章,我们从初始化 React App 的多种方式,引出 CRA 的必要性再对其进行较为充分的解释,最后配上 6 个角度来从一些角度对 CRA 的使用方式进行了实战,最后回归到 CRA 的版本展望之中。

感谢你的阅读,如果你有什么更多的疑惑,CRA 的官方文档 + 开源仓库一定会满足你的一切。

最后,一起拜读一下 CRA 和 Redux 作者、React 的核心贡献者 Dan Abramov 发布的这篇“我的十年回顾”文章。

现在我们可以开始正式深入地学习 React 技术栈了。

上一篇 下一篇

猜你喜欢

热点阅读