npm包也有SEO!手把手教你提升自己的npm包排名

avatar
前端研发工程师 @快手

之前写了一个将中文转换为拼音的工具包,名为 pinyin-pro , 支持汉字、词语、句子等多种格式的拼音、声母、韵母、音调等多种转换形式。

前两天去 npm 使用 拼音 关键字搜索一下,结果发现得到第二页底部才能找到我的包,看了看前面的许多包,下载量和热度不如我,你说说,这合理吗?

image.png

细细一研究,这才发现,原理 npm 包的搜索排名也大有说法。甚至许多非常优秀的开源包如react、vue他们在这方面也并没过多关注。

你说这我能忍吗?连肝一晚上,立马把排名干到了第二位,下面写一下 npm 包排名规则以及优化 npm 包的详细教程。

npm 包排名指标

首先你随便搜一个包,如果有包的名称和你的搜索是完全匹配的,那么 npm 搜索排名第一的一定是它。所以同搜索引擎一样,npm 搜索的优先权重一定是包名称和你搜索内容的匹配度,且权重远大于其他指标。

如下图我随便搜索一个 adsa,出现的第一个包便是与他 exact match 的,尽管这个包质量并不好且无人无津。

image.png

除去搜索的名称匹配相似度外,npm 包有三个指标,分别是 p(Popularity)、q(Quality)、m( Maintenance)。

可以根据 https://api.npms.io/v2/package/:packageName 接口查询 npm 包信息,里面包含了包的指标评分。

Popularity

Popularity这一项是最难优化的,主要和你的包下载量及热度有关,想提升它需要靠你的宣传(当然你的包的功能还需要足够优秀)。

它包含以下4个指标:

  • communityInterest: 社区利益,这一项是你的 git 的 star + watch + fork 的总和。(经过我连续多天的总结和实践终于发现了这个规律)
  • downloadsCount: npm 的下载量这个略微有些迷糊,我细细比对了一下,大概是接近月下载量,但是又比 npm 上显示的月下载量略少一点。
  • downloadsAcceleration: 这个和下载次数的增长有关,具体的数值规律没总结出来,但是不需要关注太多,优化好自己的包就行。
  • dependentsCount: npm 社区依赖于你的包的数量,即有多少其他 npm 包的dependecies中使用了你的包。

Quality

Quality 和你的 npm 包代码规范、测试、说明等有关,代表你 npm 包的质量,我们本篇文章的优化也会主要针对这一项。

它也包含4个指标:

  • carefulness: 你对你的包的细心程度。包括你的包里是否有readme、gitignore、LICENSE、是否包含代码规范 lint等等。
  • tests: package.json 里是否有test的script,以及你的测试用例覆盖率。
  • health: package.json 信息是否完善,包括 description、keywords 等等信息是否有TODO。
  • branding: README.md 中的文档开头的那些标签,例如 npm versiondownloads 那些。

Maintenance

Maintenance和你的维护频率有关,通过定期维护,也可以提升这方面的评分。

同样地,Maintenance也有四个指标:

  • releasesFrequency: 顾名思义,npm 版本发布频率。
  • commitsFrequency: github 的 commit 频率。
  • openIssues: github 上状态为 open 的 issue 数量
  • issuesDistribution: 不太清楚

优化前

这是我的包优化前的状态,可以看右侧 q(Quality) 这项的指标评分很低,通过 拼音 关键词查询,排名大约在20多。

image.png

通过 api.npms.io/v2/package/… 查询详情,直接拉到数据最后,可以看到 quality 项的得分为 0.8179011286168503,导致总得分 final 为0.6355458339200173。(满分为1)

细看 quality 项,可以看到 carefulness、tests、branding 三项的评分都偏低,那我们就有了优化的方向了。

{
    "evaluation":{
        "quality":{
            "carefulness":0.7899999999999999,
            "tests":0.6,
            "health":1,
            "branding":0
        },
        "popularity":{
            "communityInterest":289,
            "downloadsCount":331,
            "downloadsAcceleration":2.3441590563165904,
            "dependentsCount":1
        },
        "maintenance":{
            "releasesFrequency":1,
            "commitsFrequency":0.9078356164383562,
            "openIssues":1,
            "issuesDistribution":1
        }
    },
    "score":{
        "final":0.6355458339200173,
        "detail":{
            "quality":0.8179011286168503,
            "popularity":0.11479715693618153,
            "maintenance":0.9999899725922818
        }
    }
}

优化过程

