美文网首页Reactreact
create-react-app全家桶router+mobx

create-react-app全家桶router+mobx

作者: cc_licc | 来源:发表于2018-07-02 16:14 被阅读2800次

    create-react-app 是一个搭建 react 项目的脚手架,该脚手架很好用,文档功能也很全,是上手 react 项目的不二首选,下面我们就来讲讲 reacte-react-app 创建的项目如何配置UI组件以及数据流

    使用 ceacte-react-app 初始化项目

    全局安装 create-react-app
    npm install -g create-react-app
    

    or

    yarn -g create-react-app
    
    新建一个项目
    create-react-app react-demo
    

    工具会帮你初始化一个简单基本的项目并且会自动帮你安装项目所需要的各种依赖,如果中途出现网络问题导致依赖安装不上,这时你可能需要配置代理或者设置其他的 npm 源。关于 npm 源镜像有很多选择,比如淘宝镜像等,这里不多做说明,网上有很多。

    进入项目并启动
    cd react-demo
    npm start
    

    or

    yarn start
    

    此时浏览器会自动访问 http://localhost:3000/,你会看到一个 react 的欢迎界面,如下:代表你的项目已经正常运行了

    欢迎.png

    但是:这仍然不够,这时你用代码编辑器打开项目会发现项目结构其实是这样的:

    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) 项目,这个一个不可逆过程,一旦你执行了,就不能回到初始化

    npm run eject
    

    再看项目结构,就会多了一些其他目录,如下:

    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 依赖
    npm install resolve-url-loader sass-loader node-sass --save
    
    修改 webpack配置文件

    找到 webpack.config.dev.jswebpack.config.prod.js 文件,后缀 dev 表示开发的配置,prod 表示是生产环境的配置,因此两个配置文件都需要修改。

    • 修改webpack.config.dev.js
      modulerules 字段中添加以下代码
    {
      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 字段中添加以下代码
    {
      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组件库,文档全,使用简单,组件也能满足基本的需求。官方文档也有具体的相关配置说明。

    安装组件
    npm install antd --save
    

    or

    yarn add antd
    
    按需加载

    使用 babel-plugin-import

    npm install babel-plugin-import --save
    
    修改 webpack 文件

    rules 中的 babel 规则中的 options 中添加以下代码

    plugins: [
       ['import', { libraryName: 'antd', style: true }],
    ],
    
    引入样式

    使用 less 加载

    npm install less@2.7.2 less-loader --save
    

    注意: less 版本不能高于 3.0.0 至于为什么,请原谅笔者也不知道,官方issue

    修改 webpack 文件

    {
      test: /\.less$/,
      use: [
        require.resolve('style-loader'),
        require.resolve('css-loader'),
        {
          loader: require.resolve('less-loader'),
          options: {
            modifyVars: { '@primary-color': '#1890ff' },
          },
        },
      ],
    },
    

    其中 @primary-color 表示主题色,官方也有推荐配置主题色的说明。

    在页面中使用组件
    import { Button } from 'antd';
    ...
    <div>
      <Button type="primary">button</Button>
    </div>
    ...
    

    此时页面上就会显示 Button 组件

    配置 eslint

    为了是代码保持统一风格,可以使用工具 eslit 来检查代码的规范性。笔者是使用 airbnb 的代码风格,当然你也可以自定义属于自己的code-style。

    安装需要的包
    npm install eslint-config-airbnb --save
    

    注意
    也许使用 create-react-app 初始化出来的项目,配置 eslint 以及安装了各种 eslint 依赖,这时启动项目发现报以下错误,那么你可能需要更改包的版本,笔者也是尝试了多次才成功的。

    eslint.png
    引入配置

    在项目的根目录下创建 .eslintrc 文件

    {
      "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 检查

    安装依赖

    npm install lint-staged husky --save
    

    修改 package.json 文件

    "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 来设置别名。

    • 修改 config 文件夹下的 paths 文件
    module.exports = {
      ...
      appSrc: resolveApp('src'),
      appStyles: resolveApp('src/styles'),
      appRoutes: resolveApp('src/routes'),
      appComponents: resolveApp('src/components'),
      appUtils: resolveApp('src/utils'),
      ...
    
    • 修改 webpack 配置项 alias
    alias: {
      styles: paths.appStyles,
      routes: paths.appRoutes,
      components: paths.appComponents,
      utils: paths.appUtils,
      ...
    
    安装路由组件 react-router
    npm install react-router react-router-dom --save
    
    • routes 文件夹中新建 index.jsx 页面,以及新建两个页面组件分别是 home.jsxabout.jsx
      index.jsx
    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

    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

    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
    
    • 修改 src 文件夹下的 index
    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 的数据状态管理,如 fluxreduxmobx 等等。下面我们就讲解项目如何配置 mobx

    安装依赖
    npm install mobx mobx-react --save
    
    修改文件
    • 新建文件夹 stores
      src 目录下新建一个文件夹 stores,创建 index.js 文件
    const store = {}
    
    export default store
    
    • 修改 webpack 文件
      webpack 文件中设置别名,方面引用,当然别忘了修改 paths 文件来设置路径
    alias: {
      styles: paths.appStyles,
      routes: paths.appRoutes,
      components: paths.appComponents,
      stores: appStores,
    ...
    
    • 修改入口文件
      修改 routes 下的 index.js
    ...
    import { Provider } from 'mobx-react'
    import stores from 'stores'
    ...
    const App = () => (
      <Provider {...stores}>
        <Routes />
      </Provider>
    )
    ...
    
    开始使用
    • 使用 mobx 你还需要安装 babel 的装饰器插件,以及修改 babel 的配置
    npm install babel-plugin-transform-decorators-legacy --save
    

    修改 package.json 文件中的 babel 参数,或者在根目录下新建一个 .babelrc 文件

    "babel": {
      "presets": [
        "react-app"
      ],
      "plugins": [
        "babel-plugin-transform-decorators-legacy"
      ]
    ...
    

    现在,你可以在你的组件中使用 mobx 来管理你的状态了。关于 mobx 的使用,你可以访问官方文档

    添加 mobx 开发工具
    • 安装依赖
    npm install mobx-react-devtools
    
    • 修改入口文件 routes 下的 index.js
    ...
    import DevTools from 'mobx-react-devtools'
    ....
    const App = () => (
      <Fragment>
        <Provider {...stores}>
          <Routes />
        </Provider>
        <DevTools />
      </Fragment>
    )
    

    当然,你也可以设置环境变量,只在开发中打开该工具

    {
      process.env.NODE_ENV === 'development' ? (
        <DevTools />
      ) : null
    }
    

    总结

    create-react-app 脚手架其实已经很完美了,一些列的打包编译优化也做了,使用 create-react-app 初始化的项目,只需要根据业务定制化的配置一些东西,这些都不难,网上有很多类似的案例,主要还是心细,多去专研。
    最后,附上本次项目的完整代码
    欢迎指出不足之处,如果您觉得不错,不要忘记star

    相关文章

      网友评论

        本文标题:create-react-app全家桶router+mobx

        本文链接:https://www.haomeiwen.com/subject/ylwoyftx.html