前言:

create-react-app 是一个全局的命令行工具用来创建一个新的项目

react-scripts 是一个生成的项目所需要的开发依赖

一般我们开始创建react web应用程序的时候,要自己通过 npm 或者 yarn 安装项目的全部依赖,再写webpack.config.js,一系列复杂的配置,搭建好开发环境后写src源代码。
现在 如果你正在搭建react运行环境,使用 create-react-app 去自动构建你的app程序。你的项目所在的文件夹下是没有配置文件。react-scripts 是唯一的 额外的 构建依赖在你的package.json中,你的运行环境将有每一个你需要用来构建一个现代React app应用程序。你需要的依赖,和在配置文件中编写的配置代码,react-scripts 都帮你写了,比如:react-scripts帮你自动下载需要的 webpack-dev-server 依赖,然后react-scripts自己写了一个nodejs服务端的脚本代码 start.js来 实例化 WebpackDevServer ,并且运行启动了一个使用 express 的Http服务器,现在你只需要专心写src源代码就可以了。省去了很多精力,最适合快速上手一个demo了。

react-scripts有以下支持,都帮你配置好了:
React, JSX, ES6, and Flow syntax support.
Language extras beyond ES6 like the object spread operator.
Import CSS and image files directly from JavaScript.
Autoprefixed CSS, so you don’t need -webkit or other prefixes.
A build script to bundle JS, CSS, and images for production, with sourcemaps.
A dev server that lints for common errors.

Getting Started

安装

[plain] view plaincopy
  1. npm install -g create-react-app

创建一个应用程序

[plain] view plaincopy
  1. create-react-app my-app
  2. cd my-app

生成的目录结构

[plain] view plaincopy
  1. my-app/
  2. README.md
  3. node_modules/
  4. package.json
  5. .gitignore
  6. public/
  7. favicon.ico
  8. index.html
  9. src/
  10. App.css
  11. App.js
  12. App.test.js
  13. index.css
  14. index.js
  15. logo.svg

没有配置文件(webpack.config.js)

运行应用程序

[plain] view plaincopy
  1. npm run start

or

[plain] view plaincopy
  1. yarn start

在浏览器中打开

[plain] view plaincopy
  1. http://localhost:3000

现在我们看 my-app文件夹下的public/index.html 和src/index.js的源码,我们可以在这里编写项目代码,但是注意 public/index.html 是启动http服务器的首页,src/index.js是编译的入口文件,只能叫index这个名字,改别的名字不行。

打开 http://localhost:3000/index.html 首页,f12查看 网页源码,你会看到

[plain] view plaincopy
  1. <script type="text/javascript" src="/static/js/bundle.js"></script>

/static/js/bundle.js
在你的项目my-app你是看不到这个文件路径的,你也没有写配置文件webpack.config.js,
http服务器配置,自动代开浏览器窗口,react,es6语法编译,babel-core,webpack,等等这些 你都没下载,配置。
这些活,react-scripts 都帮你做了。

刚才的过程分析

回顾 
npm run start
我们 一开始这么启动服务 运行项目
打开你的my-app\package.json

[plain] view plaincopy
  1. "scripts": {
  2. "start": "react-scripts start",
  3. ...
  4. }

所以执行的是 react-scripts start 
打开你的my-app\node_modules\react-scripts这个文件夹下的bin文件夹下的react-scripts.js文件

