当前位置: 首页 > news >正文

Create React App 使用

作为大前端时代的页面仔, 工作至今, 在项目中一直使用的是 Vue, 很遗憾对 React 的了解仅限于几个版本之前官方文档与网上的教程。新春伊始,有幸在下一个项目中用到 React, 既是从零开始, 不妨写一点东西以记录学习的过程,这也是用了一上午搭建这个博客的初衷。首当其冲的是项目的搭建, 相信没有人会喜欢 webpack 繁琐的配置,因此这里学一下 Create React App(CRA) 的用法。

快速开始

根据官网上的介绍,只需下面两个命令,就能实现项目的基本搭建:

$ yarn global add create-react-app

$ create-react-app react-demo

生成的项目目录结构如下图所示 ?:

图片描述

和 Vue Cli 相比还是比较简陋的, Vue Cli 通过命令行选择是否使用 vuex 或 vue-router,CRA 貌似需要手动添加路由库与状态管理库,这也是可以理解的,毕竟 React 生态圈中类似路由与状态管理的库不止一家。

看了下 package.json 中的 scripts 命令,如下:

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

执行 start 命令会启动 webpack-dev-server 方便本地开发调试,build 命令对应打出生产环境的包。eject 命令作用是将 webpack 配置暴露出来, 默认利用 CRA 生成项目的一些 webpack 配置是不可覆盖的, 比如内置的环境变量 Process.env.NODE_ENV。 通过 eject 得到具体的 webpack 配置之后可以进行修改, 这里没有演示, 就是不想看到一堆 webpack 配置, 要的就是主流前端开发工具的开箱即用,而且 eject 执行之后是不可恢复的。

到这里就会有一个问题, 在使用 Vue Cli 时, build 命令提供了 mode 选项设置 process.evn.NODE_ENV 的值为 development 还是 production。遗憾的是, CRA 没有相似的选项。但是在实际开发中, 可能测试环境上上部署的代码需要开发环境下打包的代码以方便调试, 比如在测试环境上可以有 VConsole 和 SourceMap,但是在生产环境下就需要去掉。

那如何才能有开发环境的打包呢 ??

build 区分 development 和 production 模式

查阅文档发现, 为了达到区分生产环境构建和开发环境构建的目的, 可以通过自定义环境变量来实现, 参考 How can I create build for my dev server, 在项目文件夹下创建 .env.production 和 .env.development 文件。 分别设置 REACT_APP_ENV 为 production 和 development。 在package.json 中创建新的命令如下:

// yarn add dotenv-cli -D
"dev-build": "dotenv -e .env.development react-scripts build"

当使用 yarn start 和 yarn dev-build 命令时会加载 .env.development 文件。 当使用 yarn build 命令时,对应加载 .env.production 文件。因此可以在业务代码中可以通过使用 process.env.REACT_APP_ENV 来区分不同构建环境(实际 dev-build 打包还是生产环境的,仅用于业务代码区分 )。

Sass/Less 处理

文档中有提到如何添加 Sass, 并没有提到如何添加 Less,真是是逼死强迫症 ?。各种查找,发现了一个工具 react-app-rewired 可以很方便的覆盖 CRA 的 webpack 配置而不用执行 eject 命令。于是乎, 安装 react-app-rewired, 并将 package.json 中的命令修改如下:

  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "dev-build": "dotenv -e .env.development react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },

同时, 有 react-app-rewire-less 工具用来提供 Less 支持,瞬间人生充满希望,仿佛胜利近在咫尺。 撸起袖子,对照文档, 在项目根目录下添加 config-overrides.js 文件,内容如下:

  /* config-overrides.js */
  const rewireLess = require('react-app-rewire-less');
  
  module.exports = function override(config, env) {
    config = rewireLess(config, env);
    return config;
  };

执行 yarn start 查看效果:

图片描述

很遗憾报错了, 根据提示 getBbabelLoader 工具方法在 2.0 版本废弃, 可以使用 customize-cra 进行替代,于是安装 customize-cra。

修改 config-overrides.js 如下:

const { override, addLessLoader } = require('customize-cra');

module.exports = override(
    addLessLoader()
);

重新执行 yarn start,demo 能够正常运行了, 试了一下, 貌似还支持 css modules。 虽然有点曲折,终归是车到山前必有路。(其实心里已经喊了好多次mmp了, 整个 Less 还这么麻烦~ ?)

