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

femi

v0.13.0

Published

集运行时和构建时于一体的微前端脚手架

Downloads

56

Readme

Femi

集运行时和构建时于一体的微前端脚手架

Feature

独立开发、独立部署

  • 每个 App 可以单独启动,单独构建
  • 提供优化的 dockerfile, 一键生成 Docker 镜像

动态加载

  • 主工程与子应用解耦
  • System.js 协议动态加载 App
  • 便捷的封装 Parcel Api,以技术无关的形式加载 App 或者组件

集成加载

  • 可选,将独立的 App 放在一个工程内进行构建打包

快速上手

安装 Femi

npm install femi -g
yarn global add femi

初始化主工程

femi init myFemiProject

进入目录,安装依赖

cd myFemiProject && yarn

启动主工程开发环境

yarn start

主工程

主工程目录结构

  -
  |--- public         // 可选,存放静态资源,此目录下的文件构建时仅复制
  |--- src
    |--- main.less    // 可选,全局样式
    |--- main.ts      // 入口文件

Buildin App

Buildin App 是随主工程一起编译的,使用主工程统一的 femi-scripts 进行构建,这种类型的 App 具有以下特点:

  • 集成度高,环境统一,复用率高
  • 不灵活,需要随主工程一起发布

推荐用于主工程的公共页面,例如登陆页、首页等

快速上手

启动某个 buildin App 的开发环境

yarn start appKey

构建某个 buildin App

yarn build appKey

Runtime App

Runtime App 为独立开发、独立部署的 App,当主工程匹配到相对应的路由后,通过 System.jS 加载对应 App 的静态资源,找到 App 静态资源中提供的生命周期方法来完成对应的挂载和之后的卸载。

创建 App

femi create-app <type> <name>

type 可选 react 和 vue

例如,我想创建一个使用 React App,名字为 Intro

femi create-app react Intro

然后在当前运行目录下就多了 Intro App 目录啦

React App 推荐目录

|--- src
  |--- common       // 可选,app 内公共库
    |--- history.ts // 可选,app 内的跳转
  |--- components   // 可选,app 内公共组件
  |--- constants    // 可选,app 内常量
  |--- routes       // app 内路由
    |-- Home        // 目录与嵌套路由结构相似
      |-- Intro Page
    |-- User
      |-- Add Page
      |-- Edit Page
  |--- stores       // 可选,app 内状态库
  |--- styles       // 可选,app 内公共样式
  |--- types        // 可选,app 内类型
  |--- index.tsx    // 根组件
|--- app.tsx        // 入口,提供接入主工程的生命周期方法和独立启动方法

Vue App 推荐目录

待补

配置主工程路由

src/app.js

export default [
  ...
  {
    name: "React应用",      // 名字, 随意取
    key: "app-runtime-react",       // key,唯一,也是 App 挂载的 dom 节点 id
    path: APP_PARCEL_REACT,       // 路由匹配前缀,匹配到就会分配到此 App
  },
  ...
]

子应用 dev 环境

yarn start

子应用独立构建

yarn build

子应用 dev 环境中以 system.js 格式输出

// Parcel 为入口名称,子应用默认已经配好
// devServer输出静态资源: localhost: [端口号]/Parcel/js/main.js
yarn build Parcel --system

子应用以 system.js 格式输出

// 生成 dist 目录
yarn build Parcel --system

主工程接入子应用

public/index.html

...
<head>
  ...
  <script type="systemjs-importmap">
    {
      "imports": {
        ...
        // 这个 key 即为 system 模块名字
        "reactApp": "http://localhost:3001/Parcel/js/main.js"
      }
    }
  </script>
</head>
<body>
  ... // 新增 dom 容器
  <div id="app-parcel-react"></div>
</body>
...

apps/appRuntimeReact 新建

import { bootstrapFac, mountFac, unmountFac } from "@common/appFac"

const bootstrap = bootstrapFac(() => {})

