發布一個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文檔,以查看更多詳細內容。
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-js
和 regenerator
。
安裝 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+
環境。
這意味著你可以使用像 Promise
或 WeakMap
這樣的新內置函數,像 Array.from
或 Object.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 單元測試
至于單元測試你可以另外請自行選擇相關庫進行測試,也可以按照我的習慣進行測試。
在測試前你需要了解一下mocha,chai這兩個庫,這里放上教程你可以看看:測試框架 Mocha 實例教程
安裝 mocha
和 chai
:
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
執行效果如圖:
當你的npm包發布后,可以通過如下格式的內容訪問到你的包:
unpkg.com/:package@:version/:file
訪問結果如圖:
這也意味著你可以通過<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(打賞)
Contact me(聯系我)
Just Contact Me At:
- Email: ym1185509297@163.com
- 簡書: 言墨兒
結語
至此,我們發布的包的工作就徹底完成了。
我參考學習了很多的其他的第三方庫以及工具網站,這里放上一些鏈接供大家參考:
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送來問候。