詳解從零建立本身的NPM包

碼路工人 CoderMonkey
轉載請註明做者與出處

原文連接yuquejavascript


之前 JavaScript 只能運行在瀏覽器端,html

有了 Nodejs 環境,JavaScript 也能夠在後端運行了。java

NPM 是用於 Nodejs 的 JavaScript 包管理器,node

提供了大量的輪子,讓老司機程序員瞬間提速起飛。webpack


在工做學習之餘,git

不(nu)甘(li)寂(shang)寞(jin)的碼農們有機會也要嘗試下,程序員

造造輪子造造車。github


如下爲碼路工人造輪過程,web

記錄開發一個簡單的JS數據結構包,npm

分享出來與工友們學習探討。


本例中碼路工人作了一個使用JavaScript實現數據結構的包
npm install data-struct-js
https://github.com/codermonkie/data-struct-js


0. 前提


前提是安裝了 Nodejs,NPM 會隨 Nodejs 一塊兒安裝。

若是沒有 Node 環境,應該也不會有 NPM 包開發的需求了。


1. NPM用戶註冊


既然是 NPM 包,首先天然是要有 NPM 的帳戶。

註冊很簡單,去官網。

[NPM 官網](www.npmjs.com/)


另:學習的話,這裏的中文文檔網站不錯:

[NPM 中文文檔](www.npmjs.cn/)


記住用戶名和密碼,在發佈時要用到。


2. 新建倉庫並初始化一個 NPM 項目


2.1 Github 或 Gitee 上新建倉庫

碼路工人這個項目就叫 data-struct-js 了。

克隆到本地。

git clone https://github.com/CoderMonkie/data-struct-js.git複製代碼


2.2 初始化 NPM 項目

VSCode 打開 data-struct-js 文件夾,終端中執行

npm init -y複製代碼

不加 -y 的話,須要一步步的確認或手動輸入

加上 -y 的參數就會所有以默認生成


上面這個命令自動爲咱們生成了 package.json 文件。

{
  "name": "data-struct-js",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/CoderMonkie/data-struct-js.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/CoderMonkie/data-struct-js/issues"
  },
  "homepage": "https://github.com/CoderMonkie/data-struct-js#readme"
}複製代碼


各項目根據實際作適當修改。

其中的 url 地址,

是根據咱們 github 項目的 git 信息來生成的。

git 信息存在於 .git 文件夾中。

各屬性咱們在修改時再作具體說明。


3. 準備開始 NPM 包的開發


3.1 編輯 package.json 文件


這裏說明一下相關屬性項目,

  • name:即項目名
  • version:即包的版本
  • description:描述信息
  • main:指定入口文件
  • scripts:腳本命令
  • repository:源碼倉庫地址
  • keywords:關鍵詞
  • author:做者信息
  • license:版權類型
  • bugs:bug反饋
  • homepage:項目主頁


其中,

必須包含的項目有:nameversion

做者信息格式官方建議

Your Name <email@example.com> (http://example.com)複製代碼

版權類型,本項目中改成了限制最小的 MIT 類型。


本例中修改完成後的 package.json 文件:

{
  "name": "data-struct-js",
  "version": "0.0.1",
  "description": "Provide commonly used data-structures for javascript.",
  "main": "index.js",
  "scripts": {
    "compile": "npx babel src --out-dir compiled"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/CoderMonkie/data-struct-js.git"
  },
  "keywords": [
    "data-structure",
    "javascript"
  ],
  "author": "Mao NianYou <maonianyou@gmail.com> (http://github.com/codermonkie)",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/CoderMonkie/data-struct-js/issues"
  },
  "homepage": "https://github.com/CoderMonkie/data-struct-js#readme"
}
複製代碼


除了上面列出的之外,

還會有 dependenciesdevDependencies

分別表示項目的依賴包以及項目開發中用到的依賴包。

這裏不寫出來,是由於,當咱們要添加依賴時,

