npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@plume/app

v0.1.14

Published

About the configuration and construction of webApp

Downloads

45

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

  1. 创建 models 的时候,会搜索当前项目下所有models目录,目录内的每个*.js文件作为一个 model,所以 models 目录下每个 js 文件务必有默认输出 export defaut。支持嵌套 models 目录。默认忽略node_modules.plume目录。
  2. 每个 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.jsAuthor.jsx组件即可。

同一目录下的其他子目录,都会走此处的权限组件。除非子目录下有自己的 Author 组件。

在权限组件内,被渲染的组件为权限组件的props.children

在权限组件内,可以使用 react-router-dom 的history,location,matchstaticContext属性,其他父级传入的属性,将直接传入被渲染的组件内

权限组件需要使用export default输出。

例如,有这样的一个目录结构:

└── src
    ├── components
    └── pages
        ├── Home
        │   └── index.jsx
        └── Manager
            ├── _Author.js
            ├── User
            │   └── index.jsx
            ├── Post
            │   ├── _Author.jsx
            │   └── index.jsx
            └── index.jsx

则路由到ManagerManager/User都会先经过 Manager/_Author 组件,在内部拿到props.children,也就是ManagerUser页面,再去判断是否需要渲染。

而路由到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,matchstaticContext属性,其他父级传入的属性,将直接传入被渲染的组件内。

例如有这样一个目录结构:

└── src
    ├── components
    └── pages
        ├── Home
        │   └── index.jsx
        └── Manager
            ├── _Layout.js
            ├── User
            │   └── index.jsx
            ├── Post
            │   ├── _Layout.jsx
            │   └── index.jsx
            └── index.jsx

则路由到ManagerManager/User都会使用Manager组件下的_Layout.jsx组件渲染,在内部会拿到props.children,也就是ManagerUser页面。

而路由到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