發布一個 npm 包,構建自己的第三方庫

發布一個npm包,構建自己的第三方庫

前言

小生在需要發布自己npm包時,見網上諸多教程,皆無法滿足所思需求;不是太簡單,就是缺三少四,故前往各大廠商之GitHub,耐心翻閱其源碼,始有心得;特此做博客以記,與諸君共勉。

如果你需要進行快速搭建自己的第三方庫,請移步:npm-plugins-building-shell 或者 借用shell,快速搭建一個npm插件庫

申請一個npm 賬號 以及創建好相關 github 項目

前往申請 npm 賬號: https://www.npmjs.com/

此處本人創建的 github 項目名字為my-npm-libs,你需要另外重新起個名字。

本地創建 npm 項目

我們需要創建自己npm項目。


mkdir my-npm-libs # 創建文件夾,注意此處的名字和你上面創建的GitHub項目名稱保持一致
cd my-npm-libs # 進入文件
# 此處使用 -y 可以跳過后面讓你填寫內容操作,所有內容都是用默認值就好,有需要的話回頭可以在package.json 文件中進行修改
npm init -y # 默認配置

這里我們選擇的是默認配置npm init -y,如果,你需要進行更詳細的配置請使用:

npm init

使用npm init的結果如圖:

npm init result

查看npm init文檔,以查看更多詳細內容。

npm 項目目錄

mkdir examples lib src test # 創建所需目錄
touch .babelrc .gitignore README.md # 創建所需文件
touch examples/index.html src/index.js test/index.js

目錄如下:

.
├── examples/                         // 目錄: 放置案例文件
│   ├── index.html                    // 文件: 案例運行結果
├── lib/                              // 目錄: 放置 script 引用的文件
├── src/                              // 目錄: 庫目錄
│   ├── index.js                      // 文件: 庫內容
├── test/                             // 目錄: 放置單元測試文件
│   ├── index.js                      // 文件: 測試內容
.babelrc
.gitignore
package.json
README.md

相關配置(請按照順序進行配置)

src/index.js 庫內容

我們的包需要支持如下三種引用方式:

import引用

import ... from '...'

require引用

const ... = require('...')

標簽引用

<script src="..."></script>

此處我們使用自己寫的,獲取數據類型的方法:

// 獲取數據類型
(function (root, globalName, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD:
    define([], factory);
  } else if (typeof module === 'object' && module.exports) {
    // Node:
    module.exports = factory();
    // Use module export as simulated ES6 default export:(將模塊導出用作模擬ES6默認導出)
    module.exports.default = module.exports;
  } else {
    // Browser:
    window[globalName] = factory();
  }
}(this, 'dataType', function () {
  'use strict';

  return function dataType (data) {
    return ({}).toString.call(data).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
  }
}));

babel配置

由于,目前絕大部分的瀏覽器只支持ES5,故此我們需要把ES5以上的語法?轉換為ES5,我們需要引用babel。不了解babel的請移步babel 官網

如果你不需要進行語法轉換則跳過此babel配置步驟。

我們需要配置babel,這里由于babel的更新babel的配置基本分為兩類:
1.babel6.X 以及其以下版本
2.babel7.X 以及其以上版本

babel6.X以及其以下版本的配置

安裝 Babel 命令行工具(babel-cli)以及一種 Babel preset

npm install --save-dev babel-cli babel-preset-env

創建一個 .babelrc 文件(或者使用你的 package.json 文件):我們上面已經創建過了的話,此處不必再進行創建。

{
  "presets": ["env"]
}

由于 Babel 只進行語法轉換(如箭頭函數),你可以使用 babel-polyfill 來支持新的全局變量,如 Promise 或新的原生方法,如 String.padStart(left-pad)。它使用了 core-jsregenerator
安裝 babel-polyfill

npm install --save-dev babel-polyfill

運行此命令將所有代碼從 src 目錄編譯到 lib

./node_modules/.bin/babel src --out-dir lib

babel7.X以及其以上版本的配置

安裝 Babel 命令行工具(@babel/cli)、Babel核心以及一種 @babel preset :

npm install --save-dev @babel/core @babel/cli @babel/preset-env

在項目的根目錄中創建名為 babel.config.js 的配置文件:

const presets = [
  ["@babel/env", {
    targets: {
      edge: "17",
      firefox: "60",
      chrome: "67",
      safari: "11.1"
    },
    useBuiltIns: "usage"
  }]
]; // 上面的瀏覽器列表只是用于展示的示例。你必須根據想要支持的瀏覽器進行調整。

