基于 NPM 的大型 React 单页应用探索(多场景多方案)
基于 NPM 的大型 React 单页应用探索(多场景多方案)
未完待续……
本文目标构建基于 NPM 的大型 React 单页应用(以及多页面),支持多模块协同开发、分布式构建与发布。
- React
- React Router
- Redux...
- webpack
- ES2015+/JSX with babel
JavaScript 规划
首先初始化顶层目录结构:
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/
...
...
可以像这样按功能分组:
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
- relative paths in Node
- Backend Apps with Webpack (Part I)
- Backend Apps with Webpack: Driving with Gulp (Part II)
- Live Editing JavaScript with Webpack (Part III)
- react-redux-universal-hot-example
Domains and Authentication
- JSON Web Tokens
- Secure cookies over HTTPS (under one primary domain name)
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 方案:
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
参考:
Nice sharing
@AllenFang Thank you。先整理下资料,后续会整理出基于 npm 的多模块多项目开发协作流程及工具。
:+1:
@AllenFang 推荐你看看上面的两篇参考文章
Readed, Good articles :)