基于 NPM 的大型 React 单页应用探索(多场景多方案)

基于 NPM 的大型 React 单页应用探索(多场景多方案)

原文地址:https://github.com/luqin/blog/issues/10javascript

未完待续……php

本文目标构建基于 NPM 的大型 React 单页应用(以及多页面),支持多模块协同开发、分布式构建与发布。css

  • Reacthtml

  • React Routerjava

  • Redux...react

  • webpackwebpack

  • ES2015+/JSX with babelgit

JavaScript 规划

首先初始化顶层目录结构:github

app/
config/
package.json
README.md
... and tons of project .dotfiles and tool files ...

按文件类型组织 File-Type First (FTF)

app/
  reducers/
    root.js
    memberships.js
  components/
    home.jsx
    memberships.jsx
  ... of course more type folders/ ...

按功能组织 Feature First (Pods)

app/
  authentication/
    api/
    components/
    helpers/
    ...
  comments/
    actions/
    api/
    components/
    reducers/
    stores/
    ...
  ...

能够像这样按功能分组:web

app/
  settings/
    profile/
    notifications/
  ...

那么通用文件如何放置呢?一个方案是将他们放入框架文件夹:

app/
  flux/
    apiUtils.js
    baseActions.js
    baseStore.js
    connectToStores.js

多 App 模式 Multiple Apps

app/
  kapost.jsx
  studio/
    studioEntry.jsx
    content/
    ...
  gallery/
    galleryEntry.jsx
    collections/
    ...
  insights/
    insightsEntry.jsx
    content-scoring/
    ...
  members/
    membersEntry.jsx
    profile/
    ...

依然有不少通用代码,能够放入通用文件夹:

app/
  ...
  shared/
    users/
    ui/
      dropdowns/
      ...
    ...

到目前为止,按功能组织模式仍然能够 hold 住,咱们能够在每一个 App 使用按文件类型组织模式,可是依然有缺点,仅仅适合单 App 模式。

面对疯狂增加的 routes 或者 reducers,还有一种优雅的方式是使用代码分包(code-splitting),例如动态加载 React Router动态增长 Redux reducers,那么咱们如何组织这些文件呢?咱们能够定义一个顶级文件夹 boot/,一个项目文件夹例如 kapost/

app/
  kapost/
    routes.jsx (holds and rolls up all other app routes dynamically)
    reducer.js (holds all reducers dynamically)
  studio/
    studioEntry.jsx
    app/
      routes.jsx (rolls up all application routes)
      reducers.jsx (rolls up all studio reducers across all the feature folders)
    ...
  ...

……

Application Organization

API

同构 Universal Rendering

Domains and Authentication

App Configuration

Assets

Styles

CSS 方案:

  • SASS

  • LESS

  • Inline Style

  • PostCSS

  • CSS Modules

构建工具:

本文基于 SASS 实现模块化方案。

Without webpack and inlining

每一个项目的样式文件目录:

studio/
  app/
  config/
  stylesheets/
  spec/
  package.json
  ...

每一个样式文件经过命名空间来实现模块化,根据组件肯定前缀:

studio/
  app/
    comments/
      commentEntry.jsx
  stylesheets/
    comments/
      _commentEntry.scss
// _commentEntry.scss
.studio-comment-entry-component {
  // my name-spaced styles
}


// commentEntry.jsx#render
render() {
  <div className="studio-comment-entry-component">...</div>
}

共享的样式能够放入 shared/ 目录,全局样式能够放入相似 stylesheets/app/ 的目录(使用命名空间)。

每一个 app 都负责引入全部功能模块的样式文件,顶层 app 负责引入全部子 app 的样式文件。若是分离一些 apps 到分离的代码仓库,能够共享相同的构建流程,只须要维护相同的构建配置。

With webpack and inlining

studio/
  app/
    comments/
      styles/
        individualComponentStylesheet.scss
      ...

Why You Shouldn’t Style React Components With JavaScript

Testing

studio/
  app/
    comments/
      components/
      commentsContainer.jsx
      specs/
        components/ (unit tests of sorts)
        integration/ (testing entire comment feature)
        commentsContainerSpec.jsx (container could even be the main integration test)
        ...
      ...

基于 NPM 的协同开发方案

私有 NPM 方案:

  1. 官方私有 NPM

  2. 搭建私有 NPM 仓库

NPM 分包:

@kapost/app
@kapost/studio
@kapost/gallery
@kapost/insights
...
module/
  ...
  assets
  dist
  js
  scss
  test
  tools
  routes.jsx
  package.json

……

分布式编译

  • gulp + webpack + babel

  • gulp + System.js + babel

参考:

相关文章
相关标签/搜索