經過 npm install --savenpm install --save-dev 來安裝,

所依賴的包及版本信息都會添加到上面對應的屬性中,

基本無需手動編輯。


3.2 規劃項目目錄和文件


能夠比這個更復雜,

本例中最基本的結構包括如下:

data-struct-js
|--examples
|  |--(for sample files)
|--lib
|  |--(for compiled files)
|--src
|  |--(for development files)
|--.babelrc
|--.gitignore
|--.npmignore
|--index.js
|--LICENSE
|--package.json
|--README.md
|複製代碼

*注:上面有子層次的表示文件夾,其它爲文件


3.2.1 目錄結構簡介

  • data-struct-js:本項目根目錄
  • examples:存放本項目的示例用文件
  • lib:存放編譯結果(鑑於瀏覽器兼容性,ES6標準的JavaScript編譯爲ES5)
  • src:開發目錄
  • .babelrc:babel的配置文件(使用webpack的話也能夠寫在 webpack.config 中)
  • .gitignore:git 配置文件,配置忽略版本管理的對象
  • .npmignore:npm配置文件,配置發佈到 npm 時的忽略對象
  • index.js:統一導出的出口文件
  • LICENSE:版權信息文件,在新建倉庫時根據選擇自動生成
  • package.json:項目管理文件,項目初始化時自動生成
  • README.md:項目說明文件,可在新建倉庫時生成該文件,根據項目內容自行編輯
  • 另外,若是使用 webpack 的話,還要有一個 webpack.config 的配置文件


(注:本文項目中將 webpack 配置在了 examples 下的樣例工程中 )


3.2.2 特殊文件說明

.babelrc

babel 讓咱們可使用最新 JavaScript 語法,

而不用擔憂瀏覽器兼容問題,

由於它能夠幫咱們把 ES6 的代碼編譯爲 ES5。

示例:

{
    "presets": [
        "@babel/preset-env"
    ]
}複製代碼


.gitignore

在此配置 git 版本管理要忽略的文件或文件夾。

新建倉庫時根據選擇能夠生成默認的配置。

本身編輯的話,至少應該有如下:

examples/dist/
lib/
node_modules/
.npmignore複製代碼


.npmignore

非 npm 發佈對象配置。

示例:

examples/
node_modules/
src/
.babelrc
.gitignore
.npmignore複製代碼


LICENSE

在新建倉庫時根據選擇的版權類型會自動生成該文件。

示例:

MIT License

Copyright (c) 2019 Mao NianYou

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
複製代碼


package.json

項目配置管理文件,參照上文 3.1 中已做的說明。


README.md

使用 markdown 標記的項目說明文檔,

介紹本身項目狀況。好比:

# 背景介紹
# 項目介紹
# 查看示例
# 使用說明
# License
# 聯繫
# 貢獻者/鳴謝複製代碼

根據以上大項目填寫具體內容。


4. 開發咱們本身的 NPM 包


配置完上面的內容,到了主要環節,

開發咱們的 NPM 包。


4.1 安裝相關依賴


在本次開發中,咱們當前僅用到了 babel 相關的包。

在 VSCode 終端(或其它命令行工具)執行如下命令:

npm install --save-dev @babel/cli
npm install --save-dev @babel/core
npm install --save-dev @babel/preset-env複製代碼


也能夠簡寫爲如下一條命令:

npm i -D @babel/cli @babel/core @babel/preset-env複製代碼


--save-dev 等同於 -D

會添加依賴到 devDependencies 中


--save 等同於 -S

會添加依賴到 dependencies 中


由於代碼中用到了類屬性,僅安裝以上的話,運行 babel 會報錯,

根據錯誤信息,還需安裝 @babel/plugin-proposal-class-properties

注:參見下文代碼 ArrayBasedStruct.js

Error: Cannot find module '@babel/plugin-proposal-class-properties' from...複製代碼


  1. 安裝
