概览
目前社区上主流的 React 应用初始化工具为 create-react-app,所以我们也是基于其来创建我们的 React 应用。
初始化项目
我们推荐使用 TypeScript,所以可以参照 Adding TypeScript 中的的命令初始化项目:
yarn create react-app --template typescript
增加 Prettier 的支持
我们推荐使用 Prettier 对提交的源码进行格式化,所以我们可以按照 Install 教程来使用它。
1. 安装 Prettier
首先需要通过以下的命令安装 Prettier:
yarn add --dev --exact prettier
接着我们需要在项目根目录下创建 .prettierrc
文件,并将以下内容写入:
{
"tabWidth"``: 2,
"printWidth"``: 80,
"trailingComma"``: ``"none"``,
"singleQuote"``: ``true``,
"jsxBracketSameLine"``: ``false
}
因为项目中可能存在着一些不需要被格式化的文件,所以我们需要在项目根目录下创建 .prettierignore
文件来记录这些不需要被格式化的文件:
# Ignore artifacts:
build
coverage
2. 提交前的钩子
在之前的步骤中,我们已经为项目安装了 Prettier,接着我们需要为项目增加提交前的格式化的钩子,我们依然可以参照 Pre-commit Hook 教程来添加钩子(这边选用 Option 2. pretty-quick 进行介绍)。
首先,我们需要安装 pretty-quick 与 husky。
yarn add --dev pretty-quick husky
然后我们需要往 package.json
的末尾塞入这么一段 JSON:
{
"husky"``: {
"hooks"``: {
"pre-commit"``: ``"pretty-quick --staged"
}
}
}
配置 TypeScript
每次启动项目 create-react-app 都会检查 tsconfig.json 配置是,我们需要通过 extends 配置进行定制,否则配置将会被 create-react-app 覆盖。
首先,我们在 tsconfig.json 配置中增加 extends 配置:
{
"extends"``: ``"./tsconfig.paths.json"
}
紧接着我们在项目根目录下创建 tsconfig.paths.json
文件,并填充如下的内容:
{
"compilerOptions"``: {
"baseUrl"``: ``"."``,
"paths"``: {
"@/*"``: [``"src/*"``]
}
}
}
这样,我们就可以令 TypeScript 能够识别 @
别名了。
自定义配置
默认情况下,create-react-app 不能够自定义配置,我们选用了社区的 react-app-rewired 自定义配置方案对原有的配置进行扩展。
首先,我们需要安装 react-app-rewired 以及 customize-cra
yarn add --dev react-app-rewired customize-cra
安装完毕之后,我们需要对 **package.json**
的 **scripts**
进行修改:
{
"scripts"``: {
"start"``: ``"react-app-rewired start"``,
"build"``: ``"react-app-rewired build"``,
"test"``: ``"react-app-rewired test"
}
}
接着我们需要在项目根目录创建 config-overrides.js
配置文件,用于修改默认的配置。
module.exports = ``function
override(config, env) {
// do stuff with the webpack config...
return
config;
};
将 moment 替换成 dayjs
moment 是一个优秀的日期库,它的历史非常悠久,我们使用它的时候往往忽略了它的大小,现在社区流行的做法就是在打包的时候将其替换成 dayjs。
首先,我们需要安装 dayjs
yarn add dayjs
接着,我们需要安装 antd-dayjs-webpack-plugin
yarn add --dev antd-dayjs-webpack-plugin
最后,我们需要修改 config-overrides.js
配置文件,增加对 antd-dayjs-webpack-plugin 的支持。
const AntdDayjsWebpackPlugin = require(``'antd-dayjs-webpack-plugin'``);
const { addWebpackPlugin, override } = require(``'customize-cra'``);
module.exports = override(
addWebpackPlugin(``new
AntdDayjsWebpackPlugin())
);
增加 @ 别名的支持
我们在之前的 TypeScript 配置中,增加了 TypeScript 中对 @
别名的解析,但是!实际上我们并不会在 webpack 中有任何的卵用。所以我们需要令 webpack 增加对该别名的支持:
const { addWebpackAlias, override } = require(``'customize-cra'``);
const path = require(``'path'``);
module.exports = override(
addWebpackAlias({
[``'@'``]: path.resolve(__dirname, ``'./src'``)
})
);
为 CSS Modules 增加 camelCase 变量名
默认情况下,CSS Modules 生成的字典中是根据样式的原始名称,举个例子,写的样式如果是 .foo-bar
,生成的字典将会是 { 'foo-bar': 'xxx' }
,这对我们的开发是比较不方便的。
所以,我们需要将要支持生成的字典的键全都为小驼峰的格式。
首先,需要安装 [customize-cra-util](https://github.com/PeckZeg/customize-cra-util)
yarn add --dev customize-cra-util
然后,我们在config-overrides.js
中增加配置
const { addCssModulesCamelCase } = require(``'customize-cra-util'``);
const { override } = require(``'customize-cra'``);
module.exports = override(
addCssModulesCamelCase()
);
为应用注入标题
create-react-app 默认的应用标题是 React App,这个可能和我们在 .env 配置文件中定义的 REACT_APP_TITLE
常量有出入,所以我们期望模板中能够配置标题。
为了达到我们的目标,我写了一个工具 customize-cra-util 用来解决当前的问题。
首先,需要安装 customize-cra-util
yarn add --dev customize-cra-util
接着,我们在项目根目录下新建 .env
文件,并在文件中增加下面的内容
# 应用名称
REACT_APP_TITLE=React App
然后,我们在**config-overrides.js**
中增加配置
const { addDocumentTitle } = require(``'customize-cra-util'``);
const env = require(``'react-scripts/config/env'``)().raw;
const { override } = require(``'customize-cra'``);
module.exports = override(
addDocumentTitle(env.REACT_APP_TITLE)
);
最后,我们需要修改 public/index.html
,将标题注入到模板中
<!DOCTYPE html>
<``html
lang``=``"en"``>
<``head``>
<``title``><%= htmlWebpackPlugin.options.title %></``title``>
</``head``>
</``html``>
区分环境
在大部分情况下,我们构建的 React 应用是区分环境的,所以我们约定了 REACT_APP_ENV
常量来指代当前应用的环境。
下面是 REACT_APP_ENV
值和其所代表环境的参考
REACT_APP_ENV |
应用环境 |
---|---|
development , 空值 |
开发环境 |
pre |
预发环境 |
beta |
测试环境 |
release |
线上环境 |
所以,我们可以对上面的配置进行修改,令其在标题之后加上环境信息
const { addDocumentTitle } = require(``'customize-cra-util'``);
const env = require(``'react-scripts/config/env'``)().raw;
const { override } = require(``'customize-cra'``);
module.exports = override(
addDocumentTitle(
(() => {
const envNames = {
pre: ``'预发环境'``,
beta: ``'测试环境'``,
development: ``'开发环境'
};
const { REACT_APP_TITLE: title, REACT_APP_ENV: appEnv } = env;
const appEnvName = envNames[appEnv || ``'development'``];
return
appEnvName ?
title (${appEnvName}): title;
})()
)
);
增加对 Lodash 的支持
lodash 是一个优秀的工具库,我们一般都会在项目中使用它。但是 lodash 是一个 CommonJS 的库,其对 webpack 构建工具来说,不能够非常友好的进行 Tree Shaking.所以,我们需要引入 babel-plugin-lodash 插件来优化这个打包过程。
首先,我们先安装 lodash:
yarn add lodash @types``/lodash
接着,我们还需要安装 babel-plugin-lodash
yarn add --dev babel-plugin-lodash
最后,我们需要在 config-overrides.js
中增加配置
const { addBabelPlugin, override } = require(``'customize-cra'``);
module.exports = override(
addBabelPlugin(``'lodash'``)
);
增加对 antd 的支持
antd 是一个优秀的中后台基础组件库,要在项目中支持它也是非常简单的。
首先,我们需要安装它
yarn add antd
因为 antd 使用 less 作为样式的预加载器,所以我们应当添加 less 的支持
less-loader 需要指定为 ^7.3.0
的版本(因为 customize-cra 的 addLessLoader
还未对最新版本的 less-loader 进行支持)
yarn add --dev ``less
less``-loader@^7.3.0
然后,我们在config-overrides.js
中增加配置
const { addLessLoader, override } = require(``'customize-cra'``);
module.exports = override(
addLessLoader({
lessOptions: {
javascriptEnabled: ``true``,
localIdentName: ``'[local]_[hash:base64:8]'``,
noIeCompat: ``true``,
modifyVars: {
'@primary-color'``: ``'#7955ff'
}
}
})
);
最后,我们需要利用 babel-plugin-import 来按需加载组件和样式
yarn add --dev babel-plugin-``import
在 config-overrides.js
中增加配置
const { fixBabelImports, override } = require(``'customize-cra'``);
module.exports = override(
fixBabelImports(``'import'``, {
libraryName: ``'antd'``,
libraryDirectory: ``'es'``,
style: ``true
})
);
应用体积分析
我们在构建应用的时候,有时候会关注整个应用的体积,所以在项目中增加包分析工具是非常有必要的。
我们通过 create-react-app 中的 Analyzing the Bundle Size 教程,可以很好的对应用体积进行分析。
首先,我们需要安装 source-map-explorer
yarn add --dev ``source``-map-explorer
{
"scripts"``: {
"analyze"``: ``"source-map-explorer 'build/static/js/*.js'"
}
}
接着,我们可以通过先后执行以下的命令来对应用的体积进行分析了
yarn build
yarn analyze