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

@mx-design/release

v2.2.29

Published

Lightweight release script for Front-end project

Downloads

5

Readme

文档如下

前言

兄弟们,这个东西是真的真的好用,为什么需要自动化发布脚本呢? 如果你们目前的项目是这样push代码的,就有大问题:

git add -A
git commit -m "xxx"
git push
  • 首先,你push版本前是不是要手动修改package.json里的版本号?是不是很麻烦?
  • 其次,代码如果要打tag,你是不是要手动git tag vXXX还要git push origin tag把tag单独推到git仓库?
  • 还有,你commit不符合angular规范咋办(比如修改bug是'fix:' 开头, 新增功能是'feat:' 开头)
  • 还有,修改了commit之后如何自动生成changelog?
  • 最重要的是你如果自己写bash 脚本,如何保证你代码的拓展性,比如我要加减一个流程,你必须面向过程编码去改bash脚本,而不能轻易的抽象出一个可配置化的流程脚本。

看看这个npm包咋样

这是我自己写的一个可配置化的node发布脚本,先看看效果:

我在自己项目的根目录建立一个scripts文件夹,下面建立一个release.ts 脚本

import defaultRelaseProcess from '@mx-design/release';
defaultRelaseProcess();

package.json

  "scripts": {
    // 不用担心ts-node依赖,@mx-design/release包会帮你安装
    "release": "ts-node ./scripts/release.ts"
  },
   "devDependencies": {
    "@mx-design/release": "^1.0.0",
  },

然后命令行界面到你的项目根目录,输入:

npm run release

然后你的命令行界面会显示如下: 1、询问你要升级的版本

34182EEF-6E27-41B9-AE4F-41C6AFEFB6E7.png

看到了吧,你可以自由选择是主版本升级,还是次版本,或者其他版本,都是符合semver规范的。

2、选择后会让你填写commit信息,如果你的commit的信息不符合angular提交规范,会报错提示你不符合规范,并且终止脚本。(整体交互很舒服,比如你git push的时候,我们会显示正在push loading,push成功,就会覆盖当时正在push的文字,颜色标绿并显示对钩的图标)

image.png

交互loading如下:

image.png

如果命令执行错误,显示如下(国内github环境非常差,经常git push失败,用vpn还是一样的):

109CAAC1-709A-4686-86A9-AF64D960E984.png

git push成功效果如下:

C74EFAE8-C49A-447F-8E14-093B2ACBD947.png

3、这里release的主要流程完成如下:

4E008797-7E12-4619-B39A-A3C8E131B4C1.png

流程包括:

  • 选择升级版本 ->
  • 修改package.json的版本号 ->
  • 填写commit信息(校验格式,不通过终止) ->
  • 推送到代码仓库(推送失败会帮你把package.json里的版本回退) ->
  • 生成changeLog ->
  • build打包(这里执行的是npm run build 所以你的scripts里必须有build命令,要不执行失败) ->
  • 发布包(执行的 npm publish --access=public 命令) ->
  • 打tag并且推送到git仓库

自定义流程

上面几个流程是这个包自带流程顺序,你可以配自己的顺序,

import { getNextVersion, gitPush, setChangelog, build, publishNpm, addTag, compose } from '@mx-design/release';

// getNextVersion 获取下个版本号函数
// updateVersion 修改版本号 返回值是回退版本号的函数
// gitPush push代码函数
// setChangelog 设置changeLog函数
// build 执行npm run build函数
// publish 执行npm publish函数
// addTag 打tag函数
// compose函数组合器

// 使用方法,这些函数顺序可以自己换位置,或者增删减
const middle = [getNextVersion, updateVersion, gitPush, setChangelog, build, publishNpm, addTag];

function execRelease() {
  compose(middle);
}

寻求共建 + 源码分析

本项目随时欢迎任何有兴趣的同学加入,评论区写自己github账号,或者issue上留言,我会第一时间加你到核心开发成员列表。