从上面的评分,我们确定了本优化过程主要针对 quality 项进行优化的方向。

提高test

一般我们的 npm 包都需要写测试用例,常用的测试工具有mochajest等等,我这里使用的是mocha,所以以mocha为例。

  1. 安装相关工具,我这里使用了 mocha + chai + istanbul。mocha 是用来编写测试用例,chai 断言库在判断期望值与实际值不相等时会抛出异常,istanbul是用来帮我们检查测试覆盖率的。

    npm i mocha chai istanbul -D
    
  2. 在根目录新建 test 文件夹,在里面编写测试用例,具体 mocha 的测试用例比较简单,没接触过的话可以自己上网简单学一下。以我的为例:

    // /test/dist.test.js
    const { pinyin } = require('../dist/index');
    const expect = require('chai').expect;
    
    describe('aggregate', () => {
      it('test1', () => {
        const result = pinyin('汉语拼音', { pattern: 'num', toneType: 'num' });
        expect(result).to.be.equal('4 3 1 1');
      });
    
      // ...
    });
    
  3. package.json 中增加测试命令:

    {
      // ...
      "scripts": {
    +    "test": "mocha",
    +    "coverage": "istanbul cover _mocha -- -R spec --timeout 15000 --recursive",
    +    "coverage:check": "istanbul check-coverage",
    +    "cover": "istanbul cover --report=html node_modules/mocha/bin/_mocha -- -R spec test/*.js"
      },
      // ...
    }
    

    在终端执行 npm run test 可以查看测试用例覆盖率,执行 npm run cover 会在项目根目录下生成一个名为 coverage 的文件夹,打开 /coverage/html 文件,可以在浏览器查看测试覆盖率。(其他两个命令后面会有用到)

    image.png

  4. 提高测试覆盖率。接上一步,浏览器打开/coverage/html 文件后,找到测试覆盖率不足100%文件,点击进去可以看到测试未覆盖到的代码。

    image.png

    红色和黄色的部分便是测试用例未覆盖到的代码,可以增加测试用例,争取将测试覆盖率提高到100%。

    image.png

提高test的部分就到这里了。

提高carefulness

增加CI

一般开源项目都会使用 travis-ci 进行CI。

  1. 登录 travis-ci ,选择使用 github 账号登录。

  2. 点击下方图片中的 + 号,选择添加你要发布的 npm 包绑定的 github 仓库。

    image.png

  3. 在项目根目录添加 .travis.yml 文件,添加如下代码:

    language: node_js
    node_js:
      - stable
    script: npm run test
    
  4. github 提交时,就会执行 CI 过程并执行 test 命令,CI 通过后,会生成这样的一个 building: passing 的 brand:

    image.png

    点击这个 brand,选择 markdown,就可以生成它的 markdown 地址,放到你的 README.md 文件中就行:

    image.png

增加coverage

前面提到了测试覆盖率,我们还要将其与 npm 的检测机制关联起来。这里我们使用 coveralls 平台。

  1. 使用 github 账号登录 coveralls,选择把对应的仓库打开:

    image.png

  2. 点击DETAILS按钮,里面会有repo_token:

    image.png

  3. 执行以下命令,安装相关包: 安装 coveralls

    npm i coveralls -D
    

    安装 travis

    gem install travis
    

    执行 encrypt,将下方的 your_repo_token 替换为上面第二步中的 repo_token

    travis encrypt COVERALLS_TOKEN=your_repo_token --add
    

    执行之后会发现 .travis.yml 文件中多出了下面的信息,这会将我们的测试覆盖率上传至coveralls,与 npm 关联

    + env:
    +   global:
    +     secure: U8Zd1z5E3/ovD87OpBWxMm0xCNcl1mqOM+cWKgTmOJlTPVHLCVA7G9oZd8i1K7trW6fDvTJT1GW5ZNzBOV8+bYEVUeTeqAvtgiqZLLVC2IEdmfXsumvsprC8OuCKHh8d7lNhn1vCGXGGLllO2J3tG66ATjQ2ZgdqPBUQ20mafqy4OOGkqs7PcvV1A7OMQnFNpPL6bptpxiumCdHUSirsM48e0dFRPNVfxPVYbKitil0Q+sWUh+Heb=
    

    再在 .travis.yml 添加如下执行过程:

    + after_script: npm run cover && cat coverage/lcov.info | node_modules/coveralls/bin/coveralls.js
    

    完整的 .travis.yml 如下:

    language: node_js
    node_js:
      - stable
    script: npm run test
    after_script: npm run cover && cat coverage/lcov.info | node_modules/coveralls/bin/coveralls.js
    env:
      global:
        secure: U8Zd1z5E3/ovD87OpBWxMm0xCNcl1mqOM+cWKgTmOJlTPVHLCVA7G9oZd8i1K7trW6fDvTJT1GW5ZNzBOV8+bYEVUeTeqAvtgiqZLLVC2IEdmfXsumvsprC8OuCKHh8d7lNhn1vCGXGGLllO2J3tG66ATjQ2ZgdqPBUQ20mafqy4OOGkqs7PcvV1A7OMQnFNpPL6bptpxiumCdHUSirsM48e0dFRPNVfxPVYbKitil0Q+sWUh+Heb=
    
  4. github上 push 代码后,就能在 coveralls 中看到测试覆盖率了:

    image.png 点击EMBED,把MAEKDOWN复制到你的 README.md 中,就会增加 coverage 的图标了:

    image.png