[plain] view plaincopy
  1. #!/usr/bin/env node
  2. var spawn = require('cross-spawn');
  3. var script = process.argv[2];
  4. var args = process.argv.slice(3);
  5. switch (script) {
  6. case 'build':
  7. case 'eject':
  8. case 'start':
  9. case 'test':
  10. var result = spawn.sync(
  11. 'node',
  12. [require.resolve('../scripts/' + script)].concat(args),
  13. .......

上面代码中  script 的变量值是 start
所以执行 my-app\node_modules\react-scripts\scripts 文件夹下的  start.js 文件代码节选重点如下

[plain] view plaincopy
  1. var webpack = require('webpack');
  2. var WebpackDevServer = require('webpack-dev-server');  // 启动http服务器
  3. var paths = require('../config/paths');  //要编译的文件路径与生成路径等
  4. var config = require('../config/webpack.config.dev');
  5. var DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; //这就是为什么 端口号 不是8080 而是 3000 的原因,在这里可以改成8080,重新npm run start 生效
  6. detect(DEFAULT_PORT).then(port => {
  7. if (port === DEFAULT_PORT) {
  8. run(port); //这里开始运行
  9. return;
  10. }
  11. ......
  12. function run(port) {
  13. // 这里可以设置 http协议, 或者可以在 npm run start 之前 cmd命令窗口中执行 set HTTPS=true&&npm start 改成https 安全协议
  14. var protocol = process.env.HTTPS === 'true' ? "https" : "http";
  15. var host = process.env.HOST || 'localhost';
  16. setupCompiler(host, port, protocol);  // 编译源码 ,生成路径
  17. runDevServer(host, port, protocol);  //启动 http服务器
  18. }
  19. //配置http服务器
  20. function runDevServer(host, port, protocol) {
  21. var devServer = new WebpackDevServer(compiler, {
  22. compress: true,
  23. clientLogLevel: 'none',
  24. contentBase: paths.appPublic,   //根据导入的paths 指定应用根目录(即index.html所在目录)
  25. hot: true,
  26. publicPath: config.output.publicPath, //根据导入的 config 变量,指定 虚拟目录,自动指向path编译目录(/assets/ => /build/js/)。html中引用js文件时,
  27. //必须引用此虚拟路径(但实际上引用的是内存中的文件,既不是/build/js/也不是/assets/)。
  28. quiet: true,
  29. watchOptions: {
  30. ignored: /node_modules/
  31. },
  32. // Enable HTTPS if the HTTPS environment variable is set to 'true'
  33. https: protocol === "https",
  34. host: host
  35. });
  36. /**
  37. * 省略其他代码
  38. */
  39. openBrowser(protocol + '://' + host + ':' + port + '/');    // 打开浏览器 向服务器发送请求
  40. });
  41. }
  42. function setupCompiler(host, port, protocol) {
  43. compiler = webpack(config, handleCompile);  //  根据导入的 config 变量  指向的 webpack.config.dev 配置文件  运行
  44. /**
  45. * 省略其他代码
  46. */
  47. }

start.js 文件代码 中 导入了  my-app\node_modules\react-scripts\config文件夹下的  webpack.config.dev.js 与 paths.js
paths.js  代码节选如下:

[plain] view plaincopy
  1. var appDirectory = fs.realpathSync(process.cwd());   // 获取npm run start 运行所在的路径
  2. function resolveApp(relativePath) {
  3. return path.resolve(appDirectory, relativePath);
  4. }
  5. module.exports = {
  6. appPath: resolveApp('.'),
  7. ownPath: resolveApp('node_modules/react-scripts'),
  8. appBuild: resolveApp('build'),
  9. appPublic: resolveApp('public'),
  10. appHtml: resolveApp('public/index.html'),   //  这就是  一开始  我们的项目 要使用public/index.html作为 默认首页
  11. //  这里写什么文件名,项目中就要使用什么文件名  包括 也要有public文件夹
  12. appIndexJs: resolveApp('src/index.js'),   //编译的入口文件的文件名  项目中要包括src文件夹
  13. appPackageJson: resolveApp('package.json'),
  14. appSrc: resolveApp('src'),
  15. yarnLockFile: resolveApp('yarn.lock'),
  16. testsSetup: resolveApp('src/setupTests.js'),
  17. appNodeModules: resolveApp('node_modules'),
  18. // this is empty with npm3 but node resolution searches higher anyway:
  19. ownNodeModules: resolveOwn('node_modules'),
  20. nodePaths: nodePaths,
  21. publicUrl: getPublicUrl(resolveApp('package.json')),
  22. servedPath: getServedPath(resolveApp('package.json'))
  23. };
  24. /**
  25. * 省略其他代码
  26. */

webpack.config.dev.js  代码节选如下:

[plain] view plaincopy
  1. var paths = require('./paths');  //也导入了 同文件夹下的 paths.js
  2. module.exports = {  entry: [    require.resolve('react-dev-utils/webpackHotDevClient'),    require.resolve('./polyfills'),    paths.appIndexJs     // 编译的入口文件  ],  output: {    path: paths.appBuild,    pathinfo: true,       filename: 'static/js/bundle.js', // 只是编译后生成的目标文件 ,这就是一开始我们 打开浏览器按f12看到的index.html导入的           //  <script type="text/javascript" src="/static/js/bundle.js"></script>    publicPath: publicPath  },
  3. /**
  4. * 省略其他代码
  5. */
  6. }

已经搭建好运行环境了,接下来 如何开发app

导入组件

由于babel依赖,这个项目支持es6模块
当你仍然使用require() and module.exports ,我们鼓励你去使用import and export 替代.

例如: 
Button.js

[plain] view plaincopy
  1. import React, { Component } from 'react';
  2. class Button extends Component {
  3. render() {
  4. // ...
  5. }
  6. }
  7. export default Button; // 不要忘记去使用 export default!

DangerButton.js

[plain] view plaincopy
  1. import React, { Component } from 'react';
  2. import Button from './Button'; //从另一个文件导入一个组件
  3. class DangerButton extends Component {
  4. render() {
  5. return <Button color="red" />;
  6. }
  7. }
  8. export default DangerButton;

增加样式
Button.css

[plain] view plaincopy
  1. .Button {
  2. padding: 20px;
  3. }

Button.js

[plain] view plaincopy
  1. import React, { Component } from 'react';
  2. import './Button.css'; // 告诉webpack Button.js 使用这些样式
  3. class Button extends Component {
  4. render() {
  5. // You can use them as regular CSS styles
  6. return <div className="Button" />;
  7. }
  8. }

Autoprefixer

react-scripts 通过Autoprefixer 帮你的css文件自动添加浏览器兼容前缀
例如:

[plain] view plaincopy
  1. .App {
  2. display: flex;
  3. flex-direction: row;
  4. align-items: center;
  5. }

变成

[plain] view plaincopy
  1. .App {
  2. display: -webkit-box;
  3. display: -ms-flexbox;
  4. display: flex;
  5. -webkit-box-orient: horizontal;
  6. -webkit-box-direction: normal;
  7. -ms-flex-direction: row;
  8. flex-direction: row;
  9. -webkit-box-align: center;
  10. -ms-flex-align: center;
  11. align-items: center;
  12. }

增加CSS预处理器

首先在 my-app/  目录下  安装node-sass用来将scss编译成css

[plain] view plaincopy
  1. npm install node-sass --save-dev

打开my-app/package.json,增加以下代码到scripts中

[plain] view plaincopy
  1. "scripts": {
  2. +    "build-css": "node-sass src/ -o src/",
  3. +    "watch-css": "npm run build-css && node-sass src/ -o src/ --watch",
  4. "start": "react-scripts start",
  5. "build": "react-scripts build",
  6. ......
  7. }

现在你可以重新命名my-app/ src/App.css  to my-app/ src/App.scss  and 运行    npm run watch-css
或者你可以改成

[plain] view plaincopy
  1. "scripts": {
  2. "build-css": "node-sass src/ -o src/",
  3. "start": "npm run build-css && react-scripts start",  //先执行 build-css 再执行 react-scripts start
  4. "build": "react-scripts build",
  5. "test": "react-scripts test --env=jsdom",
  6. "eject": "react-scripts eject"
  7. }

直接 npm run start

增加图片

[plain] view plaincopy
  1. import React from 'react';
  2. import logo from './logo.png'; // 告诉webpack 这个js文件使用这张图片
  3. console.log(logo); // /logo.84287d09.png  会改变图片的名字
  4. function Header() {
  5. //导入结果是这个图片的url地址
  6. return <img src={logo} alt="Logo" />;
  7. }
  8. export default Header;

当项目构建的时候,Webpack将正确的移动图片到构建的文件夹下,提供我们正确的路径

在css工作中的方式也一样

[plain] view plaincopy
  1. .Logo {
  2. background-image: url(./logo.png);
  3. }

webpack发现所有的相对模块, 以 ./  开始

增加 bootstrap
在react+es6 moudle+bootstrap
你不是一定要React Bootstrap和React 一起使用,但是他是流行的库去整合 bootstrap 和react应用程序,如果你需要他,你可以通过Create React App整合他,通过以下几个步骤

首先安装React Bootstrap and Bootstrap从npm,React Bootstrap 不包括Bootstrap CSS ,所以你需要去安装
在 my-app/  目录下  安装

[plain] view plaincopy
  1. npm install react-bootstrap --save
  2. npm install bootstrap@3 --save

修改 my-app/src/index.js
在你的src/index.js 文件内容的顶部,导入 Bootstrap CSS 和可选的 Bootstrap theme CSS

[plain] view plaincopy
  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import 'bootstrap/dist/css/bootstrap.css';  // 必须的
  4. import 'bootstrap/dist/css/bootstrap-theme.css';  //  可选的
  5. import App from './App';
  6. import './index.css';
  7. ReactDOM.render(
  8. <App />,
  9. document.getElementById('root')
  10. );

修改 my-app/src/App.js

[plain] view plaincopy
  1. import React, { Component } from 'react';
  2. import { Grid, Navbar, Jumbotron, Button } from 'react-bootstrap';
  3. class App extends Component {
  4. render() {
  5. return (
  6. <div>
  7. <Navbar inverse fixedTop>
  8. <Grid>
  9. <Navbar.Header>
  10. <Navbar.Brand>
  11. <a href="/">React App</a>
  12. </Navbar.Brand>
  13. <Navbar.Toggle />
  14. </Navbar.Header>
  15. </Grid>
  16. </Navbar>
  17. <Jumbotron>
  18. <Grid>
  19. <h1>Welcome to React</h1>
  20. <p>
  21. <Button
  22. bsStyle="success"
  23. bsSize="large"
  24. href="http://react-bootstrap.github.io/components.html"
  25. target="_blank">
  26. View React Bootstrap Docs
  27. </Button>
  28. </p>
  29. </Grid>
  30. </Jumbotron>
  31. </div>
  32. );
  33. }
  34. }
  35. export default App;

最后 运行

[plain] view plaincopy
  1. npm run start

参考链接  https://github.com/facebookincubator/create-react-app

使用 create-react-app 构建 react应用程序 (react-scripts)相关推荐

  1. react入门代码_如何在React中构建温度控制应用程序-包括提示和入门代码

    react入门代码 我们正在建立的 (What we're building) In this beginner React project, we're going to learn how to ...

  2. 深入浅出 Create React App

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

  3. tailwind css_什么是Tailwind CSS,如何将其添加到我的网站或React App中?

    tailwind css CSS is a technology that can be your best or worst friend. While it's incredibly flexib ...

  4. react apollo_Apollo GraphQL:如何使用React和Node Js构建全栈应用

    react apollo Apollo Client is a complete state management library for JavaScript apps. It's a powerf ...

  5. react.js做小程序_如何使用React.js构建现代的聊天应用程序

    react.js做小程序 In this tutorial, I will guide you to build your own group chat application using React ...

  6. 【翻译】基于 Create React App路由4.0的异步组件加载(Code Splitting)

    基于 Create React App路由4.0的异步组件加载 本文章是一个额外的篇章,它可以在你的React app中,帮助加快初始的加载组件时间.当然这个操作不是完全必要的,但如果你好奇的话,请随 ...

  7. 在 .NET Core 5 中集成 Create React app

    翻译自 Camilo Reyes 2021年2月22日的文章 <Integrate Create React app with .NET Core 5> [1] 本文演示了如何将 Crea ...

  8. react.js app_如何创建Next.js入门程序以轻松引导新的React App

    react.js app Getting started with a new React app is easier than ever with frameworks like Next.js. ...

  9. 如何使用Create React App DevOps自动化工作中所有无聊的部分

    by James Y Rauhut 詹姆士·鲁豪(James Y Rauhut) 如何使用Create React App DevOps自动化工作中所有无聊的部分 (How I automate al ...

  10. react hooks使用_如何使用React Hooks和Context API构建简单的PokémonWeb App

    react hooks使用 After seven years of full stack development using Ruby, Python, and vanilla JavaScript ...

最新文章

  1. 【408预推免复习】计算机组成原理之计算机的运算方法
  2. oracle 11gr2 单机数据库使用asm,RHEL7上安装11gR2单机使用ASM存储搭建Physical Standby笔记...
  3. Unity3D游戏内存瘦身指南: UI优化是关键
  4. IDA Pro安装教程
  5. Asp.Net第一章入门之后台处理程序
  6. dedecms提取某栏目及子栏目名称到首页怎么弄
  7. 宁波医院计算机试题及答案,(宁波市第25届小学生计算机程序设计竞赛试题及答案.doc...
  8. Why Open vSwitch?
  9. 初二因式分解奥数竞赛题_八年级数学因式分解专项练习试题.doc
  10. Android日期格式化
  11. (转载)JavaWeb学习总结(五十二)——使用JavaMail创建邮件和发送邮件
  12. C BNF grammar
  13. 洛谷 P2764(最小路径覆盖=节点数-最大匹配)
  14. Hexo博客与Next主题的高级应用
  15. ijkplayer 代码走读之 h264 解封装器应用详解
  16. Kaggle案例精选——电信客户流失预测(Telecom Customer Churn Prediction)Part One:数据说明;数据导入、处理;数据总览;描述性分析
  17. 盘点中国顶级黑客Top10,雷军也名列其中!
  18. Linux系统日志管理
  19. Spark数据挖掘实例1:基于 Audioscrobbler 数据集音乐推荐
  20. Mysql数据库使用规范

热门文章

  1. C++编程进阶5(内联函数、如何降低编译成本、处理继承体系中同名不同参的成员函数、私有虚函数)
  2. syntaxerror是什么错误_【第1643期】自定义错误及扩展错误
  3. Redis Sentinel--运维管理
  4. 业界 | Facebook F8开发者大会首日:扎克伯格走心演讲,VR硬件发售
  5. 换行显示print_r($arr);打印结果显示:Array( [0] = 百度 [1] = 阿里)
  6. J2EE Java泛型的好处
  7. 简单解决XP共享连接数10限制
  8. 时间戳显示为多少分钟前,多少天前的JS处理,JS时间格式化,时间戳的转换
  9. 程序员修炼之道:从小工到专家阅读笔记01
  10. Python面向对象(继承)