如何發佈一個完整Node.js Module
本文會透過以下幾個段落,讓各位一步一步學習如何寫一個自已的Node.js Module並且發佈到npm package上
Node.js Module 結構
我們先建立一個 NodeModuleDemo 的資料夾 ,接下來利用 npm init 進行初始化
(這裡不用特別設置,一路按 Enter 到底即可)
Tips. 這裡可以簡單的利用VSCode 熱鍵 Ctrl + ` 開啟命令視窗
初始化完成的畫面如上
接下來我們會先建立好相關的資料夾用來分類我們的程式碼
其中 lib 資料夾是我們要寫的原始程式碼,test 資料夾則專門放我們的測試程式
最後 benchmark 資料夾裡面是用來做我們效能測試的程式
因我們這次會利用 ES6 的 Class 語法來寫我們的模組程式,所以這裡也需要加入 babel 的設定
再來為了讓我們的程式碼可以有統一的風格,我們也會加入 eslint 的設定
( babel 與 eslint 我通常會裝成全域的package ,各位可以自已選擇要安裝的目標)
先來安裝 babel 與 eslint 吧!

安裝完後,可以像上圖中,透過 –version 來確認安裝的狀況
這裡可以看到我們的 babel 版本為 6.26.0 而 eslint 則為 5.7.0
再來我們下一步先建立 babel 的設定檔,檔名為 .babelrc 放置在我們的根目錄下
內容直接設為
{
"presets": ["env"]
}
eslint 的部分則更簡單了,只需要在命令視窗輸入 eslint –init 選擇想要的範本即可,在我們的練習中,我們選擇
standard 。最後會自動在根目錄產出 .eslintrc.js 檔 ,相關的操作如下圖 (黃字標示處)

最後,因為我們希望 eslint 只檢查我們 lib 主程式目錄,所以這裡需要加入一個 .eslintignore 檔
將我們的 test 、benchmark 及輸出的 dist 資料夾做排除的動作,話不多說請看下圖

整個 Node.js Module 的目錄架構會像下圖這樣 ( formatter 、output 、index.js 可以先建立起來)

再來我們就開始動手寫我們的模組程式吧!
我們這次要做一個很簡單的文字轉換程式,輸出效果大致如下

首先我們先來寫做轉換的主程式,大致如下
export default class MyTextOutput {
constructor (formatter = null) {
this.formatter = formatter
}
getResult (text) {
if (!this.formatter) {
throw new Error('Text Formatter is required')
}
let result = this.formatter.getFormatterText(text)
return result
}
}
首先 MyTextOutput 類需要在建立時指定要用的 formatter , 最後再透過 getResult 取得轉換後的內容
而這裡我們就簡單的寫一個 SimpleFormatter 做到一個簡易的轉換效果
export default class SimpleFormatter {
getFormatterText (text) {
let trans = {
'a': 'Ä',
'b': 'ß',
'c': 'Ć'
}
let outPutTxt = ''
for (let index = 0; index < text.length; index++) {
const ele = text[index]
outPutTxt += trans[ele.toLowerCase()]
}
return outPutTxt
}
}
加入測試
在我們完成程式之後,通常會寫一段測試程式來保護你的程式。 當然,如果是採用 TDD 開發方式的話,則是先寫完你的測試程式,再寫你的主程式。但我們這裡先不介紹 TDD , 單純的來介紹一下你的測試程式該怎麼寫
在寫我們的測試程式之前,我們需要先安裝相關的套件,在這個範例中我們會用到 mocha 與 chai 這兩個套件
安裝方式如下圖

再來就是我們的測試程式了,我們這次會簡單的寫兩個案例
一個是忘記指定要使用的formatter 另一個則是我們輸入文字 abc 應該要出現我們預期的結果
完整的案例如下

要運行上述的測試案例 我們需要在 package.json 裡添加相關的 script ,參考下圖

接下來運行 npm run test 時便可自動的進行測試案例執行

3.加入typing.d.ts
這裡加入 typing 檔其實是為了讓使用者用 VSCode 在開發時,能夠擁有 Intellisense 的效果
在這裡我們透過微軟提供的 dts-gen 來產生 typeing 檔案。首先我們需要先安裝 dts-gen 這個套件
接下來比較麻煩的是,依照文件上說明,我們需要先透過 npm 安裝我們的套件,才可以產生 typing 檔
npm install -g dts-gennpm install –g nodedemomoduledts-gen --dt --name nodedemomodule --template module
不過在我實作的過程中發現到, dts-gen 在產生的時候會少掉主程式的定義,變成我們主程式這個部分需要手動加入。最後產生出來的 typing 檔如下。其中 MyTextOutput 這裡面的定義是我手動加入的

再來就是在 package.json 設定發佈時要將 typing 檔上傳
這猚可以看到我們的 typing 檔檔名是叫 index.d.ts ,並且是放在根目錄底下
原因是 VSCode 這裡在搜尋 typing 檔時,預設會從根目錄開始搜尋,並且優先比對 index.d.ts

最後的效果圖如下,可以看到 getFormatterText 是一個方法,並且相關參數的說明跟我們 typing 檔一樣

從下圖可以見到在還沒加入 typing 檔時,是不會有上面這樣的效果的

4.加入Code Coverage
接下來我們要做的是 Code Coverage 的設定 , Code Coverage 其實是用來呈現你目前 測試案例完整的程度
幫助你了解是否測試已經足夠,還有那些方法測試不足
在這個部分我們為了能容易結合 TravisCI ,採用 nyc 與 coveralls 這兩個套件
npm install nyc –D
npm install coveralls –D
接下來我們設定一 package.json 裡面執行的命令

最後簡單執行
npm run coveralls
就會在目錄底下看到 .nyc_ouput 資料夾產生
再來呢! 我們需要到 https://coveralls.io/sign-in 這個網站進行註冊與設定的動作
因為我這裡直接選擇 github 登入。所以可以看到我在 ADD REPO 這裡,可以很容易選擇我想要呈現 code coverage 數據的 REPO


我們在這裡找到練習用的這個 REPO (如果在裡面沒有看到預計要使用的 REPO 的話,右上角有一個 SYNC REPOS 按下去後會進行同步的動作)
接下來只要按一下 REPO 前面的那個 OFF 圖示,讓他變成 ON 就行了

再來我們需要移到 TravicsCI 做相關的設定,這樣 coveralls 才能收到相關的數據
5.結合TravisCI 自動編譯與呈現Code Testing coverage
同樣的,我們需要先在 TravisCI 上註冊一組我們的帳號,這裡為了求方便我一樣使用 GitHub 登入
一進來的畫面如下,因為我先前已經有使用 TravisCI 來建置我的 REPO ,所以會看到有一個專案叫 HtmlSEO

但我們這次要建立我們練習用的專案來讓 TravisCI 做自動建置,所以我們選一下圖中紅框處的 + 號
接下來直接搜尋我們要使用的 REPO ,這裡就是我練習用的 nodedemomodule 了。
並把 REPO 旁邊的 X 按下去,成功後就會呈現打勾的狀態
(如果沒有出現想使用的 REPO 在左方有一個 Sync account 按下去後就會同步重整了)

最後回到我們的專案底下設定 TravisCI 專用的設定檔 .travis.yml ,這個檔案一般也都會放在根目錄底下
設定完成的圖如下

可以看到,我們首先要告知 TravisCI 我們的建置環境是 node_js 與 nodejs 的版本為 8
再來則是需要安裝那些要全域執行的套件,最後就是常用的 npm install 還原我們專案所使用到的套件
安裝完成後則進行建置的動作,最後再額外產生我們的 code coverage 檔案
當這個檔案設定完成後,就可以進行 git commit 與 push 的動作!
接下來就可以看到 TravisCI 幫忙你做建置的畫面囉!
下圖就是 TravisCI 發現 REPO 有更新時自動觸發建置的畫面

最後當 npm run coveralls 執行完成時 ,回到 coervalls.io 就可以看到我們的 code coverage 比率了 (如下圖)

coveralls.io 上的 code coverage 結果

最後你可以利用以下這幾個連結,放在你的 README 裡讓其它人知道你這個套件的狀態
<a href=https://badge.fury.io/js/{換成你的套件名稱}>
<img src="https://badge.fury.io/js/{換成你的套件名稱}.svg" alt="npm version" height="18">
</a>
<a href="https://travis-ci.org/{換成你的travisCI帳號}/{換成你的套件名稱}">
<img src="https://travis-ci.org/{換成你的travisCI帳號}/{換成你的套件名稱}.svg?branch=master" alt="Travis CI" />
</a>
<a href='https://coveralls.io/github/{換成你的github帳號}/{換成你的套件名稱}?branch=master'>
<img src='https://coveralls.io/repos/github/{換成你的github帳號}/{換成你的套件名稱}/badge.svg?branch=master' alt='Coverage Status' />
</a>
成功的話就會看到下面這樣的圖示

以上就是一個比較完成發佈 node module 的流程了!其它像 React 、 Vue 、Angular 其實都大同小異
如果有任何問題再請留言讓我知道
謝謝大家
如何發佈一個完整Node.js Module的更多相关文章
- (转)Node.js module.exports与exports
本文转自Node.js module.exports与exports 作者: chemdemo 折腾Node.js有些日子了,下面将陆陆续续记录下使用Node.js的一些细节. 熟悉Node.js的童 ...
- 创建并发布node.js module
创建node.js module. 创建一个文件夹,用来存放module. Cd到新创建的文件夹,运行npm init,会提示输入package的信息. 可以按照这个视频的来输入.Test com ...
- Node.js & module system
Node.js & module system Node.js v10.9.0 Documentation https://nodejs.org/api/modules.html#module ...
- node.js module.exports & exports & module.export all in one
node.js module.exports & exports & module.export all in one cjs const log = console.log; log ...
- Node.js & module.exports & exports
Node.js & module.exports & exports https://www.cnblogs.com/xgqfrms/p/9493550.html exports &a ...
- node.js module初步理解
在开发一个复杂的应用程序的时候,我们需要把各个功能拆分.封装到不同的文件,在需要的时候引用该文件.没人会写一个几万行代码的文件,这样在可读性.复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组 ...
- Node.js module.exports和exports的区别
require 用来加载代码,而 exports 和 module.exports 则用来导出代码,从接触node.js就不会它们两陌生,上代码: foo.js exports.a = functio ...
- node.js module初步理解-(转载)
在开发一个复杂的应用程序的时候,我们需要把各个功能拆分.封装到不同的文件,在需要的时候引用该文件.没人会写一个几万行代码的文件,这样在可读性.复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组 ...
- How to use Request js (Node js Module) pools
Can someone explain how to use the request.js pool hash? The github notes say this about pools: pool ...
随机推荐
- Windows上安装配置SSH教程(5)——win10下使用Cygwin+Expect自动登陆ssh
1.安装Cygwin,安装上Tcl和Expect两个工具. 可以使用apt-cyg命令安装,也可以在安装Cygwin的时候选中这两个包. 命令安装的话使用下面的两个命令: apt-cyg instal ...
- Hibernate-ORM:02.Hibernate增删改入门案例
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本笔者使用的是Idea+mysql+maven做Hibernate的博客,本篇及其以后都是如此! 首先写好思路 ...
- SpringCloud分布式微服务搭建(一)
本例子主要使用了eureka集群作为注册中心来保证高可用,客户端来做ribbon服务提供者的负载均衡. 负载均衡有两种,第一种是nginx,F5这种集中式的LB,对所有的访问按照某种策略分发. 第二种 ...
- 【STM32H7教程】第12章 STM32H7的HAL库框架设计学习
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第12章 STM32H7的HAL库框架设计学 ...
- Spark学习之数据读取与保存总结(一)
一.动机 我们已经学了很多在 Spark 中对已分发的数据执行的操作.到目前为止,所展示的示例都是从本地集合或者普通文件中进行数据读取和保存的.但有时候,数据量可能大到无法放在一台机器中,这时就需要探 ...
- typecho设置文章密码保护
在别人博客看到了一个需要输入密码才能访问文章的功能,像下图一样 typecho也是有这个功能,不需要插件就可以实现.在编辑文章时,右边高级选项,公开度里有个密码保护可以选择 效果图 不过这样的界面不是 ...
- Android Gradle 依赖配置:implementation & api
背景: Android Gradle plugin 3.0开始(对应Gradle版本 4.1及以上),原有的依赖配置类型compile已经被废弃,开始使用implementation.api和anno ...
- HTML阻止iframe跳转页面并使用iframe在页面内嵌微信网页版
昨天看到这篇文章[置顶]开源组件NanUI一周年 - 使用HTML/CSS/JS来构建.Net Winform应用程序界面 就想弄一个winform结合html5的一个小东西,突有兴致,想在里面嵌套一 ...
- Java 在PDF文档中绘制图形
本篇文档将介绍通过Java编程在PDF文档中绘制图形的方法.包括绘制矩形.椭圆形.不规则多边形.线条.弧线.曲线.扇形等等.针对方法中提供的思路,也可以自行变换图形设计思路,如菱形.梯形或者组合图形等 ...
- 学JAVA第二十天,接触异常处理,自定义异常
1.java.lang.NullPointerException(经常报)(运行时异常) 属于运行时异常,是编译器无法预知的异常,比如你定义了一个引用变量String a,但是你确没有用new关键字去 ...