npm i -D @babel/plugin-proposal-class-properties複製代碼


  1. 修改 babel 配置文件(.babelrc),添加 plugins
{
    "presets": [
        "@babel/preset-env"
    ],
    "plugins": [
      ["@babel/plugin-proposal-class-properties",
          {
              "loose": true
          }
      ]
    ]
}複製代碼


安裝完成後,package.json 文件中就增長了 devDependencies 字段。

{
  "name": "data-struct-js",
  "version": "0.0.1",
  "description": "Provide commonly used data-structures for javascript.",
  "main": "index.js",
  "scripts": {
    "compile": "npx babel src --out-dir compiled"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/CoderMonkie/data-struct-js.git"
  },
  "keywords": [
    "data-structure",
    "javascript"
  ],
  "author": "CoderMonkey <maonianyou@gmail.com> (http://github.com/codermonkie)",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/CoderMonkie/data-struct-js/issues"
  },
  "homepage": "https://github.com/CoderMonkie/data-struct-js#readme",
  "devDependencies": {
    "@babel/cli": "^7.7.5",
    "@babel/core": "^7.7.5",
    "@babel/plugin-proposal-class-properties": "^7.7.4",
    "@babel/preset-env": "^7.7.6"
  }
}
複製代碼


4.2 ES6 代碼實現(示例:Stack.js)


由於本文主題是講如何從零發佈一個本身的 npm 包,

代碼部分僅舉一例說明,完整代碼可查看:

[Github](github.com/CoderMonkie…)


如下爲本項目中棧結構的實現代碼,

其中引用到的其它文件,

一併貼在下方以供參考。

data-struct-js/src/Stack.js

import {
    deepCopy,
    isFunction
} from './common_utils'
import ArrayBasedStruct from './ArrayBasedStruct'

/**
 *棧結構
 *
 * @export
 * @class Stack
 * @extends {ArrayBasedStruct}
 */
export default class Stack extends ArrayBasedStruct {
    constructor() {
        super()
    }

    /**
     *將新元素入棧
     *
     * @param {*} element
     * @memberof Stack
     */
    push(element) {
        return this.__items.push(element)
    }

    /**
     *棧頂元素出棧
     *
     * @returns 棧頂元素
     * @memberof Stack
     */
    pop() {
        return this.__items.pop()
    }

    /**
     *查看棧頂元素
     *
     * @returns 棧頂元素
     * @memberof Stack
     */
    peek() {
        if (!this.__items.length) return undefined
        return deepCopy(this.__items[this.__items.length - 1])
    }

    /**
     *遍歷棧結構
     *
     * @param {function} callback
     * @param {boolean} [reversal=false]
     * @memberof Stack
     */
    traverse(callback, reversal = false) {
        // 檢查回調函數
        if (!isFunction(callback)) return

        var items = this.getItems(this.__items)
        var from = reversal ? items.length - 1 : 0
        var to = reversal ? 0 : items.length - 1
        // 循環條件
        var loopCondition = function (current) {
            if (reversal) {
                return current >= to
            } else {
                return current <= to
            }
        }
        // 遊標前進
        var stepIn = function (current) {
            if (reversal) {
                return current - 1
            } else {
                return current + 1
            }
        }

        // 進行遍歷
        for (var index = from; loopCondition(index); index = stepIn(index)) {
            var element = items[index];
            callback(element, index)
        }
    }

    /**
     *轉爲字符串
     *
     * @returns
     * @memberof Stack
     */
    toString() {
        return this.__items.map(element => element.toString()).join(' ')
    }
}複製代碼


data-struct-js/src/common_utils.js
本身實現的經常使用方法

/**
 *深拷貝
 *
 * @export
 * @param {*} source 要拷貝的對象
 * @returns 深拷貝結果
 */
