create-react-app
是一个搭建 react
项目的脚手架,该脚手架很好用,文档功能也很全,是上手 react
项目的不二首选,下面我们就来讲讲 reacte-react-app
创建的项目如何配置UI组件以及数据流
使用 ceacte-react-app
初始化项目
全局安装 create-react-app
1
| npm install -g create-react-app
|
or
1
| yarn -g create-react-app
|
新建一个项目
1
| create-react-app react-demo
|
工具会帮你初始化一个简单基本的项目并且会自动帮你安装项目所需要的各种依赖,如果中途出现网络问题导致依赖安装不上,这时你可能需要配置代理或者设置其他的 npm
源。关于 npm
源镜像有很多选择,比如淘宝镜像等,这里不多做说明,网上有很多。
进入项目并启动
or
此时浏览器会自动访问 http://localhost:3000/, 你会看到一个 react
的欢迎界面,如下:代表你的项目已经正常运行了
但是:这仍然不够,这时你用代码编辑器打开项目会发现项目结构其实是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| react-demo/ README.md node_modules/ package.json public/ index.html favicon.ico src/ App.css App.js App.test.js index.css index.js logo.svg
|
找不到 webpack
的配置项,此时你需要展开 (eject
) 项目,这个一个不可逆过程,一旦你执行了,就不能回到初始化
再看项目结构,就会多了一些其他目录,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| react-demo/ README.md config/ jest/ env.js paths.js polyfills.js webpack.config.dev.js webpack.config.prod.js webpackDevServer.config.js node_modules/ package.json public/ index.html favicon.ico scripts/ build.js start.js test.js src/ App.css App.js App.test.js index.css index.js logo.svg registerServiceWorker.js
|
展开 config
目录,里面就有 webpack
配置文件,还有一些环境、兼容、测试等的配置。而 scripts
目录里主要就是测试、启动、打包的脚本,这里不做过多描述,(其实笔者也没认真看过里面的代码),如果要详细研究,create-react-app
的官方文档有详细的讲解。
好了,现在 react
项目已经跑起来了,也找到 webpack
配置,可以做一些自定义的配置,接下来我们就讲一将,如何配置数据流以及UI库。
sass
的配置
安装 loader
依赖
1
| npm install resolve-url-loader sass-loader node-sass --save
|
修改 webpack
配置文件
找到 webpack.config.dev.js
与 webpack.config.prod.js
文件,后缀 dev
表示开发的配置,prod
表示是生产环境的配置,因此两个配置文件都需要修改。
在 module
的 rules
字段中添加以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| { test: /\.scss$/, use: [ require.resolve('style-loader'), { loader: require.resolve('css-loader'), // translates CSS into CommonJS options: { sourceMap: true, importLoaders: 3, }, }, require.resolve('resolve-url-loader'), // resolves relative paths in url() statements based on the original source file { loader: require.resolve('postcss-loader'), options: { ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options plugins: () => [ require('postcss-flexbugs-fixes'), autoprefixer({ flexbox: 'no-2009', }), ], }, }, { loader: require.resolve('sass-loader'), // compiles Sass to CSS, options: { includePaths: [`${paths.appNodeModules}/normalize-scss/sass`], }, }, ], },
|
这时修改 .css
样式文件为 .scss
并用 sass
语法修改样式,会发现页面生效了,别忘了修改在组件中引用样式的后缀。
当然,这只是修改了开发环境的配置,还需要修改生产环境
修改webpack.config.prod.js
同样在 rules
字段中添加以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| { test : /\.scss$/, use : ExtractTextPlugin.extract( Object.assign( { fallback: require.resolve('style-loader'), use: [ { loader: require.resolve('css-loader'), // translates CSS into CommonJS options: { sourceMap : true, minimize : true, importLoaders : 3, }, }, require.resolve('resolve-url-loader'), // resolves relative paths in url() statements based on the original source file { loader: require.resolve('postcss-loader'), options: { ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options plugins: () => [ require('postcss-flexbugs-fixes'), autoprefixer({ flexbox: 'no-2009', }), ], }, },
{ loader: require.resolve('sass-loader'), // compiles Sass to CSS, options: { includePaths: [`${paths.appNodeModules}/normalize-scss/sass`], }, }, ] }, extractTextPluginOptions ) ), },
|
引入UI库
笔者使用的是蚂蚁金服的 antd
UI组件库,文档全,使用简单,组件也能满足基本的需求。官方文档也有具体的相关配置说明。
安装组件
or
按需加载
使用 babel-plugin-import
1
| npm install babel-plugin-import --save
|
修改 webpack
文件
在 rules
中的 babel
规则中的 options
中添加以下代码
1 2 3
| plugins: [ ['import', { libraryName: 'antd', style: true }], ],
|
引入样式
使用 less
加载
1
| npm install less@2.7.2 less-loader --save
|
注意: less
版本不能高于 3.0.0
至于为什么,请原谅笔者也不知道,官方issue
修改 webpack
文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| { test: /\.less$/, use: [ require.resolve('style-loader'), require.resolve('css-loader'), { loader: require.resolve('less-loader'), options: { modifyVars: { '@primary-color': '#1890ff' }, }, }, ], },
|
其中 @primary-color
表示主题色,官方也有推荐配置主题色的说明。
在页面中使用组件
1 2 3 4 5 6
| import { Button } from 'antd'; ... <div> <Button type="primary">button</Button> </div> ...
|
此时页面上就会显示 Button
组件
配置 eslint
为了是代码保持统一风格,可以使用工具 eslit
来检查代码的规范性。笔者是使用 airbnb
的代码风格,当然你也可以自定义属于自己的code-style。
安装需要的包
1
| npm install eslint-config-airbnb --save
|
注意:
也许使用 create-react-app
初始化出来的项目,配置 eslint
以及安装了各种 eslint
依赖,这时启动项目发现报以下错误,那么你可能需要更改包的版本,笔者也是尝试了多次才成功的。
引入配置
在项目的根目录下创建 .eslintrc
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { "env": { "browser": true, "jest": true, "es6": true, "node": true }, "parser": "babel-eslint", "plugins": [ "react", "import" ], "extends": "airbnb", "rules": {} }
|
其中 rules
可以覆盖 airbnb
的规则,关于如何编写 eslint
规则可以查询 eslint
官方文档
也可以在根目录下创建 .eslintignore
来对某些文件不做 eslint
校验
commit
代码时使用 eslint
检查
安装依赖
1
| npm install lint-staged husky --save
|
修改 package.json
文件
1 2 3 4 5 6 7 8 9 10 11
| "scripts": { "precommit": "lint-staged", "start": "react-scripts start", "build": "react-scripts build", ... "lint-staged": { "src/**/*.{js,jsx}": [ "eslint --fix", "git add" ] }
|
引入路由系统
设置文件别名
现在,我们需要更改 src
目录的文件结构,以便于更符合实际项目场景,我们可能需要 components
文件夹来存放组件,routes
文件夹来存放页面,styles
文件夹来存放样式,utils
文件夹来存放工具类函数等。
既然有了文件夹来区分不同的功能,为了方便文件的相互,我们可以利用 webpack
来设置别名。
1 2 3 4 5 6 7 8
| module.exports = { ... appSrc: resolveApp('src'), appStyles: resolveApp('src/styles'), appRoutes: resolveApp('src/routes'), appComponents: resolveApp('src/components'), appUtils: resolveApp('src/utils'), ...
|
1 2 3 4 5 6
| alias: { styles: paths.appStyles, routes: paths.appRoutes, components: paths.appComponents, utils: paths.appUtils, ...
|
安装路由组件 react-router
1
| npm install react-router react-router-dom --save
|
- 在
routes
文件夹中新建 index.jsx
页面,以及新建两个页面组件分别是 home.jsx
和 about.jsx
index.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import React from 'react' import { Route, Redirect } from 'react-router' import { HashRouter, Switch } from 'react-router-dom'
import Home from 'routes/home' import About from 'routes/about'
const Routes = () => ( <HashRouter> <div> <Route exact path="/" render={() => <Redirect to="/home" />} /> <Switch> <Route path="/home" component={Home} /> <Route path="/about" component={About} /> </Switch> </div> </HashRouter> )
const App = () => ( <Routes /> )
export default App
|
about.jsx
1 2 3 4 5 6 7 8 9 10 11
| import React from 'react' import { Link } from 'react-router-dom'
const About = () => ( <div> <p>this is about page</p> <Link to="/home">goto Home</Link> </div> )
export default About
|
home.jsx
1 2 3 4 5 6 7 8 9 10 11
| import React from 'react' import { Link } from 'react-router-dom'
const Home = () => ( <div> <p>this is home page</p> <Link to="/about">goto About</Link> </div> )
export default Home
|
1 2 3 4 5 6
| import React from 'react' import ReactDOM from 'react-dom' import App from 'routes/index' import registerServiceWorker from './registerServiceWorker'
ReactDOM.render(<App />, document.getElementById('root'))
|
添加数据状态管理
react
本身就有自己的状态管理 state
,但随着项目的复杂性页面的增多其维护性不是那么友好,于是出现了针对 react
的数据状态管理,如 flux
、redux
、mobx
等等。下面我们就讲解项目如何配置 mobx
。
安装依赖
1
| npm install mobx mobx-react --save
|
修改文件
1 2 3
| const store = {}
export default store
|
1 2 3 4 5 6
| alias: { styles: paths.appStyles, routes: paths.appRoutes, components: paths.appComponents, stores: appStores, ...
|
修改入口文件
修改 routes
下的 index.js
1 2 3 4 5 6 7 8 9 10
| ... import { Provider } from 'mobx-react' import stores from 'stores' ... const App = () => ( <Provider {...stores}> <Routes /> </Provider> ) ...
|
开始使用
- 使用
mobx
你还需要安装 babel
的装饰器插件,以及修改 babel
的配置
1
| npm install babel-plugin-transform-decorators-legacy --save
|
修改 package.json
文件中的 babel
参数,或者在根目录下新建一个 .babelrc
文件
1 2 3 4 5 6 7 8
| "babel": { "presets": [ "react-app" ], "plugins": [ "babel-plugin-transform-decorators-legacy" ] ...
|
现在,你可以在你的组件中使用 mobx
来管理你的状态了。关于 mobx
的使用,你可以访问官方文档
添加 mobx
开发工具
1
| npm install mobx-react-devtools
|
- 修改入口文件
routes
下的 index.js
1 2 3 4 5 6 7 8 9 10 11
| ... import DevTools from 'mobx-react-devtools' .... const App = () => ( <Fragment> <Provider {...stores}> <Routes /> </Provider> <DevTools /> </Fragment> )
|
当然,你也可以设置环境变量,只在开发中打开该工具
1 2 3 4 5
| { process.env.NODE_ENV === 'development' ? ( <DevTools /> ) : null }
|
总结
create-react-app
脚手架其实已经很完美了,一些列的打包编译优化也做了,使用 create-react-app
初始化的项目,只需要根据业务定制化的配置一些东西,这些都不难,网上有很多类似的案例,主要还是心细,多去专研。
最后,附上本次项目的完整代码
欢迎指出不足之处,如果您觉得不错,不要忘记star哟