增加eslint

  1. 安装eslint
    npm i eslint -D
    
  2. 在项目根目录新增 .eslintrc 文件,这里的代码规范可以根据自己需要去写,我这里添加了一点最简单的:
    {
      "env": {
        "browser": true,
        "node": true,
        "commonjs": true
      },
      "parserOptions": {
        "ecmaVersion": 7,
        "sourceType": "module"
      }
    }
    
  3. package.json 文件中新增 lint 命令,执行 npm run lint 可以对代码进行规范检测:
    {
     // ...
     "scripts": {
     // ...
    +    "lint": "eslint ."
     },
     // ...
    }
    

增加CHANGELOG.md

在项目根目录新建 CHANGELOG.md 文件,里面添加你的包更新日志,若已有请忽略。

增加.gitignore

若项目中没有 .gitignore 文件请在项目根目录新建,若已有请忽略。

增加.npmignore

若项目中没有 .npmignore 文件请在项目根目录新建,若已有请忽略。

增加LICENSE

若已有LICENSE,请忽略这一步,我以一个其他仓库添加LICENSE为例。

  1. 在 github 选择 Add file -> Create new file

    image.png

  2. 在filename 那里输入 LICENSE 后,右侧会出现 Choose a license template 选项:

    image.png

  3. 点击左侧选择一个 LICENSE,然后单击 Review and submit

    image.png

  4. 最后点击 commit new file 就添加了:

    image.png

提高health

health大多数人的包应该都是1,如果不是,请检查 package.json 的配置项:desciption、keywords、name、main等信息是否完善及正确。

提高branding

branding就是你的 package.json 中这些东西,上面的教程已经添加过 buildcoverage 了。

image.png

其他的图标可以在 shields.io 查看地址,例如添加一个npm version的图标,只需要在 README.md 文件中添加:

[![NPM version](https://img.shields.io/npm/v/pinyin-pro.svg)](https://www.npmjs.com/package/pinyin-pro)

优化后

经过了以上几步,我们的优化过程基本就差不多了,让我们看看优化后的结果,搜索 拼音 关键字:

image.png

可以看到我们 q(Quality) 这一项已经大幅提高,搜索结果的排名也是直接到了第一位。

image.png

再来看看各项评分:

{
    "evaluation": {
        "quality": {
            "carefulness": 0.9999999999999999,
            "tests": 1,
            "health": 1,
            "branding": 0.6
        },
        "popularity": {
            "communityInterest": 298,
            "downloadsCount": 668.6666666666666,
            "downloadsAcceleration": 10.897393455098936,
            "dependentsCount": 1
        },
        "maintenance": {
            "releasesFrequency": 1,
            "commitsFrequency": 1,
            "openIssues": 1,
            "issuesDistribution": 1
        }
    },
    "score": {
        "final": 0.69251706704311,
        "detail": {
            "quality": 0.9995248552319843,
            "popularity": 0.12188460135289936,
            "maintenance": 1
        }
    }
}

可以看到 quality 中的 test 飙到了满分,carefulness 也无限接近满分,branding 也上升到了0.6分。再看 score 中的 quality 的总评分也是接近满分了!

剩下的优化就是提升你的包的功能,再加上推广和宣传了!

最后

最后附上我的包的地址,有需要汉字转拼音,以及获取声母、韵母、音调的朋友可以下载试一下,感觉蛮好用的!觉得不错可以点个 star,也欢迎有要想参与一起建设交流的朋友可以在 readme 的最后加我。