export function deepCopy(source) {
    var dest
    if(Array.isArray(source)) {
        dest = []
        for (let i = 0; i < source.length; i++) {
            dest[i] =deepCopy(source[i])
        }
    }
    else if(toString.call(source) === '[object Object]') {
        dest = {}
        for(var p in source){
            if(source.hasOwnProperty(p)){
                dest[p]=deepCopy(source[p])
            }
        }
    }
    else {
        dest = source
    }
    return dest
}

/**
 *判斷傳入參數是否爲函數
 *
 * @export
 * @param {*} func 參數(函數)
 * @returns true:是函數 false:不是函數
 */
export function isFunction (func) {
    if (!func || toString.call(func) !== '[object Function]') return false
    return true
}複製代碼


data-struct-js/src/ArrayBasedStruct.js

給棧結構提供的基類

import { deepCopy } from "./common_utils"

/**
 *基於數組實現的數據結構的基類
 *
 * @class ArrayBasedStruct
 */
class ArrayBasedStruct {
    constructor() {
        this.__items = []
    }

    /**
     *獲取全部元素
     *
     * @returns 元素集合
     * @memberof Stack
     */
    getItems () {
        return deepCopy(this.__items)
    }

    /**
     *數據結構實例中是否包含元素
     *
     * @readonly
     * @memberof ArrayBasedStruct
     */
    get isEmpty() {
        return this.__items.length === 0
    }

    /**
     *數據結構實例的元素個數
     *
     * @readonly
     * @memberof ArrayBasedStruct
     */
    get size() {
        return this.__items.length
    }

    /**
     *清空數據結構中的元素
     *
     * @memberof ArrayBasedStruct
     */
    clear() {
        this.__items.length = 0
    }
}

export default ArrayBasedStruct複製代碼


經過 index.js 文件統一導出

data-struct-js/index.js

import { Stack } from './lib/Stack'
export { Stack }複製代碼

注:目前本示例中只有 Stack,後續添加的也都是在這裏統一導出


4.3 使用 babel 進行編譯


還記得咱們在 package.json 中配置的腳本命令嗎,

"scripts": {
    "compile": "npx babel src/ --out-dir lib"
  },複製代碼


執行方法:

npm run compile複製代碼


執行結果:

> data-struct-js@0.0.1 compile F:\path\to\data-struct-js
> npx babel src/ --out-dir lib

Successfully compiled 3 files with Babel.複製代碼


編譯執行成功,能夠看到 data-struct-js/lib/ 文件夾下生成了編譯後的文件。

咱們作的包在被別人使用時,下載和引入的就是這些編譯後的文件。


5. 測試本身的 NPM 包


跟普通項目開發同樣 NPM 包開發也須要測試。

經過測試,減小或避免產生 bug。


5.1 建立 demo 項目

data-struct-js/examples/ 路徑下,新建咱們的測試用項目。

cd examples
npm init
package name: data_struct_js_demo複製代碼

生成的 package.json 項目文件:

{
  "name": "data_struct_js_demo",
  "version": "1.0.0",
  "description": "demo for data-struct-js",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT"
}複製代碼

告訴你個小祕密:

這個工程位於咱們主工程的目錄底下,

這裏要用到的依賴包,若是本工程沒有安裝,

則會自動查找上層目錄,

也就是,外層安裝了的話就可用。

另外,

找到根目錄也沒有的話還會查看全局安裝,

都沒有的時候纔會報錯


5.2 完成相關配置

5.2.0 安裝 data-struct-js

注意:

如下安裝方式,不適用於本次示例,

由於 demo 工程位於 package 工程目錄下,

會致使遞歸引用。

僅當不在同一路徑下建立新工程時能夠。

npm install --save-dev ../../data-struct-js複製代碼

因此,這裏咱們須要手動引用咱們包裏的文件。

data-struct-js/examples/src/index.js

// 直接引入原文件
import Stack from '../../src/Stack'

// 或編譯後的也能夠
// import Stack from '../../lib/Stack'複製代碼


注:

這裏有個坑,就是模塊化方式必須統一!

也就是,若是代碼裏用 ES6 的模塊化方式(import/export),