@babel/polyfill 模塊包括 core-js 和自定義 regenerator runtime 來模擬完整的 ES2015+ 環境。
這意味著你可以使用像 PromiseWeakMap 這樣的新內置函數,像 Array.fromObject.assign 這樣的靜態方法,像 Array.prototype.includes 這樣的實例方法,以及 generator 函數(提供給你使用 regenerator 插件)。
安裝@babel/polyfill

npm install --save @babel/polyfill

運行此命令將所有代碼從 src 目錄編譯到 lib

./node_modules/.bin/babel src --out-dir lib

.gitignore的配置

.DS_Store
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln

package.json的配置

{
  "name": "my-npm-libs",
  "description": "發布一個npm包,構建自己的第三方庫",
  "version": "1.0.1",
  "author": "nongshuqiner <ym1185509297@163.com>",
  "license": "MIT",
  "main": "src/index.js",
  "files": [
    "examples",
    "lib",
    "src",
    "test"
  ],
  "private": false,
  "scripts": {
    "test": "mocha --recursive",
    "examples": "open ./examples/index.html",
    "build": "./node_modules/.bin/babel src --out-dir lib"
  },
  "keywords": [
    "my-npm-libs"
  ],
  "homepage": "https://github.com/nongshuqiner/my-npm-libs.git",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/nongshuqiner/my-npm-libs.git"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.7.0",
    "chai": "^4.2.0",
    "mocha": "^5.2.0"
  }
}

examples/index.html的配置

在配置 examples/index.html 前需要運行如下命令:

./node_modules/.bin/babel src --out-dir lib
# 或者,由于我們在 package.json 中,已經配置了,故此也可以使用下面這個命令構建
npm run build

examples/index.html的內容:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>my-npm-libs</title>
  </head>
  <body>
    <div id="examples">
      <div class="">
        var a = [1, 2, 3, 4, 1, 5, 1, 7],a的數據類型是什么?
      </div>
      <div id="result"></div>
    </div>
    <script src="../lib/index.js"></script>
    <script>
      console.log(window.dataType);
      var a = [1, 2, 3, 4, 1, 5, 1, 7];
      var result = document.getElementById('result');
      result.innerHTML = dataType(a);
    </script>
  </body>
</html>

我們可以通過如下命令進行案例查看:

npm run examples

README.md的配置

# XXX(組件名)

## 概述

...

## Install(安裝)

npm install --save ...

## Usage(使用)

...

... 其他內容 ...

## Donation

...

## Contact me(聯系我)

...

## License

