本文差点难产而死。由于总结的过程当中,屡次怀疑本文是对官方文档的直接翻译和简单诺列;同时官方文档很全面,全范围的介绍无疑加深了写做的心智负担。但在最终的梳理中,发现走出了一条不同凡响的路,因而坚持分享出来。javascript
但愿本文除了能带领咱们再次了解 Create React App(后文简称 CRA) 外,还能提供一种不一样的知识组织结构和技术视角,加深咱们对整个 React 技术生态的理解。css
本文多是多篇博客的综合体,整理和写做时间 15h+,仔细阅读时间 30min+,请慢用。
本文面向的读者是:html
其次,本文在对官方文档进行必定的从新编排下,加上了以下创新点以完善总体的阅读学习体验:前端
最终,本文不涉及源码的解读,想要阅读源码的同窗能够移步官方源码仓库,总体设计思路并非很难,具体实现原理能够细细品嚼;且本文对与 CRA 不直接相关的技术点会略略而过,欢迎从点到面主动学习更多。如下是官方源码仓库以及官方文档地址:java
常见的初始化 React App 的方式有:node
下面咱们分别进行介绍与实战练习。react
React 自己专一于构建用户界面,并不依赖于某个构建工具,所以咱们能够用传统的方式引入 React 并书写第一个“Hello World!” App。这种方式是快速尝试 React 的好方法,但并不适用于正式开发。webpack
如下 HTML 代码段是一种实现方式,使用了可选的 Babel 编译和 JSX 语法,基于非构建工具的更多初始化页面的方法(如不使用 JSX 等)能够自行探索。git
<html> <head> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <!-- 不须要用于生产环境 --> </head> <body> <div id="root"></div> <script type="text/babel"> ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root') ) </script> </body> </html>
构建工具备不少种,目前最为主流的构建工具当属 Webpack。如何使用 Webpack 逐步构建 React App?github
果不其然,为了证实 CRA 的便捷性而引出的本节 Webpack 实战,耗费了一小时多的时间进行了亲自踩坑,搜索了较多的博文都因为发布时间性而不能和最新的版本进行融合,最终根据 Github 中 react-webpack-babel 库的 package.json 文件里的相关信息才获得实现。
# 建立一个项目并进入该项目 $ mkdir react-webpack-steper & cd react-webpack-steper # 使用默认选项直接生成一个初始化的 package.json $ npm init -y # 安装 React 基础包 $ sudo npm install --save react react-dom # 安装 Webpack 相关工具 - 打包、本地启动支持、本地异步请求模拟以及热更新等 $ sudo npm install --save webpack webpack-cli webpack-dev-server # 安装 Babel 相关工具 - 提供 ES6+ 新功能支持 $ sudo npm install --save-dev @babel/cli @babel-core @babel/preset-env @babel/preset-react $ sudo npm install --save-dev babel-loader babel-plugin-module-resolver html-webpack-plugin # 新建打包、编译配置文件并准备编写 $ touch webpack.config.js $ touch .babelrc # 新建 React 文件 $ mkdir src $ touch src/index.js $ touch src/index.html
其中,webpack.config.js 源码以下:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: path.resolve(__dirname, './src/index.js'), module: { rules: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }, ] }, resolve: { extensions: ['*', '.js', '.jsx'] }, output: { path: path.resolve(__dirname, './build'), filename: 'bundle.js', publicPath: '/' }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, './src/index.html') }) ] }
.babelrc 源码以下:
{ "presets": ["@babel/preset-env", "@babel/preset-react"], "plugins": [ ["module-resolver", { "root": ["./src"] }] ] }
src/index.html 源码以下:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Hello World!</title> </head> <body> <div id="root">Loading...</div> </body> </html>
src/index.js 源码以下:
import React from 'react' import ReactDOM from 'react-dom' ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root') )
此时,一个基于 Webpack 手动搭建的简易型“Hello World”App 开发完成,能够经过以下命令本地运行。
$ webpack-dev-server --mode development --open --hot
更多自定义内容如添加 devServer 支持、添加多页应用支持...等各类各样新技术栈的支持,也能够引伸实战。
可见,不使用构建工具编写不切实际,使用构建工具手动搭建 React App 又很繁琐。所以咱们须要一个能初始化一个可直接运行项目的工具,并提供各类简易的插件,Create React App 应运而生。
CRA 适用于中小型 React 项目。
CRA 将具备构建现代单页 React 应用所需的一切:
Create React App 很是适合:
若是咱们想在没有数百个传递构建工具依赖的状况下尝试 React,请考虑使用单个 HTML 文件构建或使用在线沙箱平台构建。
一些支持的浏览器规则以下:
这里的重点是 BrowsersList,一个“在不一样的前端工具之间共用目标浏览器和 node 版本的配置工具”。简而言之,就是 Babel 等转移工具经过咱们设置的 BrowsersList 中想要支持的浏览器版原本决定哪些语法须要被编译。
一些支持的 ES 标准规则以下:
该项目支持最新 JavaScript 标准的超集。 除ES6语法功能外,它还支持:
Create React App 有两个核心库,以下:
到这里,咱们终于须要经过命令行来安装和使用 CRA,来构建咱们的第三个“Hello World”App。
为保证每个新项目都能使用到 CRA 最新最全的功能,请确保 CRA 为最新版本。
# 再已安装 CRA 的状况下,能够先卸载 CRA $ npm uninstall -g create-react-app # 正式安装 CRA $ npm install -g create-react-app
根据咱们的 npm 版本,选择相应命令来安装最新版的 CRA 并初始化第一个项目。同时检查本身的 node 版本,须要在本地开发计算机上安装 Node 8.16.0 或 Node 10.16.0 或更高版本(但服务器上不须要)。 咱们可使用nvm(macOS / Linux)或 nvm-windows 在不一样项目之间切换Node版本。
# 查看本身的 npm 版本 $ npm --version # 第一种新建项目方式——npm 5.2+ 时,如下命令会安装最新版 CRA $ npx create-react-app my-app # 第一种新建项目方式——npm 版本小于等于 5.1 时 $ create-react-app my-app # 第二种新建项目方式 # npm 6+ 开始支持 npm init <initializer> $ npm init react-app my-app # 第三种新建项目方式 $ yarn create react-app my-app
经过命令行的构建,咱们初始化了第一个 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 打包入口文件,一般连接整个业务代码;后者是页面模板,是打包后整个静态页面的总入口。
这里对如下两个文件的出现进行简要的意义归纳。
_
CRA 默认提供了运行、测试、打包、部署以及弹出项目的命令。其中的一些贴士:
# ---- 运行 ---- $ npm start $ open http://localhost:3000 # ---- 测试 ---- $ npm test # ---- 打包 ---- $ npm run builds # ---- 弹出配置 ---- $ npm run eject
根据官方文档的思路,咱们还能从更多角度拓展 CRA 的使用边界,下面进行概要介绍。
这里没法深刻展开,每个点均可以是一个新的实战,当咱们须要某个功能时即可以查阅相关文档来主动探索。其中“分析打包文件”的解读见“实战 4”。
# 安装文件分析工具 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。
回到刚才“实战 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
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 上。
截止目前(2020-01-10),CRA 的最新版本是 v3.3.0,咱们能够从 Github 的 MileStone 中看到将来可能会改善的功能,其中整理并以下所述。
让咱们一块儿持续关注。
回顾文章,咱们从初始化 React App 的多种方式,引出 CRA 的必要性再对其进行较为充分的解释,最后配上 6 个角度来从一些角度对 CRA 的使用方式进行了实战,最后回归到 CRA 的版本展望之中。
感谢你的阅读,若是你有什么更多的疑惑,CRA 的官方文档 + 开源仓库必定会知足你的一切。
最后,一块儿拜读一下 CRA 和 Redux 做者、React 的核心贡献者 Dan Abramov 发布的这篇“个人十年回顾”文章。
如今咱们能够开始正式深刻地学习 React 技术栈了。