那麼這裏若是用 Node 的模塊化(require/module.exports=),

就會報錯。(new 導出的class的時候報:xxx is not a constructor)

=> data-struct-js/index.js 也是這樣


5.2.1 安裝其它所需依賴包

這裏列出咱們本次用到的開發依賴:

(爲了不太長,分兩行寫)

npm i -D webpack webpack-cli webpack-dev-server
npm i -D html-webpack-plugin clean-webpack-plugin複製代碼


data-struct-js/examples/package.json

{
  "name": "data_struct_js_demo",
  "version": "1.0.0",
  "description": "Demo for data-struct-js",
  "main": "index.js",
  "scripts": {
  },
  "author": "CoderMonkey <maonianyou@foxmail.com>",
  "license": "MIT",
  "devDependencies": {
    "babel-loader": "^8.0.6",
    "clean-webpack-plugin": "^3.0.0",
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.41.3",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.9.0"
  }
}
複製代碼


5.2.2 配置 webpack,添加腳本命令

data-struct-js/examples/webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlWebpackPlugin = new HtmlWebpackPlugin({
    template: path.join(__dirname, "./src/index.html"),
    filename: "./index.html"
});
const {CleanWebpackPlugin} = require("clean-webpack-plugin");

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, "./src/index.js"),
    output: {
        path: path.join(__dirname, "dist/"),
        filename: "[name].[hash:6].js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                use: "babel-loader",
                exclude: /node_modules/
            }
        ]
    },
    plugins: [
        htmlWebpackPlugin, new CleanWebpackPlugin()
    ],
    resolve: {
        extensions: [".js", ".jsx"]
    },
    devServer: {
        port: 8080
    }
};
複製代碼


data-struct-js/examples/package.json

// ...略...
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "webpack --config webpack.config.js"
  },
// ...略...複製代碼


5.2.3 編寫簡單的測試內容,啓動並查看

data-struct-js/examples/src/index.js

// 直接引入原文件
import Stack from '../../src/Stack'

var stack = new Stack()
for (var i = 0; i < 5; i++) {
    stack.push(i)
}
console.log('isEmpty: ', stack.isEmpty)
console.log('size: ', stack.size)
console.log(stack.toString())
console.log(`pop: `, stack.pop())

stack.traverse((ele,index)=>{
    console.log(`Traversing-Stack:${index}: ${ele}`)
})

stack.traverse((ele,index)=>{
    console.log(`Traversing-Stack:${index}: ${ele}`)
}, true)

console.log(`claer: `, stack.clear())
console.log('isEmpty: ', stack.isEmpty)
console.log('size: ', stack.size)複製代碼

data-struct-js/examples/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Demo of data-struct-js</title>
</head>
<body>
</body>
</html>複製代碼


5.3 確認運行結果

執行咱們配置的腳本命令,

啓動本地服務,並打開網頁:

注意當前目錄:data-struct-js/examples

npm run start複製代碼


將輸出結果附在代碼後面方便閱讀

// 直接引入原文件
import Stack from '../../src/Stack'

var stack = new Stack()
for (var i = 0; i < 5; i++) {
    stack.push(i)
}
console.log('isEmpty: ', stack.isEmpty)
// isEmpty:  false

console.log('size: ', stack.size)
// size:  5

console.log(stack.toString())
// 0 1 2 3 4

console.log(`pop: `, stack.pop())
// pop:  4

stack.traverse((ele,index)=>{
    console.log(`Traversing-Stack:${index}: ${ele}`)
})
// Traversing-Stack:0: 0
// Traversing-Stack:1: 1
// Traversing-Stack:2: 2
// Traversing-Stack:3: 3

stack.traverse((ele,index)=>{
    console.log(`Traversing-Stack:${index}: ${ele}`)
}, true)
// Traversing-Stack:3: 3
// Traversing-Stack:2: 2
// Traversing-Stack:1: 1
// Traversing-Stack:0: 0