const mount = mountFac(props => {
  System.import("reactApp").then((res: any) => {
    res.mount(props)
  })
})

const unmount = unmountFac(props => {
  System.import("reactApp").then((res: any) => {
    res.unmount(props)
  })
})

export { bootstrap, mount, unmount }

femi.json

在项目根目录中添加,主要用于指定入口和提供一些个性化配置 | 字段 | 用途 |是否必须 | 默认值 | | ----- | ----| -------: | -----: | | hash | 入口配置 |false | true | | output |出口配置 | false | true | | port | 开发环境端口 | false | 4000 | | public | 公共 | false | | | html | html 模板 | false | | | alias | 引入路径的别名 | false | "@/": ["src/"] | | proxy | 开发环境代理 | false | | | externals| 构建排除项 | false | |

entry

/* 方式一 */
{
  "entry": "src/main.ts"
}

/* 方式二 */
{
  "entry": {
    "default": "src/main.ts",
    "react": "src/apps/appReact/index.tsx"
  }
}

output

{
  "output": {
    "hash": false
  }
}

port

{
  "port": 3001 // 非必填,指定开发环境端口
}

public

{
  imports: {
    [key: string]: string
  }                 // 公用模块
  headTags: string  // 在 html 的 head 标签内,排序在构建产物之后
  bodyTags: string  // 在 html 的 body 标签内,排序在构建产物之后
}

html

{
  title: string     // 页面标签标题
  favicon: string   // favicon 图标
  headTags: string  // 在 html 的 head 标签内,排序在构建产物之后
  bodyTags: string  // 在 html 的 body 标签内,排序在构建产物之后
}

alias

引入路径的别名

import { history } from "@/common/history"
// => import { history } from "./src/common/history"

proxy

开发环境代理

{
  "proxy": {
    "/api": {
      "target": "http://xxxxx.com/",
      "changeOrigin": true
    }
  }
}

externals

构建排除项

{
  "externals": ["vue", "vue-router"]
}

Parcel 使用

待补

Commitlint

目前只在主工程中默认开启

规范

git commit -m '\<type\>(\<scope\>): \<message\>.'
git commit -m '\<type\>(\<scope\>): \<message\>. \<type2\>(\<scope2\>): \<message2\>.'

示例

git commit -m 'fix(scale): fix something.'
  • type

      feat      功能
      fix       修复
      docs      文档
      build     构建
      style     样式
      refactor  重构
      test      测试
      chore     构建、工具
      revert    回退
      ci
  • scope: 作用范围

  • message: 描述,必须以英文句号.结尾

ESLint

ESLint Rules

ESLint React 规则

如何配合 TypeScript: typescript-eslint

覆盖冲突规则: plugin:@typescript-eslint/recommended

Docker

大名鼎鼎的 docker 带来的好处自然无需赘述,以 docker 封装,前端可以作为一个服务进行发布,并且隔离外部运行环境。在做版本回滚时非常方便,只需要以安全的镜像起一个容器,保住研发的最后一条生命线。配合容器的概念,通过控制流量导向,可以实现灰度发布。

安装 docker

mac

brew install docker

hello world

docker run hello-world

搜索镜像

docker search nginx

下载镜像

docker pull nginx

展示所有的镜像

docker images

通过 dockerfile 构建镜像

  • -t 指定镜像名
  • -f 指定 dockerfile 路径
docker build ./ -f ./path/to/dockerfile -t yourImageName

使用镜像  运行容器

docker run -p 80:80 -it ImageName /bin/sh

连接到正在运行的容器

docker attach --sig-proxy=false ContainerNameOrId
docker exec -it ContainerNameOrId /bin/bash

Dockerfile

FROM: 指定基础镜像

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>

RUN: 运行指定的命令

RUN <command>

COPY: 复制命令

COPY <src>... <dest>

* src 为本地文件

docker 命令大全

dockerfile 命令大全

CDN

<script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.js"></script>