背景
在做表單的時候,會遇到很多的表單項的驗證工作,幾乎很多驗證都是重復的,有一個比較好的lodash庫來做了這些工作,但是里面有些方法與自己的期望不符。比如,lodash.isEmpty(2) // true是會認為是空的。這顯然與實際的業(yè)務是不符的。另外還有一些數(shù)字校驗等其他的常用的校驗方法,想結合lodash做一個自己的庫,這樣比較有利于業(yè)務的開發(fā)。
基于以上的考量,準備開一個自己的jsUtils庫。
要點
- 新建個npm賬號
- 項目初始化
- 發(fā)布
實踐
0. 什么是npm?
npm是javascript的包管理工具,是前端模塊化下的一個標志性產(chǎn)物
簡單地地說,就是通過npm下載模塊,復用已有的代碼,提高工作效率
- 1.從社區(qū)的角度:把針對某一特定問題的模塊發(fā)布到npm的服務器上,供社區(qū)里的其他人下載和使用,同時自己也可以在社區(qū)里尋找特定的模塊的資源,解決問題
- 2.從團隊的角度:有了npm這個包管理工具,復用團隊既有的代碼也變的更加地方便
1. 新建個npm賬號
在npmjs上注冊一個自己的賬號。
點擊創(chuàng)建賬號注冊一個自己的賬號。

如果已經(jīng)有自己的賬號,登錄即可:npm login。
2. 項目初始化
新建一個項目,cd進去,然后執(zhí)行npm init來初始化項目的配置。
在執(zhí)行npm init之前,有兩點需要我們注意一下:
- 包名不能重復
- npm對包名的限制:不能有大寫字母/空格/下劃線
我們首先要驗證一下我們即將要起的包名是否存在。驗證我們即將要起的包名是否存在的方式有兩種:
- 去npm倉庫中輸入一下“我們即將要起的包名”,看是否可以查找到。like:
search1.gif
- 去npm倉庫中輸入一下“我們即將要起的包名”,看是否可以查找到。like:
- 直接使用
npm install <packagename>,如果能夠下載下來,那么說明這個包名在npm倉庫是存在的,也就是不可使用的。
- 直接使用
這樣提前驗證一下,能夠避免一些發(fā)布(npm publish)時會出現(xiàn)的這個錯誤。

這個錯誤就是說,npm倉庫中已經(jīng)存在這個包名的庫了,我沒有權限去發(fā)布。
配置項:
| 配置項 | 意義 | 默認值 | 備注 |
|---|---|---|---|
| name | 填寫你這個包的名字 | 默認是你這個文件夾的名字 | 不過這里要著重說一下,最好先去npm上找一下有沒有同名的包。最好的測試方式就是,在命令行里面輸入npm install 你要取的名字,如果報錯,那么很好,npm上沒有跟你同名的包,你可以放心大膽地把包發(fā)布出去。如果成功下載下來了。。。那么很不幸,改名字吧。。。 |
| version | 你這個包的版本 | 默認是1.0.0 | |
| description | 項目描述 | ||
| entry point | 入口文件 | 默認是Index.js | 你也可以自己填寫你自己的文件名 |
| test command | 測試命令 | ||
| git repository | 這個是git倉庫地址 | 如果你的包是先放到github上或者其他git倉庫里,這時候你的文件夾里面會存在一個隱藏的.git目錄,npm會讀到這個目錄作為這一項的默認值。如果沒有的話,直接回車繼續(xù)。 | |
| keyword | 這個是一個重點,這個關系到有多少人會搜到你的npm包。盡量使用貼切的關鍵字作為這個包的索引。 | ||
| author | 作者 | 寫你的賬號或者你的github賬號吧 | |
| license | 執(zhí)照 | 這個直接回車,開源文件來著。。。 |
然后它就會問你Are you ok?
回車Ok!
然后我們回到我們的文件目錄里面去看一看,發(fā)現(xiàn)多出來一個package.json文件,點進去基本上就是下面這張圖輸出的信息。
{
"name": "jsutils-100",
"version": "1.0.1-alpha.2",
"author": "spring.hehe.v5",
"dependencies": {
"lodash": "^4.17.10"
},
"scripts": {
"test": "jest"
},
"devDependencies": {
"jest": "^23.5.0"
},
"description": "在 lodash 基礎上擴展的一些 jsUtils",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/springHyc/jsUtils.git"
},
"keywords": [
"jsUtils"
],
"license": "ISC",
"bugs": {
"url": "https://github.com/springHyc/jsUtils/issues"
},
"homepage": "https://github.com/springHyc/jsUtils#readme"
}
3. 寫項目
首先入口文件是index.js,或者是你剛才修改了那個entry point的值,那么你這個文件名也跟著改為那個值。