console.log(`claer: `, stack.clear())
// claer:  undefined

console.log('isEmpty: ', stack.isEmpty)
// isEmpty:  true

console.log('size: ', stack.size)
// size:  0複製代碼


TODO

這樣就可以簡單地確認結果了,

以後咱們再考慮使用測試框架。

結果代表運行正確符合預期。

這樣咱們就能夠着手發佈了。


6. 發佈到 NPM 上


注:路徑回到本項目根目錄,即 data-struct-js/


6.1 發佈須知

6.1.1 用戶登陸

未登陸狀態下直接發佈的話會報如下錯誤:

npm ERR! publish Failed PUT 403
npm ERR! code E403
npm ERR! [no_perms] Private mode enable, only admin can publish
this module [no_perms] Private mode enable,
only admin can publish this module: data-struct-js複製代碼


登陸的話,執行:

npm login複製代碼


npm login 根據提示輸入 username 跟 password,

而後報了錯,發現 npm 源用的 taobao,

這裏注意:發佈 npm 包時,要將源切換到 npm。

npm ERR! code E409
npm ERR! Registry returned 409 for PUT on
https://registry.npm.taobao.org/-/user/org.couchdb.
user:maonianyou: [conflict] User maonianyou already exists複製代碼


碼路工人這裏用的 nrm 來管理 安裝源。

切換:

> nrm use npm

    Registry has been set to: https://registry.npmjs.org/複製代碼


成功登陸:

> npm login
Username: yourname
Password: (yourpassword)
Email: (this IS public) yourname@somemail.com
Logged in as yourname on https://registry.npmjs.org/.複製代碼


註冊用戶時郵箱未驗證也是會報錯的:

npm ERR! publish Failed PUT 403
npm ERR! code E403
npm ERR! you must verify your email before publishing a new package:
https://www.npmjs.com/email-edit : your-package複製代碼


6.1.2 不可重名

首先要在 npm 官網檢索一下有沒有重名的包,

不然發佈的話會因沒有權限報如下錯誤:

npm ERR! publish Failed PUT 403
npm ERR! code E403
npm ERR! You do not have permission to publish "xxxxxxx". Are you logged in as
the correct user? : xxxxxxxxx複製代碼


6.2 發佈


6.2.1 編譯&發佈

注意:

  • 先編譯 npm run compile
  • 再發布 npm publish
npm run compile
npm publish複製代碼


爲了方便,咱們配置一條腳本命令:

data-struct-js/package.json

// ...略...
  "scripts": {
    "dopublish": "npm run compile && npm publish"
  },
// ...略...複製代碼

之後就能夠:

npm run dopublish複製代碼


6.2.2 發佈成功

>npm publish
npm notice
npm notice package: data-struct-js@0.0.1
npm notice === Tarball Contents ===
npm notice 866B  package.json
npm notice 55B   index.js
npm notice 1.1kB LICENSE
npm notice 26B   README.md
npm notice 1.8kB lib/ArrayBasedStruct.js
npm notice 947B  lib/common_utils.js
npm notice 5.1kB lib/Stack.js
npm notice === Tarball Details ===
npm notice name:          data-struct-js
npm notice version:       0.0.1
npm notice package size:  3.7 kB
npm notice unpacked size: 9.9 kB
npm notice shasum:        2001495314blsd9gaj9g0b7b15aewr6we5207aac
npm notice integrity:     sha512-UzOx7tFP8/qJp[...]DPJ1wherlFJyQ==
npm notice total files:   7
npm notice
+ data-struct-js@0.0.1複製代碼


到 npm 官網查看發佈的 data-struct-js

www.npmjs.com/package/dat…


6.3 下載安裝


在本身的工程中安裝測試一下。

npm install data-struct-js複製代碼


引入使用

import { Stack } from 'data-struct-js'複製代碼

參照:

5.3 確認運行結果


6.4 撤銷發佈