[MIT](http://opensource.org/licenses/MIT) Copyright (c) 2018 - forever Naufal Rabbani

test 單元測試

至于單元測試你可以另外請自行選擇相關庫進行測試,也可以按照我的習慣進行測試。

在測試前你需要了解一下mochachai這兩個庫,這里放上教程你可以看看:測試框架 Mocha 實例教程

安裝 mochachai

npm install --save-dev mocha chai

test/index.js:

// 斷言庫 chai.js
var expect = require('chai').expect;
var dataType = require('../src/index');

// 測試腳本里面應該包括一個或多個describe塊,稱為測試套件(test suite)
describe('基本數據類型', function () {
  // 每個describe塊應該包括一個或多個it塊,稱為測試用例(test case)
  // 基本數據類型
  it('undefined-類型檢測測試', () => {
    // 斷言
    expect(dataType(undefined)).to.equal('undefined');
  });
  it('null-類型檢測測試', () => {
    expect(dataType(null)).to.equal('null');
  });
  it('string-類型檢測測試', () => {
    expect(dataType('abc')).to.equal('string');
  });
  it('boolean-類型檢測測試', () => {
    expect(dataType(true)).to.equal('boolean');
  });
  it('number-類型檢測測試', () => {
    expect(dataType(1)).to.equal('number');
  });
});

describe('引用數據類型', function () {
  it('array-類型檢測測試', () => {
    expect(dataType([1])).to.equal('array');
  });
  it('object-類型檢測測試', () => {
    expect(dataType({})).to.equal('object');
  });
  it('function-類型檢測測試', () => {
    expect(dataType(function () {})).to.equal('function');
  });
});

describe('其他數據類型', function () {
  it('date-類型檢測測試', () => {
    expect(dataType(new Date())).to.equal('date');
  });
  it('regex-類型檢測測試', () => {
    expect(dataType(new RegExp("\\w+"))).to.equal('regexp');
  });
});

通過命令行測試:

npm run test

結果如下:

$ npm run test

> my-npm-libs@1.0.1 test /Users/yanmo/Public/mynpm/my-npm-libs
> mocha --recursive



  基本數據類型
    ? undefined-類型檢測測試
    ? null-類型檢測測試
    ? string-類型檢測測試
    ? boolean-類型檢測測試
    ? number-類型檢測測試

  引用數據類型
    ? array-類型檢測測試
    ? object-類型檢測測試
    ? function-類型檢測測試

  其他數據類型
    ? date-類型檢測測試
    ? regex-類型檢測測試


  10 passing (12ms)

至此一個基本的簡單的npm第三方庫構建完成。下面我們進行其他的發布工作。

發布 npm 包

進入項目根目錄,登錄剛剛申請的npm 賬號。登錄完成以后執行提交。

npm login # 登陸

npm publish # 發布

發布npm包的時候需要注意把npm倉庫鏡像庫,從國內的淘寶源切換到npm國外源,不然無法提交。

這里我做了一個shell文件,用以簡化你的提交操作,你在根目錄下新建一個文件npm-publish.sh,內容如下:

#!/usr/bin/env bash

echo "\033[0;32m?\033[0m \033[36m請輸入你的新發布的版本號(ex:1.0.0):\033[0m"

read version

# 處理 package.json
sed -i -e "s/\"version\": \(.*\)/\"version\": \"$version\",/g" 'package.json'
if [ -f "package.json-e" ];then
  rm 'package.json-e'
fi
echo '\033[36m版本號修改成功\033[0m'

npm config get registry # 檢查倉庫鏡像庫

npm config set registry=http://registry.npmjs.org # 設置倉庫鏡像庫: 淘寶鏡像https://registry.npm.taobao.org

echo '\033[36m請進行登錄相關操作:\033[0m'

npm login # 登陸

echo "-------\033[36mpublishing\033[0m-------"

npm publish # 發布

npm config set registry=https://registry.npm.taobao.org # 設置為淘寶鏡像

echo "\033[36m 完成 \033[0m"
exit

然后,可以通過如下命令運行:

sh npm-publish.sh

執行效果如圖:

sh npm-publish.sh結果

當你的npm包發布后,可以通過如下格式的內容訪問到你的包:

unpkg.com/:package@:version/:file

訪問結果如圖:

unpkg.com

這也意味著你可以通過<script>標簽的形式訪問你的包,我猜你需要了解:UNPKG

git提交

git init
git add -A
git commit -m "first commit"
git remote add origin XXX
git push -u origin master

Usage(使用)

發布成功后就可以使用了。使用有兩種形式,一種是 npm 安裝,一種是 <script> 引用。

npm 安裝:

npm install --save my-npm-libs
import myNpmLibs from 'my-npm-libs'
var a = [1, 2, 3, 4, 1, 5, 1, 7]
console.log(myNpmLibs(a)) // array
// 或者
const myNpmLibs = require('my-npm-libs')
var a = [1, 2, 3, 4, 1, 5, 1, 7]
console.log(myNpmLibs(a)) // array

<script>使用

<script src="http://unpkg.com/my-npm-libs@1.0.2/lib/index.js"></script>
<script>
  console.log(window.dataType);
  var a = [1, 2, 3, 4, 1, 5, 1, 7];
  console.log(dataType(a));
</script>

run(運行)

# git clone ...
git clone https://github.com/nongshuqiner/my-npm-libs.git

# enter
cd my-npm-libs

# install dependencies
npm install

# open examples HTML
npm run examples

# 運行此命令將所有代碼從 src 目錄編譯到 lib
npm run build

# 測試
npm run test

Donation(打賞)

payment-code.png

Contact me(聯系我)

Just Contact Me At:

結語

至此,我們發布的包的工作就徹底完成了。

我參考學習了很多的其他的第三方庫以及工具網站,這里放上一些鏈接供大家參考:

unpkg
b64-to-blob
The anatomy of a vanilla JavaScript plugin
如何定義一個高逼格的原生JS插件
How to write and build JS libraries in 2018
Building Your Own JavaScript Modal Plugin
How to write a frontend JavaScript plugin using ES6 + SASS + Webpack

在發布之前可以將這整個目錄扔到另一個項目的 node_modules 文件夾中來測試我們寫的功能是否正確。

提示:后面還有精彩敬請期待,請大家關注我的專題:web前端。如有意見可以進行評論,每一條評論我都會認真對待。覺得有用卻不點贊的,隔壁老X送來問候。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容