基於 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

參考:

相關文章
相關標籤/搜索