支持 Less 之后, 在项目中必不可少的就是 PostCSS了,还好这块文档中有提到。

PostCSS

CRA 内部已经使用了 Autoprefixer 添加浏览器前缀, 只需要在 package.json 中添加 browserslist 属行来定义支持的浏览器。

在开发 H5 app 的时候, 为了适配通常采用 rem 布局, 方便起见, 通常会用到 postcss-px2rem 这个工具, 如何在 CRA 中配置 px2rem 呢?

在上面折腾 customize-cra 的基础上,发现这个库中提供了 addPostcssPlugins 函数。

const {
  override,
  addPostcssPlugins
} = require("customize-cra");

module.exports = override(
  addPostcssPlugins([
    require('postcss-px2rem')({ remUnit: 37.5 })
  ]),
);

代码如上, 就可以开心的使用 px2rem 了。

路由解决方案 react-router

CRA 的文档中提到最受欢迎的路由解决方案是 react-router。 命令如下

$ yarn add react-router-dom

所以 react-router-dom 是什么鬼? 参见react-router和react-router-dom的区别

react-router 实现了路由的核心功能, react-router-dom 基于 react-router, 加入了在浏览器环境下的一些功能。

react-router 4.x 相较于之前的版本有着较大的变化,不过还好,对于我这种初学者来说都一样。

状态管理方案 redux or mobx

提到 React 的状态管理, 像我这样的小白, 瞬间想到的就是 Redux,但是作为初学者在没有仔细看 redux 教程时, 对一些术语, 比如 actions、reducers、middleware等感到头疼。 搜了一下社区其他的状态管理方案,看到 mobx这个库,打算对比一下学习, 挑一个用在项目中踩坑。

代码拆分(路由懒加载)

参考 React.lazy 以及 React.Suspense

写在最后

折腾一番,到这里项目结构基本上已经搭建了, 后续关于 CRA 的问题,遇到之后,再进行补充 ?。

相关文章:

  • 演练5-5:Contoso大学校园管理系统5
  • [USACO12DEC]逃跑的BarnRunning Away From…
  • SpiderData 2019年2月13日 DApp数据排行榜
  • css按钮渐变色
  • 如何胜任知名企业的商业数据分析师?
  • 网站优化技术
  • AI和ML自动化测试是骗人的营销手段吗?
  • C# U盘扫描
  • 工欲善其事必先利其器之8266
  • 2019年面对全新的DDoS功击企业需做好哪些防护措施?
  • GCD1:构建Block Objects
  • SQL 难点解决:记录的引用
  • 百度PaddlePaddle再获新技能 智能推荐、对话系统、控制领域都能搞定!
  • SSL工作原理
  • Prometheus+Grafana+kafka_exporter搭建监控系统监控kafka
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • Android单元测试 - 几个重要问题
  • Angular 响应式表单之下拉框
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • C学习-枚举(九)
  • flutter的key在widget list的作用以及必要性
  • Git同步原始仓库到Fork仓库中
  • mysql 5.6 原生Online DDL解析
  • PHP 小技巧
  • Redis 懒删除(lazy free)简史
  • socket.io+express实现聊天室的思考(三)
  • SOFAMosn配置模型
  • SpingCloudBus整合RabbitMQ
  • Webpack 4 学习01(基础配置)
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 记一次用 NodeJs 实现模拟登录的思路
  • 老板让我十分钟上手nx-admin
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 前端知识点整理(待续)
  • 为什么要用IPython/Jupyter?
  • 新书推荐|Windows黑客编程技术详解
  • 一个SAP顾问在美国的这些年
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​第20课 在Android Native开发中加入新的C++类
  • #pragma once与条件编译
  • (02)Hive SQL编译成MapReduce任务的过程
  • (2)STL算法之元素计数
  • (9)STL算法之逆转旋转
  • (C语言)fgets与fputs函数详解
  • (java)关于Thread的挂起和恢复
  • (动态规划)5. 最长回文子串 java解决
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (四) 虚拟摄像头vivi体验
  • (转)http-server应用
  • (转)linux下的时间函数使用
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转)scrum常见工具列表
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • .htaccess 强制https 单独排除某个目录