因為我把封裝好的代碼都放在了src里面,所以,index.js里面也就一句話:
module.exports = require("./src");
而大多數(shù)我們常見npm包里面寫的是module.exports=require('./lib')。
然后寫個readme.md文件。一般這個readme.md文件都是該項目的一些說明,比如可以放一些項目的啟動命令、構建命名等等。
CommonJS標準
我們看到上面代碼中使用CommonJS標準。一個單獨的文件就是一個模塊,模塊內將需要對外暴露的變量放到exports對象里,可以是任意對象,函數(shù),數(shù)組等,未放到exports對象里的都是私有的。用require方法加載模塊,即讀取模塊文件獲得exports對象。這里出現(xiàn)的module,exports,require是JS的新語法嗎?不是新語法,只是CommonJS的語法糖。
路徑的引用:
var Hi = require('./hi');這種是用require加載時寫的是相對路徑,讓Nodejs去指定路徑下加載模塊。如果省略相對路徑,默認就會在node_modules文件夾下找hi模塊,那很可能因為找不到而報錯。
4. 調試
本地的快捷調試方法有這種:Npm link。
4.1 Npm link
Npm link 專門用于開發(fā)和調試本地 Npm 模塊,能做到在不發(fā)布模塊的情況下,把本地的一個正在開發(fā)的模塊的源碼鏈接到項目的 node_modules 目錄下,讓項目可以直接使用本地的 Npm 模塊。 由于是通過軟鏈接的方式實現(xiàn)的,編輯了本地的 Npm 模塊代碼,在項目中也能使用到編輯后的代碼。
完成 Npm link 的步驟如下:
- 確保正在開發(fā)的本地 Npm 模塊(也就是正在開發(fā)的npm模塊)的 package.json 已經(jīng)正確配置好;
- 在本地 Npm 模塊根目錄下執(zhí)行 npm link,把本地模塊注冊到全局;
- 在項目根目錄下執(zhí)行 npm link npm-name,把第2步注冊到全局的本地 Npm 模塊鏈接到項目的 node_moduels 下,其中的 npm-name 是指在第1步中的 package.json 文件中配置的模塊名稱。
鏈接好npm包 到項目后你就可以像使用一個真正的 Npm 模塊一樣使用本地的 Loader 了。
5. 發(fā)布
5.1 添加賬戶
使用npm adduser命令來添加npm的賬戶名、密碼和郵箱即可。like:

上圖是添加成功的截圖。
5.2 發(fā)布
就可以執(zhí)行npm publish命令進行發(fā)布啦。下面就是見證奇跡的時刻啦,出現(xiàn)截圖中的樣子就是發(fā)布成功啦。

希望對你們有所幫助!
下面是我在發(fā)布jsutils-100包時遇到的一些問題的記錄,在實際發(fā)布包時,很可能你寫的是es6語法的code,那么你就需要進行一下轉換才行啦。
5.3 更新npm發(fā)布后的包
更新npm包也是使用npm publish命令發(fā)布,不過必須更改npm包的版本號,也就是package.json中的version字段,否則會報錯,like:

在這里順便說一下有有關版本的小知識點- npm的版本控制
5.4 npm的版本控制
在我們的package.json里面有一個version字段。那么,怎么在項目不斷構建的過程中調整版本呢?
npm有一套自己的版本控制標準——Semantic versioning(語義化版本)
具體體現(xiàn)為:
版本格式:主版本號.次版本號.修訂號,版本號遞增規(guī)則如下:
主版本號:當你做了不兼容的 API 修改,
次版本號:當你做了向下兼容的功能性新增,
修訂號:當你做了向下兼容的問題修正。
例如:我原本的項目是1.0.0版本的話
若是1中情況,變?yōu)?.0.1
若是2中情況,變?yōu)?.1.0
若是3中情況,變?yōu)?.0.0
通過npm version <update_type>自動改變版本
update_type為patch, minor, or major其中之一,分別表示補丁,小改,大改。
備注
語義化版本號可以在這里詳細學習
5.5 利用npm撤銷發(fā)布包
這里要說一點,取消發(fā)布包可能并不像你想象得那么容易,這種操作是受到諸多限制的,撤銷發(fā)布的包被認為是一種不好的行為
(試想一下你撤銷了發(fā)布的包[假設它已經(jīng)在社區(qū)內有了一定程度的影響],這對那些已經(jīng)深度使用并依賴你發(fā)布的包的團隊是件多么崩潰的事情!)
如果發(fā)現(xiàn)已經(jīng)發(fā)布的版本有問題,可以進行撤銷操作:npm unpublish <packagename>@<version>。
如果有權限問題,撤銷不了,可以添加--force。
撤銷還是有諸多限制的:
- 根據(jù)規(guī)范,只有在發(fā)包的24小時內才允許撤銷發(fā)布的包( unpublish is only allowed with versions published in the last 24 hours)
- 即使你撤銷了發(fā)布的包,發(fā)包的時候也不能再和被撤銷的包的名稱和版本重復了(即不能名稱相同,版本相同,因為這兩者構成的唯一標識已經(jīng)被“占用”了)
like:剛剛發(fā)布的jsutils-100@1.0.1-beta.4其實是我用來測試的,里面并沒有修改任何code,現(xiàn)在進行一下撤銷。like

現(xiàn)在我準備再重新發(fā)布jsutils-100@1.0.1-beta.4這個版本你的包,like:

遇到的問題
由于我采用的es6的語法,直接發(fā)布沒問題,但是應用到項目中,項目打包發(fā)布時就會出現(xiàn)語法錯誤。

出錯的地方就就是es6的...目前不能用到對象中。like this:

所以需要引入babel來將es6轉化一下,一開始只用的babel-preset-es2015這個的轉化還是不行,仍然是報錯,最終使用的轉化強度更大的babel-preset-stage-0來能夠徹底轉化。
like:

遺留問題
- . 為什么項目中需要使用
const lodash = require("lodash");
const jsUtils = {};
module.exports = jsUtils;
這樣的方式來組織文件呢?為什么用import lodash from "lodash"在執(zhí)行npm test時會報錯呢?
