初始化

执行npm init创建一个新的项目,根据指引完成创建,最终会得到一个 package.json 文件,前端开发对这个文件应该都不陌生。

执行 git init来初始化一个 git 仓库,方便后续进行版本管理。

如果有其他的工程化的配置比如 eslint、prettier、commitlint 之类额配置根据自己的需求面向百度吧,教程一堆一堆的。

组织

提前查阅你的项目名称时候已经存在一个包,如果有的话考虑换一个其他的包名,或者直接创建一个组织,以后所有的包都发布在组织下,这样就不会有报名冲突的问题了。

直接在 NPM 官网点击头像,在下拉菜单中选择添加组织

image-20230301224943088

然后输入一个自己的组织名称,组织会作为 URL 的一部分,所以不能出现不合法的 URL 字符,后续不可以修改,想好再确认。

然后将 package.json 中的 name 字段改为 scope 的格式,比如原来的 name 是 a,创建了一个组织 b,那么这时候 name 应该为 @b/a

此外,需要在 package.json 中添加以下配置,表示是公开的项目,否则会发布失败

"publishConfig": {
  "access": "public",
  "registry": "https://registry.npmjs.org/"
}

打包

一般的第三方库使用 rollup 来进行打包,因为比较轻量化,配置简洁,而且支持生成多种模块化方案的产物。

首先安装 rollup 及其相关的依赖

$ npm install -D rollup tslib @rollup/plugin-typescript

如果你没有用到 TypeScript,后面两个依赖可以不用安装

然后在项目根目录下新建 rollup.config.js 文件

import typescript from '@rollup/plugin-typescript';
import dts from 'rollup-plugin-dts';

export default [
  {
    input: 'src/index.ts',
    output: [
      {
        file: 'dist/index.common.js',
        format: 'cjs', // CommonJS 模块化方案
      },
      {
        file: 'dist/index.esm.js',
        format: 'esm', // ES6 模块化方案
      },
      {
        file: 'dist/index.amd.js',
        format: 'amd', // AMD 模块化方案
      },
      {
        file: 'dist/index.umd.js',
        format: 'umd', // UMD 模块化方案
        name: 'ImageFactory', // UMD 模块化方案需要指定全局变量名称
      },
    ],
    plugins: [
      typescript(),
    ],
  },
];

根据项目的实际情况配置主入口以及生成的产物,如果你没有使用 TypeScript 同样不需要进行相关配置。

在 package.json 中添加打包脚本

{
  "script": {
    "build": "rollup -c"
  }
}

执行 npm run build即可进行打包。

类型

如果你使用 TypeScript 编写源码,或者想要为之前的 JavaScript 代码提供类型支持,那么需要在 package.json 中指明你的 .d.ts文件位置。

{
    "types": "dist/index.d.ts"
}

如果你是使用 TypeScript 开发,需要通过打包工具将源码打包成 JavaScript 代码以及生成 .d.ts 类型声明,以 rollup 为例,使用插件 rollup-plugin-dts来生成类型声明文件,在配置文件中添加下面一段配置项。

{
  input: 'src/index.ts',
  plugins: [dts()],
  output: {
      format: 'esm',
    file: 'dist/index.d.ts',
  }
}

发布

发布时需要将 npm 的源设置为官方源https://registry.npmjs.org/

推荐使用 nrm 来管理镜像地址,在发布之前直接 nrm use npm 即可。

首先要在 npm 官网注册一个账户,注册的过程就不多说了,应该都会。然后回到终端执行 npm login,然后根据提示输出账号密码,登陆成功后会输出成功的提示,登陆失败的话根据输出的原因处理即可。

登陆成功之后在项目目录下执行npm publish,过程可能会有点慢,等待即可,如果有 2FA 验证如果进行鉴权操作。记得每次 publish 之前要修改 package.json 中的版本号

或者使用自动化的发布工具——release-it

release-it

release-it 是一款可以帮助我们快捷发布的 cli 工具,安装使用非常简单

安装方式有两种,npm 执行安装脚本或者手动添加依赖

方法 1

$ npm init release-it

方法 2

$ npm install -D release-it

然后在 package.json 中添加脚本

"scripts": {
  // ...省略其他脚本
  "release": "release-it"
},

在 package.json 中添加或者新建一个.release-it.json并添加以下配置,自动发布到 npm 和 github

{
  "github": {
    "release": true
  },
  "git": {
    "commitMessage": "release: v${version}"
  },
  "npm": {
    "publish": true
  },
}

最好还是执行安装脚本,这样不会出错。

如果需要自动添加 changelog,可以使用插件。安装插件npm install -D @release-it/conventional-changelog,然后在刚才的配置中添加下面一段

"plugins": {
  "@release-it/conventional-changelog": {
    "preset": "angular",
    "infile": "CHANGELOG.md"
  }
}

只要符合 angular 的提交规范,就可以自动生成 changelog 记录。注意一定要符合规范,不然可能不会生成 changelog。

安装配置完成之后就可以使用了,注意在发布之前需要 git 提交并推送到远程仓库。

执行npm run release,过程如下如图

image-20230301111931827

红框标注的欧一行是因为我的 npm 绑定了虚拟令牌,如果没有绑定2FA的话不需要这些额外的操作。

之后去 npm 官网查看即可。

字段含义

package.json 中有非常多的字段,下面列出和发布 npm 相关的一些字段。

  • name:项目的名称,如果你的项目会以 npm 包的形式发布,这个字段必须是独一无二的;
  • author:项目作者;
  • version:版本号,每次发布都需要是不一样的版本号,否则会失败,版本号遵循 semver 语义化规范
    1. Major 主版本号,通常在重大更新或者破坏性变更时修改此版本号;
    2. Minor 次版本号,引入新功能但未产生破坏性变更时更新此版本号;
    3. Patch 修订号,修复 bug 并没有产生破坏性变更时更新词此版本号。
    4. pre-release 先行版本号,用于生产之前的测试阶段,目前预定三个状态 alpha.x(内测),beta.x(灰度测试),rc.x(生产候选);
  • repository:描述仓库地址及仓库类型;
  • publishConfig:发布时使用的配置,包括仓库,是否公开等;
  • description:描述文本,用于描述当前包的作用等信息,会在 npm 列表进行展示;
  • keywords: 关键词数组,用于总结当前项目的作用等,可以帮助别人在 npm 官网更好地检索;
  • license:许可声明;
  • homepage:项目主页,如果没有专门为项目开发文档站点,一般设置为 git 仓库的 readme;
  • files:声明那些文件会被发布到 npm 仓库中,也可以通过 npmrc 配置文件来控制;
  • jsdeliver/unpkg:文件路径,声明字段之后,CDN 平台会将包指向声明的文件,jsdeliver 默认会给每个包添加 CDN,unpkg 没用过;
  • peerDependencies:前置依赖,声明当前包依赖了其他包,在安装时会进行提示;
  • types:指示类型声明文件的路径,使用者的环境 TypeScript 时根据此文件进行类型提示及语法检查;
  • type:‘module’和‘commonjs’,标识当前项目使用的模块化方案;
  • main:声明入口文件,在 node 和浏览器环境下都可用;
  • broswer:同样是声明入口文件,仅允许在浏览器环境下使用。

最后,小小的广告,本篇文章是我基于 @feng-j/image-factory 发布进行的总结,这是一个利用 canvas 进行图片像素级滤镜处理的库,旨在收集一些常用和不常用的滤镜算法,如果你有好的滤镜算法,非常欢迎提 PR 来一起完善。


前端小白