6.4.1 撤銷整個包

npm unpublish --force your-package-name複製代碼

6.4.2 僅撤銷某個版本

npm unpublish <package-name>@<version>複製代碼


看到網上有說 :「

超過24小時就不能刪除了

但查看官網,是 72 小時內可撤銷發佈,

超過 72 小時的就須要聯繫 npm Support 了。

*沒有實踐確認,以官網說明爲準吧*


7. 關於包的更新


增長功能或者修改bug後,

就要更新咱們的 package。

這裏主要涉及到版本管理。


7.0 不改版本不能發佈

修改項目代碼後,版本號不變,

繼續發佈的話,就會報錯:

npm ERR! publish Failed PUT 403
npm ERR! code E403
npm ERR! You cannot publish over the previously published versions:
0.0.1. : data-struct-js複製代碼


7.1 語義化版本管理(semantic versioning)


這裏引用 npm 官方文檔的表格,

加入部分中文翻譯。



Code status Stage Rule Example version

1

First release
首次發佈
New product
新產品
Start with 1.0.0 1.0.0

2

Backward compatible bug fixes
向後兼容
bug 修改
Patch release
發佈補丁更新
Increment the third digit
第三位數增加
1.0.1

3

Backward compatible new features
向後兼容
增長新特性

Minor release
發佈小版本更新

Increment the middle digit and reset last digit to zero
中間的版本號增加,同時末尾版本號清零
1.1.0

4

Changes that break backward compatibility
不向後兼容的變動
Major release
發佈主版本更新
Increment the first digit and reset middle and last digits to zero
首位版本號增加,第二第三都清零
2.0.0


上面,除了 1 是首次新發布,後面 2 3 4 分別爲 patch / minor / major。


7.2 手動修改 version 後發佈

data-struct-js/pakcage.json

{
  "version": "1.0.1"
}複製代碼


npm publishs複製代碼


7.3 自動增長版本號發佈

npm version <update_type>
<update_type>爲:

  • patch 0.0.*
  • major *.0.0
  • minor 1.*.0
npm version patch

npm publish複製代碼


以上命令,

就是將咱們的包按照語義化的版本管理,

自動變動版本號,而後發佈。


8. 其它


8.1 修改 npm 初始化時的信息

執行如下命令,可修改默認的初始化內容

> npm set init.author.email "example-user@example.com"
> npm set init.author.name "example_user"
> npm set init.license "MIT"複製代碼


8.2 關於 scoped/unscoped

還記得咱們上面用到的 babel 相關的幾個包嗎,

@babel/cli
@babel/core
@babel/preset-env複製代碼


你會注意到,它的這種格式,

跟安裝咱們此次開發的包不同

npm install @babel/cli

npm install data-struct-js複製代碼


這個 @scopename 就是 scoped 的限定,

如包名:@codermonkey/data-struct-js

由於私有包是收費的,冠名只能設爲公開,

因此發佈時需加上如下參數:

npm publish --access public複製代碼

發佈出來就是:

@yourscope/packagename

1.0.0 · Public · Published ... ago


Scope 用以關聯一系列的包,

每一個用戶和組織都有本身的 Scope,

前面咱們提到發佈包不能夠重名,

其實若是重名的話,

只要不在同一個 Scope 下應該也是能夠的。

不知道會不會違反包名相似的規則
不過也有與本示例稍微相似的包名,

咱們的仍是發佈成功了


能夠在登陸的時候指定 scope 名稱:

npm login --registry=http://reg.example.com --scope=@myco複製代碼


也能夠在 config 中配置指定源的 scope:

npm config set @myco:registry http://reg.example.com複製代碼


更多關於 Scope 詳情,請參看官網:

docs.npmjs.com/misc/scope


*注:本文參考了 NPM 官網文檔


碼路工人的微信公衆號

CoderPower_QRCode.jpg

~歡迎聯繫交流指點斧正~

-end-

相關文章
相關標籤/搜索