这个项目还缺少一些东西,比如eslint、stylelint校验,自定义changelog位置,增加单元测试,加入git workflow 等等,我没那么多时间做,因为今年还有很多任务排着呢。。。

源码分析

目录含义:

- 根目录
 - src
   - addTag 
       - index.ts // 打tag函数
   - build
       - build.ts // build项目函数
   - config // 配置文件夹
       - functions 工具函数
       - contstants 常量
   - gitPush
       - index.ts // push到git函数
   - publishNpm
       - index.ts // publish 整个项目的函数
   - selectNextVersion
       - index.ts 选择下个版本号函数
   - setChangeLog
       - 打changeLog函数
 package.json
 tsconfig.json
 ... 普通文件没啥好讲的

核心中间件执行器compose,这个函数的灵感来源于koa框架,说白了就是一个中间件组合函数,并且能共享数据,代码如下,后面我们会举个例子,来看它的执行机制:

export function compose(middleware) {
  // 共享数据仓库,每个函数都可以往里面加数据,所有函数都可以访问到里面的数据
  const otherOptions = {}; 
  // 函数发射器,一个函数执行完毕调用next(),就执行下一个函数
  function dispatch(index, otherOptions) {
    // 每次从middleware中间件里面选取一个函数执行,直到执行了全部函数
    if (index == middleware.length) return;
    const currMiddleware = middleware[index];
    // 执行函数,传入了一下一个函数的dispatch,已经更新共享数据
    currMiddleware((addOptions) => {
      dispatch(++index, { ...otherOptions, ...addOptions });
    }, otherOptions).catch((error) => {
      console.log('💣 发布失败,失败原因:', error);
    });
  }
  dispatch(0, otherOptions);
}

middleware写法

// 获取版本号函数,固定参数第一个是next,表示调用middleware里下一个函数
const getNextVersion = async (next) => {
  // _selectNextVersion会查看你package.json里的version参数是啥版本
  const nextVersion = await _selectNextVersion();
  // 缓存老的package.json数据,为了后面可以回退版本有老版本数据做准备
  const originPackageJson = getOriginPackageJson();
  // next传入的数据都会放到共享数据仓库,下面的函数都可以拿到这些数据
  next({
    nextVersion,
    originVersion: originPackageJson.version,
    originPackageJson,
  });
};

// 更新版本号方法
const updateVersion = async (next, otherOptions) => {
  if (!otherOptions?.nextVersion) {
    throw new Error('请传入package.json新版本号');
  }
  // 返回一个回退版本号的方法,上面的函数共享的originPackageJson数据就是给他用的
  // basicCatchError如果命令执行失败,就打印失败原因,并且返回false
  const backVersionFn = await _updateVersion(otherOptions.nextVersion, otherOptions.originPackageJson).catch(
    basicCatchError,
  );
  // 把回退版本的函数共享出来,给下面需要用的地方自己调用
  next({ backVersionFn });
};

案例说明

compose([getNextVersion, updateVersion])

首先compose会调用

  • dispatch(0, otherOptions)
  • 0代表compose传参的middleware数组里的第一项
  • otherOptions代表共享数据,目前是空对象

接着, 第一个函数调用

  • getNextVersion((addOptions) => { dispatch(++index, { ...otherOptions, ...addOptions }); }, otherOptions);
  • 看第一个参数,我们是这么写的
  • const getNextVersion = async (next) => {
  • 也就是说第一个参数next调用后,实际上是调用dispatch函数,dispatch函数的参数index + 1,就调用了middleware数组里,第二个函数了
  • dispatch第二个参数就是把next想共享的数据发下去

好了源码分析完了,我今年主要是任务是写react pc和移动端组件库,之前写了cli打包和开发的脚手架,文章如下: https://juejin.cn/post/7075187294096850951

这个项目也是,有兴趣加入核心贡献者,直接留言,把github账号说下,第一时间加你进来,多谢点个star哦 现在完成了发布脚本,接着就是搭建组件库展示网站了,也是自己写,没有用现成的dumi或者storybook。