目錄:
  1. 前提说明
    1. 创建项目
      1. 精髓目录
        1. Updating to New Releases
          1. Sending Feedback
            1. Folder Structure
              1. Available Scripts
                1. Supported Browsers
                  1. Supported Language Features and Polyfills
                    1. Syntax Highlighting in the Editor
                      1. Displaying Lint Output in the Editor
                        1. Debugging in the Editor
                          1. Formatting Code Automatically
                            1. Changing the Page <title>
                              1. Installing a Dependency
                                1. Importing a Component
                                  1. Code Splitting
                                    1. Adding a Stylesheet
                                      1. Post-Processing CSS
                                        1. Adding a CSS Preprocessor (Sass, Less etc.)
                                          1. Adding Images, Fonts, and Files
                                            1. Using the public Folder
                                              1. Using Global Variables
                                                1. Adding Bootstrap
                                                  1. Adding Flow
                                                    1. Adding a Router
                                                      1. Adding Custom Environment Variables
                                                        1. Referencing Environment Variables in the HTML
                                                        2. Adding Temporary Environment Variables In Your Shell
                                                        3. Adding Development Environment Variables In .env
                                                      2. Can I Use Decorators?
                                                        1. Fetching Data with AJAX Requests
                                                          1. Integrating with an API Backend
                                                            1. Proxying API Requests in Development
                                                              1. ”Invalid Host Header” Errors After Configuring Proxy
                                                              2. Configuring the Proxy Manually
                                                              3. Configuring a WebSocket Proxy
                                                            2. Using HTTPS in Development

                                                            从create-react-app项目中挖掘精髓

                                                            閱讀時間:全文 2726 字,預估用時 14 分鐘
                                                            創作日期:2018-04-16
                                                            文章標籤:
                                                            上篇文章:面经收集
                                                             
                                                            BEGIN

                                                            前提说明

                                                            摆脱dva等框架因素, 学习React项目构建最好的方法就是跟着create-react-app项目走一遍.

                                                            ES6标准文档推荐:

                                                            创建项目

                                                            • 执行命令: npx create-react-app my-app

                                                            npx是npm@5.2后自带的命令, 简化npm执行一次性命令的复杂性, 一般要用依赖node的命令行工具都要安装在全局目录下, 有了npx可以 跳过安装操作直接执行命令, 更可以直接执行github dist的脚本文件, 挺实用的.

                                                            精髓目录

                                                            Updating to New Releases

                                                            这里对项目进行了介绍, create-react-app分为两块:

                                                            • create-react-app是命令行工具
                                                            • react-scripts是创建项目的配置与执行脚本

                                                            由于做到命令行工具与执行脚本的分离, 所有不用更新create-react-app, 而它下载的react-scripts总是最新的

                                                            Sending Feedback

                                                            项目反馈

                                                            Folder Structure

                                                            新建项目后的目录结构

                                                            .
                                                            ├── package.json
                                                            ├── public
                                                            │   ├── favicon.ico
                                                            │   ├── index.html                 # 页面模板
                                                            │   └── manifest.json
                                                            ├── README.md
                                                            ├── src
                                                            │   ├── App.css
                                                            │   ├── App.js
                                                            │   ├── App.test.js
                                                            │   ├── index.css
                                                            │   ├── index.js
                                                            │   ├── logo.svg
                                                            │   └── registerServiceWorker.js   # JavaScript代码的入口
                                                            └── yarn.lock

                                                            Available Scripts

                                                            在项目根目录可以执行的命令

                                                            • npm start: 启动开发环境
                                                            • npm test: 进行代码的单元测试
                                                            • npm run build: 构建与打包
                                                            • npm run eject: 使用Webpack和Babel替换react-scripts用于项目启动与构建, 操作不可逆

                                                            Supported Browsers

                                                            支持的浏览器, 查看react浏览器支持情况 🔗

                                                            Supported Language Features and Polyfills

                                                            支持的语言特性及Polyfill实现, Polyfill指用现有代码实现的未来语言特性

                                                            这个项目支持最新的语言标准ES6 🔗的语法, 同时支持:

                                                            更多对语言新特性的支持得看babel的实现, different proposal stages 🔗

                                                            部分polyfills 🔗说明, 可通过工具Babel REPL 🔗进行试验下转换:

                                                            Syntax Highlighting in the Editor

                                                            编辑器中代码高亮, vim用户不需要

                                                            Displaying Lint Output in the Editor

                                                            编辑器中eslint语法错误检查, vim用户不需要

                                                            Debugging in the Editor

                                                            编辑器中调试代码, vim用户不需要

                                                            Formatting Code Automatically

                                                            利用Prettier自动格式化JavaScript, CSS, JSON代码

                                                            应用于在每次git的commit时自动格式化代码:

                                                            yarn add husky lint-staged prettier

                                                            修改文件package.json

                                                              "scripts": {
                                                            +   "precommit": "lint-staged",
                                                                "start": "react-scripts start",
                                                                "build": "react-scripts build",
                                                              "dependencies": {
                                                                // ...
                                                              },
                                                            + "lint-staged": {
                                                            +   "src/**/*.{js,jsx,json,css}": [
                                                            +     "prettier --single-quote --write",
                                                            +     "git add"
                                                            +   ]
                                                            + },
                                                              "scripts": {

                                                            修改后在每次git提交代码的时候都会格式化代码, 或者手动执行./node_modules/.bin/prettier --single-quote --write "src/**/*.{js,jsx,json,css}"格式化指定目录, 应用于编辑器中 🔗

                                                            Changing the Page <title>

                                                            通过document.titleAPI修改网页标题.

                                                            Installing a Dependency

                                                            安装依赖: npm install --save react-routeryarn add react-router

                                                            Importing a Component

                                                            引入组件:

                                                            • ES5: require()module.exports
                                                            • ES6: importexport

                                                            关于import引入模块的介绍可以看ES6中模块引入与导出的使用场景 🔗

                                                            Code Splitting

                                                            代码可以进行切割分块, 然后通过import() 🔗动态导入, 并返回一个Promise对象, 示例:

                                                            // moduleA.js
                                                            const moduleA = 'Hello';
                                                            
                                                            export { moduleA };
                                                            // App.js
                                                            import React, { Component } from 'react';
                                                            
                                                            class App extends Component {
                                                              handleClick = () => {
                                                                import('./moduleA')
                                                                  .then(({ moduleA }) => {
                                                                    // Use moduleA
                                                                  })
                                                                  .catch(err => {
                                                                    // Handle failure
                                                                  });
                                                              };
                                                            
                                                              render() {
                                                                return (
                                                                  <div>
                                                                    <button onClick={this.handleClick}>Load</button>
                                                                  </div>
                                                                );
                                                              }
                                                            }
                                                            
                                                            export default App;

                                                            react官网示例及在react-route中使用Code-Splitting 🔗

                                                            Adding a Stylesheet

                                                            引入样式文件import './*.css';

                                                            Post-Processing CSS

                                                            如果css熟悉是浏览器专属属性, 则会自动给属性前面加浏览器前缀.

                                                            Adding a CSS Preprocessor (Sass, Less etc.)

                                                            添加css预处理器

                                                            Adding Images, Fonts, and Files

                                                            引入图片, 字体和文件import logo from './logo.png';

                                                            Using the public Folder

                                                            react-scripts@0.5.0和更高版本新建项目时会在根目录创建public文件夹, 用于放置静态文件.
                                                            Webpack将不能正确解析public下的文件, 通常用%PUBLIC_URL%process.env.PUBLIC_URL返回public目录的绝对路径.

                                                            教程中推荐使用import方式引入静态文件, 相对于标签形式引入, 可以减少请求次数, 避免找不到文件报404, 避免浏览器缓存文件.

                                                            Using Global Variables

                                                            当用window存放全局变量的时候, linter会发出变量未定义的警告, 此时可以向代码后面添加// eslint-disable-line让linter过滤当前行, 如: const $ = window.$; // eslint-disable-line

                                                            Adding Bootstrap

                                                            推荐使用蚂蚁金服出的React UI 框架 antd 🔗

                                                            Adding Flow

                                                            使用flow 🔗可以强制定义变量的类型, 通过以下方式配置:

                                                            1. 安装依赖: yarn add flow-bin
                                                            2. package.json的script字段加入"flow": "flow"
                                                            3. 初始化.flowconfig文件: yarn flow init
                                                            4. 在文件头部加入// @flow

                                                            示例: (arg: number): Array<number> => [arg, arg + 1], 定义传入的参数为数字类型, 并返回数组, 元素为数字类型.

                                                            Adding a Router

                                                            React没有指定路由功能用哪个模块实现, 但用的最多的还是React Router.

                                                            React Router 🔗, 点进去是个9分钟的视频, 英文的可能听不太懂, 看绝对看得懂代码, 可以看看国外开发大牛用vim写代码.

                                                            React Router的示例及api介绍 🔗

                                                            添加依赖: yarn add react-router-dom

                                                            Adding Custom Environment Variables

                                                            在项目中使用环境变量, 支持react-scripts@0.2.3或更高版本, React中统一标准变量名前加REACT_APP_前缀, 项目启动后环境变量放于process.env里面.

                                                            Referencing Environment Variables in the HTML

                                                            react-scripts@0.9.0及更高版本, 环境变量可以在public/index.html中使用, 如: <title>%REACT_APP_WEBSITE_NAME%</title>

                                                            Adding Temporary Environment Variables In Your Shell

                                                            在shell中定义环境变量后启动项目

                                                            Windows (cmd.exe)

                                                            set "REACT_APP_SECRET_CODE=abcdef" && npm start

                                                            Windows (Powershell)

                                                            ($env:REACT_APP_SECRET_CODE = "abcdef") -and (npm start)

                                                            Linux, macOS (Bash)

                                                            REACT_APP_SECRET_CODE=abcdef npm start

                                                            Adding Development Environment Variables In .env

                                                            react-scripts@0.5.0及更高版本支持在项目更目录下.env文件定义环境变量, 如.env文件中定义REACT_APP_SECRET_CODE=abcdef, 更改完后需要重新启动项目.

                                                            What other .env files can be used?

                                                            此特性应用于react-scripts@1.0.0及更高版本, 定义不同环境下的env文件:

                                                            • .env: 默认
                                                            • .env.local: 本地定义, 除test的所有环境
                                                            • .env.development, .env.test, .env.production: 分别定义各个环境下的env文件
                                                            • .env.development.local, .env.test.local, .env.production.local: 分别定义各个环境下的env本地文件

                                                            各个环境下文件读取优先级(高 -> 低):

                                                            • npm start: .env.development.local, .env.development, .env.local, .env
                                                            • npm run build: .env.production.local, .env.production, .env.local, .env
                                                            • npm test: .env.test.local, .env.test, .env (note .env.local 无效)

                                                            项目地址: dotenv 🔗

                                                            Expanding Environment Variables In .env

                                                            .env文件的扩展, 支持react-scripts@1.1.0及更高版本, 项目地址: dotenv-expand 🔗, 示例:

                                                            DOMAIN=www.example.com
                                                            REACT_APP_FOO=$DOMAIN/foo
                                                            REACT_APP_BAR=$DOMAIN/bar

                                                            Can I Use Decorators?

                                                            暂时不推荐使用装饰器, 但可能会在今后的稳定版本支持, 不支持原因有三:

                                                            1. 装饰器语法只是个提案.
                                                            2. 当前版本的Babel不支持.
                                                            3. facebook内部未使用该语法.

                                                            Fetching Data with AJAX Requests

                                                            教程中推荐使用axios 🔗fetch() 方法 🔗 发起AJAX请求, 全局变量window下的fetch方法是原生方法XMLHttpRequest的替代, 提供更利于使用的API, 请求返回Promise对象, 该Promise对象遵循 Promise/A+规范 🔗, fetch方法使用示例:

                                                            postData('http://example.com/answer', {answer: 42})
                                                              .then(data => console.log(data)) // 输出 `response.json()` 方法调用后返回的结果
                                                              .catch(error => console.error(error))
                                                            
                                                            function postData(url, data) {
                                                              // Default options are marked with *
                                                              return fetch(url, {
                                                                body: JSON.stringify(data), // 必须定义请求头的'Content-Type'类型
                                                                cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
                                                                credentials: 'same-origin', // include, same-origin, *omit
                                                                headers: {
                                                                  'user-agent': 'Mozilla/4.0 MDN Example', // 浏览器信息
                                                                  'content-type': 'application/json' // 请求体类型
                                                                },
                                                                method: 'POST', // *GET, POST, PUT, DELETE, etc.
                                                                mode: 'cors', // no-cors, cors, *same-origin
                                                                redirect: 'follow', // manual, *follow, error
                                                                referrer: 'no-referrer', // *client, no-referrer
                                                              })
                                                              .then(response => response.json()) // 提取返回体中的数据解析成JSON类型数据
                                                            }

                                                            Integrating with an API Backend

                                                            与后端API集成这个用处不大, 此处省略

                                                            Proxying API Requests in Development

                                                            此配置支持react-scripts@0.2.3或更高版本.

                                                            跨域请求(CORS)允许浏览器请求非js脚本json文件的资源, 浏览器在请求头中用Origin字段标明请求为跨域请求, 然后后端通过 Access-Control-Allow-Origin和Access-Control-Allow-Methods响应头返回验证结果, 对于js脚本的跨域请求jQuery时期用jsonp解决跨域问题, 不过在React中直接提供简单的配置实现跨域请求, 通过在package.json文件中添加"proxy": "http://localhost:4000"实现跨域请求, 且只能在npm start运行的开发模式中有效.

                                                            ”Invalid Host Header” Errors After Configuring Proxy

                                                            有可能命令行中报Invalid Host Header错误, 此时可以试试在.env.development文件中添加HOST=mypublicdevhost.com

                                                            Configuring the Proxy Manually

                                                            此特性支持react-scripts@1.0.0及更高版本. 手动配置代理的方式相对于标准配置方法更灵活, 在package.json文件中添加以下代码实现:

                                                            {
                                                              // ...
                                                              "proxy": {
                                                                // 匹配所有 /api 开头地址
                                                                "/api": {
                                                                  "target": "<url_1>",
                                                                  "ws": true
                                                                  // ...
                                                                },
                                                                // 匹配所有 /foo 开头地址, 并将 /foo 改写为 /foo/beta
                                                                "/foo": {
                                                                  "target": "<url_2>",
                                                                  "ssl": true,
                                                                  "pathRewrite": {
                                                                    "^/foo": "/foo/beta"
                                                                  }
                                                                  // ...
                                                                },
                                                                // 会匹配 /bar/abc.html 但不匹配 /bar/sub/def.html
                                                                "/bar/[^/]*[.]html": {
                                                                  "target": "<url_3>",
                                                                  // ...
                                                                },
                                                                // 会匹配 /baz/abc.html 和 /baz/sub/def.html
                                                                "/baz/.*/.*[.]html": {
                                                                  "target": "<url_4>"
                                                                  // ...
                                                                }
                                                              }
                                                              // ...
                                                            }

                                                            Configuring a WebSocket Proxy

                                                            比如做WebRTC项目时需要代理WebSocket请求, 可以在package.json文件中进行如下配置:

                                                            {
                                                              // ...
                                                              "proxy": {
                                                                "/socket": {
                                                                  // Your compatible WebSocket server
                                                                  "target": "ws://<socket_url>",
                                                                  // Tell http-proxy-middleware that this is a WebSocket proxy.
                                                                  // Also allows you to proxy WebSocket requests without an additional HTTP request
                                                                  // https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
                                                                  "ws": true
                                                                  // ...
                                                                }
                                                              }
                                                              // ...
                                                            }

                                                            Using HTTPS in Development

                                                            此特性支持react-scripts@1.0.0及更高版本, 在项目中使用HTTPS请求配置方式和一般代理HTTP请求一样, 不过需要定义环境变量, 定义如下开启开发环境支持HTTPS请求, 不过由于用的自签名证书, 通常每次打开网页都会有HTTPS页面不安全的警告.

                                                            Windows (cmd.exe)

                                                            set HTTPS=true&&npm start

                                                            Windows (Powershell)

                                                            ($env:HTTPS = $true) -and (npm start)

                                                            (Note: the lack of whitespace is intentional.)

                                                            Linux, macOS (Bash)

                                                            HTTPS=true npm start

                                                            未完

                                                            FINISH
                                                            上篇文章:面经收集

                                                            隨機文章
                                                            人生倒計時
                                                            default