@plume/app
v0.1.14
Published
About the configuration and construction of webApp
Downloads
9
Readme
app
TODO: description
entry
plume 可以手动指定项目入口文件,在plume.config.js
内配置options.entry
选项,指定入口文件的位置。
当手动指定 entry 时:
- 需要手动引入
{plume}/App.jsx
文件 - 需要手动引入 React,ReactDOM
- 需要手动渲染 App
- 需要手动指定渲染的目标元素
import App from ".plume/App.jsx";
import ReactDOM from "react-dom";
ReactDOM.render(<App />, document.getElementById("root"));
router
- plume 根据
pages
目录下的文件夹划分页面,pages 目录下的每一个文件夹当作一个页面来看待,需要index.jsx
作为页面入口。 - 子文件夹和文件夹下
.js|.jsx
文件也会作为一个页面来看待,路由为此文件或文件夹在pages
目录的相对位置。 - 默认
Home
页为入口也,路由体现为/
- 其他页面的路由为其页面文件夹的名称的英文小写,例如
About
页面的路由为/about
- 暂不支持嵌套路由
- 支持多层路由
例如:
假设/pages目录为`pages`目录
则:
目录/pages/Home/index.jsx 生成的路由为 ==> /
目录/pages/About/index.jsx 生成的路由为 ==> /about
目录/pages/About/withMe.jsx 生成的路由为 ==> /about/withme
目录/pages/About/otherAbout/index.jsx 生成的路由为 ==> /about/otherabout
plume 的典型的目录结构为:
├── .babelrc
├── .gitignore
├── .plume
│ ├── 404.jsx
│ ├── App.jsx
│ ├── Router.jsx
│ ├── index.jsx
│ └── pagesInfo.json
├── package.json
├── plume.config.js
├── src
│ ├── components
│ └── pages
│ ├── About
│ │ └── index.jsx
│ ├── Home
│ │ └── index.jsx
│ └── Product
│ ├── Product_1
│ │ └── index.jsx
│ └── index.jsx
└── yarn.lock
则会自动创建如下 router
/ # Home
/about # About
/product # Product
/product/product_1 # Product/Product_1
打包时,为每一个页面单独打包需要的资源文件。
dynamic router
在文件或目录名称前加上$
表示动态路由
例如:
├ pages
└── Dynamic
├── $id.jsx
└── index.jsx
则会生成
/dynamic
/dynamic/:id
这样的动态路由
嵌套路由
在{pages}
下的每个目录或js|jsx
文件(除了 index 文件)会被当作一个页面,所以可以在页面目录下嵌套其他目录,实现路由嵌套
例如:
{pages}
├─ Post
├─ P1
├─ P2
则会生成:
[
{
"path": "/Post",
"component": "{pages}/Post/index.jsx"
},
{
"path": "/Post/P1",
"component": "{pages}/Post/P1/index.jsx"
},
{
"path": "/Post/P2",
"component": "{pages}/Post/P2/index.jsx"
}
]
的结构,访问不同的地址,则会跳转到相应页面
@plume/flow && models
- 创建 models 的时候,会搜索当前项目下所有
models
目录,目录内的每个*.js
文件作为一个 model,所以 models 目录下每个 js 文件务必有默认输出export defaut
。支持嵌套 models 目录。默认忽略node_modules
和.plume
目录。 - 每个 model 的
namespace
必须是唯一的
可以使用其他数据流工具,如redux-saga
,必须使用自定义的entry
入口文件。
使用 saga 的例子:
import App from ".plume/App.jsx";
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import createSagaMiddleware from "redux-saga";
import { helloSaga } from "./sagas";
const sagaMiddleware = createSagaMiddleware();
const store = createStore(reducer, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(helloSaga);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root"),
);
404 页面
有默认的 404 页面,也可以自定义
自定义的 404 页面放置在{pages}/404
目录下,当检测到{pages}/404
目录存在时,将使用自定义的 404 页面
静态资源
使用了file-loader
来管理静态资源,默认输出文件夹{output}/assets
,默认识别后缀为["jpg", "gif", "png", "ttf", "woff", "eot", "svg", "otf"]的静态资源。
使用静态资源:
import React from "react";
import icon from "../icon.png";
export default () => {
return (
<div>
Home
<img src={icon} alt="icon" />
</div>
);
};
网络请求
集成了[axios]库
使用方法:
import { axios } from "@plume/core";
axios
.get("/")
.then(result => {})
.catch(reault => {});
权限路由
plume 实现权限路由十分简单,只要在相应的目录下,添加Author.js
或Author.jsx
组件即可。
同一目录下的其他子目录,都会走此处的权限组件。除非子目录下有自己的 Author 组件。
在权限组件内,被渲染的组件为权限组件的props.children
。
在权限组件内,可以使用 react-router-dom 的history
,location
,match
和staticContext
属性,其他父级传入的属性,将直接传入被渲染的组件内
权限组件需要使用export default
输出。
例如,有这样的一个目录结构:
└── src
├── components
└── pages
├── Home
│ └── index.jsx
└── Manager
├── _Author.js
├── User
│ └── index.jsx
├── Post
│ ├── _Author.jsx
│ └── index.jsx
└── index.jsx
则路由到Manager
和Manager/User
都会先经过 Manager/_Author
组件,在内部拿到props.children
,也就是Manager
或User
页面,再去判断是否需要渲染。
而路由到Manager/Post
的,会先经过Manager/Post/_Author
组件。
Author 组件内部可能是这样:
import React, { PureComponent } from "react";
import { Redirect } from "react-router-dom";
class Author extends PureComponent {
render() {
const Cmp = this.props.children; // 这个是要渲染的页面
// 此处判断权限
if (isLogin) {
return <Cmp />; // 加载组件
} else {
return <Redirect to="/login" />; // 重定向
}
}
}
export default Author;
glob author/全局权限
全局的权限放在{pages}
的根目录下,文件名为_Author.js|jsx
。用法与布局一致
Layout/布局
layout 布局的使用方法类似_Author
在嵌套的页面下,使用布局非常简单,只要添加_Layout.js|jsx
文件到目录,则此目录下的所有页面都将使用此布局配置。
除非子目录下有自己的 Layout 组件。
Layout 组件内props.children
为布局的内容部分。
在权限组件内,可以使用 react-router-dom 的history
,location
,match
和staticContext
属性,其他父级传入的属性,将直接传入被渲染的组件内。
例如有这样一个目录结构:
└── src
├── components
└── pages
├── Home
│ └── index.jsx
└── Manager
├── _Layout.js
├── User
│ └── index.jsx
├── Post
│ ├── _Layout.jsx
│ └── index.jsx
└── index.jsx
则路由到Manager
和Manager/User
都会使用Manager
组件下的_Layout.jsx
组件渲染,在内部会拿到props.children
,也就是Manager
或User
页面。
而路由到Manager/Post
的,则会使用自己的 Layout 组件。
glob layout/全局布局
全局的布局放在{pages}
的根目录下,文件名为_Layout.js|jsx
。用法与布局一致
Wrapper/包裹组件
包裹组件是在{src}
目录下名为_Wrapper.jsx
的文件。
如果有_Wrapper.jsx
,将会替换{plume}/App.jsx
作为默认的入口模块。
如果需要使用{plume}/App.jsx
,可以在包裹组件内引用
import React, { Component } from "react";
import App from "../.plume/App.jsx";
class Main extends Component {
render() {
return (
<div>
<h1>Wrapper Component</h1>
<App />
</div>
);
}
}
export default Main;
TODOS
- [x] 支持 dev 下,当新建 page 页面时,更新 pageInfo.json 文件
- [x] 支持 dev&&flow 下,当新建 model 时,更新 models.js 文件
- [x] 支持多层路由
- [x] 支持嵌套路由
- [x] 支持权限路由
- [x] 支持动态路由
- [x] 支持可选动态路由
- [x] 支持静态资源打包
- [x] 集成 axios