你剛剛完成自己第一個JavaScript庫的開發,同時你認為它可以幫助到其他人。你已經聽到人們討論“開源運動”或“GitHub簡歷”,但你在共享軟體這方面上仍然是個新手。
也許你還在學校,你想開始建立一個線上簡歷。或者你已經開始在公司工作,比如 Conductor,這個公司鼓勵開發人員為開源社群做貢獻(見 Hoard和 Kangaroo)。這篇文章將講述一些工具和技術,你可以用來釋出一個值得信賴的開源JavaScript庫。
讓你電腦上的原始碼能夠得到別人的信任,並且在他們自己的專案中使用你的庫,你需要完成幾個重要的步驟。這篇文章就是圍繞這一過程來組織。
對於這次操練,你會看到 backbone.freeze,這是我寫的一個簡單的庫,它用於支援Backbone.js的不可變的集合。我假設你有一個庫的本地版本,並且程式碼在一個準備釋出的地方。
庫檔案的原來的樣子
託管(或將“原始碼”放到“開放原始碼專案”)
讓人們使用你的程式碼的第一步是,讓你的程式碼在網上可用!當今託管程式碼流行的地方是GitHub,本指南將使用它,但是你也可以使用任何你熟悉的託管網站。
程式碼線上(或者分享)
如果你還沒有一個GitHub賬號,把這篇文章先放放,去建立一個。如果有一個?很好!現在來建立一個新的倉庫。
我們的新倉庫
現在上傳你的程式碼到GitHub。這篇文章假定你熟悉 git(或另一個版本控制系統)。如果你不知道如何做到這一點,看看 這個指南 。
這時,您應該有一個不錯的倉庫,裡面都是你寫的程式碼。拍拍自己的後背,慶祝一下你的第一個開源專案。做到這一步,現在請豐富你的README.md檔案。這樣人們可以知道專案用途。
初始化狀態的倉庫
許可(或允許人們使用你的程式碼)
當你決定將你的程式碼釋出在網上,你需要回答的一個問題是,“如何允許別人使用它?“,在這篇文章中,您將為專案新增一個許可證。畢竟,現在是思考這個問題的時候了。有關許可證的更多資訊,請檢視 這個網站。我為 backbone.freeze 選擇了MIT 許可證。因為它非常寬鬆,同時在GitHub上託管的JavaScript專案上它非常流行,這意味著其他JavaScript開發人員,在知道我的程式碼能做什麼和不能做什麼的理解上沒有問題。
遵循社群標準(或者做一個他人確實會使用的專案)
想象你是無辜的 JavaScript 程式設計師先生或女士。你偶然發現這個倉庫。你認為,”嘿,這填補了我的一個需求!“作為一個JavaScript開源社群的成員,你需要知道有一些開放原始碼專案的質量標準。除非它符合這些標準,不然你不可能使用這些程式碼。
讓你的程式碼符合這些標準!
與JavaScript社群特別相關的兩個標準是依賴管理和測試。
依賴管理
當你的專案依賴於外部庫或模組,你需要一個簡單的方法來管理這些依賴關係。當然,你可能只是簡單地複製並貼上另一個庫的原始碼到你的專案原始碼,但這很難處理版本變更和確保你的依賴關係的準確性。這就是為什麼依賴管理器可以使你變得更輕鬆。它允許使用者呼叫’install[library]’,來獲取所有依賴項庫的最新版本或他們的程式碼所依賴的任何其他庫。
在JavaScript領域,有一個流行的依賴管理器 npm。這篇文章將使用npm作為依賴管理,但是你可以使用其他任何你覺得合適的工具。
如果你沒有npm,花一些時間來安裝它。 (說明在這裡)
首先,你需要使用命令“npm init”來建立一個新的npm專案。最好猜猜這些配置選項,你可能會改變其中的一些。
如果你看看backbone.freeze的配置選項,您將看到兩個重要的事情。第一個是許可證,回憶我讓你在上面思考的有關許可證的事項?這就是填寫許可證的地方。
同時,你會發現有一個測試命令。您現在可以忽略,或者寫上“gulp test”——我將馬上解釋它的含義。
現在您已經準備好去測試。
測試
測試是讓使用者看到你的庫是實際如何工作的一種簡單方法,同時能讓使用者信任你的程式碼能做到你所聲稱能做的事情,即使是邊界情況。所以讓我們為你的外掛編寫一些測試!
安裝包
首先,你需要設定將用來編寫測試的工具。本教程將使用以下:
1 |
npm install --save-dev mocha chai |
現在你有npm,你準備安裝它們。
1 |
npm install --save-dev mocha chai |
(Mocha是一個JavaScript測試框架。Chai是一個JavaScript預測庫,對測試很有用)。
配置
在你的目錄變得混亂之前(新的package.json和node_modules目錄之間,你可能感覺有點擁擠),是時候遵循標準的約定並移動你的原始碼到“src”目錄了。
此外,您將使用另一個額外的組織方式,建立一個名為“spec”的目錄,在這裡面你將放置所有的測試。
確保你所有的測試都可以使用Chai,你需要在spec目錄中建立一個“setup.js”檔案。在該檔案中,您需要設定Chai
1 2 3 |
'use strict'; var chai = require('chai'); global.expect = chai.expect; |
view rawspecsetup.js hosted with ❤ by GitHub 【黃利民注:這裡是程式碼段】
你可通過輸入“mocha spec/ *.js”來檢驗以上是否成功,可以看到測試執行成功(包含0個測試)。
編寫所有測試! ! !
花一些時間來編寫測試。它們都應該放在spec目錄中。
如果你從來沒有編寫過測試,看看 backbone.freeze的測試。在你編寫這些測試時,我去拿一杯咖啡…
…都做完了嗎?好。現在,當你再次執行“npm test”命令,你應該看到,所有的測試用例都在執行,且通過。(如果它們沒有通過,修復之後再繼續!)
既然你已經做完了,把新程式碼上傳到GitHub。
自動化
大多數JavaScript開發人員使用某種自動化工作流,使編寫和執行測試的過程更容易一些。有幾種常用的工具,但是這篇文章將使用 gulp。你在本教程中會用它來幹幾件事,現在它將幫助啟動測試。首先,安裝 gulp 和 gulp mocha 外掛。
1 |
npm install --save-dev gulp gulp-mocha |
你需要在父目錄中新增一個gulpfile.js,它包含以下行:
1 2 |
'use strict'; require('./gulp'); |
view rawgulpfile.js hosted with ❤ by GitHub
該檔案表示,它將監視一個名為“gulp”的目錄,所以你需要建立它。在這個目錄中,建立一個index.js檔案,它是被gulp執行所有JavaScript檔案的入口點。然後建立一個名為“task”的資料夾——index.js將引用該目錄下的所有檔案,以便gulp知道它們。
1 2 3 4 5 |
'use strict';var fs = require('fs'); var tasks = fs.readdirSync('./gulp/tasks'); var gulp = require('gulp');tasks.forEach(function(task) { require('./tasks/' + task); }); |
view rawgulpindex.js hosted with ❤ by GitHub
現在進行最後一點複製-貼上。在你的task目錄,建立一個測試任務,它將啟動所有測試:
1 2 3 4 5 |
'use strict';var gulp = require('gulp'); var mocha = require('gulp-mocha');gulp.task('test', function () { return gulp.src(['./spec/setup.js', './spec/**/*.spec.js'], { read: false }) .pipe(mocha({ reporter: 'spec' })); }); |
view rawgulptaskstest.js hosted with ❤ by GitHub
您會注意到test.js這個gulp task引用了spec目錄,並載入了setup.js檔案。
在這之後,你的目錄應該像這樣:
是否記得我在文章中提到的npm初始化步驟“gulp test”?這裡是它存在的地方。使用你喜歡的文字編輯器開啟package.json,並確保它有這樣一段指令碼:
1 2 3 |
"scripts": { "test": "gulp test" }, |
package.json 中的這一行,告訴 npm 如何執行你的測試。
這是一個很好的測試,以確保你在正確地做所有事:在你的專案目錄,執行“npm test”,並確保你看到相同的測試輸出。
持續整合 (或者,確保每個人都知道你的最新更新沒有破壞任何東西)
既然您已經有一個全面的測試套件,那您需要一種方法來向使用者保證,你釋出的新版本不會破壞任何功能。這就是持續整合。“持續整合”意味著將不斷測試程式碼。(或表示程式碼不斷更新,在每一次提交。)
這裡有很多工具可以使用。這篇文章將使用一個非常棒工具,名為Travis CI,它為任何公共的GitHub專案提供免費的持續整合。
你需要做的第一件事是新增一個travis-ci配置檔案到你的倉庫。這個檔案會告訴Travis你的專案語言。在那裡,Travis可以判斷需要執行的命令,並執行你的測試。
1 |
language: node_js |
view raw.travis.yml hosted with ❤ by GitHub
將 travis-ci.org與GitHub賬戶連線。然後導航到倉庫頁面,點選右上角你名字的位置。您應該在GitHub賬戶列表看到一個公共倉庫。移動滑塊 ldibrary 到 on。可能需要一些時間,但最終,Travis將執行你的測試,並讓你知道構建正在進行。
你可能會想在GitHub頁面嵌入構建資訊,這樣一個感興趣的使用者一眼就可以看到,你的程式碼是穩定且可信賴的。如果你點選倉庫名稱旁邊的圖片(在頂部,顯示為“buid|passing”)應該會看到一個彈出框。選擇“Markdown”並複製文字框的內容。你可以貼上到你的README.md檔案,並更新到GitHub。如果你做對了,GitHub頁面現在看起來應該像這樣:
注意,你是如何一眼就可以看出這是通過所有的測試
相容性(確保每個人都能使用你的庫)
現在您已經釋出一個JavaScript專案,它提供可靠的測試和持續整合,你要確保每個人都可以使用它。在JavaScript中,一些人使用AMD(RequireJS)載入庫或模組,一些人使用CommonJS(Node.js),而有些人通過script標籤明確引用每一個檔案。這樣很難保證馬上就能相容所有這些匯入策略。
幸運的是,有一個叫做webpack庫,使所有這些變的簡單!確保你的庫是打包的,這樣它對每個人都可用,無論他們使用什麼模組系統(或不使用,視情況而定)。你需要一個名為“del”的工具來刪除檔案。
1 |
npm install --save-dev gulp-webpack del |
這裡說說打包過程是如何工作的:你需要建立一個名為“dist”的目錄(釋出的簡稱),這是“相容”版本庫的存放位置。你需要一個gulp任務來建立它,以及一個gulp任務來清理目錄。讓我們先從清理任務開始。
1 2 3 4 5 6 |
'use strict';var gulp = require('gulp'); var del = require('del');gulp.task('clean', function (cb) { del([ 'dist' ], cb); }); |
view rawgulptasksclean.js hosted with ❤ by GitHub
這不是那麼糟糕!您只需建立一個任務,刪除dist資料夾。現在看看dist。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
'use strict'; var gulp = require('gulp'); var webpack = require('gulp-webpack'); gulp.task('dist', function () { return gulp.src('src/[LIBRARY ENTRY POINT (i.e. backbone.freeze.js)]') .pipe(webpack({ output: { filename: '[NAME OF FINAL FILE (i.e. backbone.freeze.js)]', libraryTarget: 'umd' }, externals: { backbone: { amd: 'backbone', commonjs: 'backbone', commonjs2: 'backbone', root: 'Backbone' }, underscore: { amd: 'underscore', commonjs: 'underscore', commonjs2: 'underscore', root: '_' }, devtool: 'source-map'` } })) .pipe(gulp.dest('dist')); }); |
view rawgulptasksdist.js hosted with ❤ by GitHub
在括號部分內,分別填寫庫入口點的檔名和輸出檔案的最終名。你可以通過在命令列執行“gulp dist”和“gulp clean”來確保一切正常執行,並檢查資料夾和檔案是否都建立或者移除。
注意:dist資料夾在dist任務後出現,clean任務後消失。
現在你的庫馬上可以廣泛使用了!剩下要做的唯一一件事是…
釋出(確保每個人都能得到你的程式碼)
有兩種流行的方式獲得一個JavaScript庫,技術上有三個,但你可以忽視直接從GitHub頁面下載 .js 檔案,因為這裡已經準備好:Bower 和 npm。
想想前面的步驟,您通過依賴管理設定您的專案?不久後的某一天,某天真的JavaScript程式設計師先生或女士,能夠在她喜歡的依賴管理工具下輸入 ‘install [你的庫]’,它就工作了!
在以下步驟,你會將程式碼被納入公共倉庫,並使用這兩種常用的依賴管理工具,使其可用於所有其他開發人員。
配置
Bower和npm都依賴於配置檔案。(npm的package.json。)因為你沒有一個Bower配置檔案,您需要做的第一件事是寫一個gulp任務來為你生成一個。你可能會問“為什麼?“。因為你不想維護兩個不同的配置檔案。一旦你準備好釋出,您可以通過執行“gulp dist”來為所有部件的釋出做準備。
你需要為此安裝兩個庫。
1 |
npm install --save-dev gulp-rename gulp-json-editor |
現在你需要準備:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
"use strict"; var gulp = require('gulp'); var rename = require('gulp-rename'); var jeditor = require('gulp-json-editor'); var _ = require('underscore'); gulp.task('bower', function () { return gulp.src('./package.json') .pipe(rename('bower.json')) .pipe(jeditor(function (json) { return _.pick(json, [ 'name', 'version', 'description', 'main', 'keywords', 'author', 'license', 'dependencies' ]); })) .pipe(gulp.dest('.')); }); |
view rawgulptasksbower.js hosted with ❤ by GitHub
修改gulp/tasks/dist.js中gulp.task處,包含以下程式碼(斜體部分):
1 |
gulp.task('dist', <em>['bower'],</em> function () { |
這確保了dist執行時,Bower任務參與了。
現在您需要釋出程式碼到這兩個倉庫。首先,你需要為您的庫選擇一個還沒有使用的名稱。搜尋npm registry和 Bower registry ,以確保一個你想要的名字沒被使用。(如果被用了,你需要改變package.json。)
在你釋出你的程式碼之前,更新您的文件讓使用者知道如何獲取程式碼。新增這些到README.md(填入庫名):
1 2 3 4 5 6 7 |
#Installing Freeze is available on npm and Bower as "backbone.freeze" ``` bower install backbone.freeze OR npm install backbone.freeze ``` |
注意,釋出到npm和Bower上包有一些約定。根據你釋出的程式碼,您可能不希望釋出到兩個倉庫。選擇正確的依賴管理系統的更多資訊,看看這篇文章 StackOverflow。
npm
npm釋出很簡單——只是設定 npm 作者資訊:
1 2 3 4 |
npm set init.author.name "Your Name" npm set init.author.email "you@example.com" npm set init.author.url "http://yourblog.com" npm adduser |
輸入 ‘npm publish. /’.
好了!你已經正式釋出在npm !
Bower
釋出一個包到Bower有點複雜。
首先,在你專案的git倉庫中建立一個標籤。
1 |
'git tag -a [VERSION] -m "released [VERSION]"' |
…”(版本)”是package.json中的當前版本號。
接下來,將該標記上傳GitHub。
1 |
'git push origin [VERSION]' |
然後用Bower註冊您的專案。
1 |
'bower register [PACKAGE NAME] [GIT ENDPOINT]' |
…”[庫名]”是庫的名稱(對我來說,它是“backbone.freeze”),“[GIT ENDPOINT]”是github上的.git檔案的url(對我來說,它是“git://github.com/benmanbs/freeze.git”)。
現在庫已經註冊,當你把新的標籤更新到GitHub,它會在Bower自動更新。
最後的話
我編寫的一些指令碼,你可能用得上。
把這兩個檔案放在你的庫的父資料夾中: publish.sh、update_version.rb。
指令碼需要版本型別(大版本號,小版本號或補丁號),在package.json中新增你的版本號,生成一個bower.json和dist,並同時釋出到npm和Bower。
現在您已經沒有從頭學習這一切的麻煩,這是我建立的一個 骨架專案,包括了我在上面描述的標準框架。
如果你在這個過程中有任何麻煩,隨時給我發 電子郵件。
如果你發現自己需要Backbone的不變集合,可以看看 backbone.freeze!