來源:https://github.com/spmjs/spm/wiki/Hello-spm%EF%BC%9A%E4%BD%BF%E7%94%A8-spm-%E5%92%8C-SeaJS-%E5%BC%80%E5%8F%91%E4%B8%80%E4%B8%AA%E4%B8%AD%E5%9E%8B%E9%A1%B9%E7%9B%AE
現在我們要正兒八經開始開發一個叫 hello-spm 的項目了,別笑,雖然只是個為了讓你更好的了解 SPM 而杜撰出來的項目,但也五臟俱全。
我們提供了在線演示:http://fool2fish.github.com/hello-spm 。 毫不猶豫的猛擊空格鍵,就會有有趣的事情發生了。
你可以檢出源碼:https://github.com/spmjs/hello-spm 。
在正式開始之前,我還是要啰嗦一句,所有的范例代碼都是基於 SeaJS 的, 請確保你已經知道該怎么使用 SeaJS 了。
創建項目目錄
我們先來看看項目的整體結構
hello-spm/
assets/
hello/
util/
sea-modules/
package.json
index.html
- 考慮到真實的項目通常包含前后端的代碼,所有前端代碼放在 assets/ 。
- hello 和 util 是為本項目編寫的模塊。
- sea-modules/ 用於存放安裝和部署的模塊。如果你的項目基本都是基於 SeaJS 和 SPM 的,你可以把這個目錄放置在和項目目錄平級的路徑下,以便各項目公用。
- package.json 為模塊打包部署的總體配置。
- index.html 為項目頁面。
安裝需要的模塊
顯然,我們需要用到 seajs 和 jquery,所以要使用 spm install 來安裝他們。
打開命令行工具,將路徑切換至 sea-modules/ ,運行:
spm install seajs
spm install gallery.jquery@1.8.3
創建模塊
回想一下 index.html 運行的效果,多處用到了隨機數,例如 "hello spm !" 的單個字符大小,字符串出現在頁面中的位置以及字符串在頁面上停留的時間。
我們把這樣一個可產生指定范圍的隨機整數的工具方法放到 util 模塊中。
下面我們來 初始化 這個模塊。
命令行工具路徑切換至 util/ ,運行:
spm init
util/
examples/
src/
tests/
package.json
README.md
- examples/ 用於存放演示文件。
- src/ 為模塊源碼,打包后的文件會存放到和 src/ 平級的 dist/ 目錄下。
- test/ 用於存放測試用例,你可以使用 jasmine 等工具來保障代碼的質量。
- package.json 為本模塊打包部署的配置。
我們的 hello-spm 實在有點簡單,所以演示代碼僅保留了 src/ 和 package.json 這兩個必備部分。
src/ 中只有 util.js 一個文件, 源碼非常簡單,如下:
define(function(require, exports) {
exports.random = function(min, max){
return min + Math.round(Math.random() * (max - min))
}
})
拆分子模塊
接下來我們處理相對復雜一些的 hello 模塊,他要做這么幾件事情:
- 創建字符大小隨機的 "Hello SPM !" 字符串。
- 隨機顯示到頁面上。
- 一段時間后自動消失。
這個模塊復雜到需要拆分成多個子模塊來進行開發 (好吧,我承認這純粹是教程需要)。
命令行工具路徑切換至 hello/ ,運行:
spm init
使用 spm init 初始化后,在 src/ 中除了默認創建的 hello.js,還需要手工創建一個 handle-text.js 文件。
hello.js 完成大部分的主體功能,而 handle-text.js 專門負責處理傳入字符串的隨機字符大小。
hello.js 的源碼如下:
define(function(require, exports, module) {
var $ = require('$')
var random = require('util').random
var handleText= require('./handle-text')
function Hello(){
this.render()
this.bindAction()
seajs.log('new Hello() called.')
}
Hello.prototype.render = function(){
this.el = $('<div style="position:fixed;'
+ 'left:' + random(0,70) + '%;'
+ 'top:' + random(10,80)+ '%;">'
+ handleText('Hello SPM !')
+ '</div>').appendTo('body')
}
Hello.prototype.bindAction = function(){
var el = this.el
setTimeout(function(){ el.fadeOut() }, random(500,5000))
}
module.exports = Hello
})
注意 :
- var random = require('util').random 是模塊方法的引用。
- var handleText= require('./handle-text') 是子模塊的引用。
- 在 Hello 類的構造器中,我們還使用 seajs.log 打了一句日志。
更多 require 的說明可查看 SeaJS 的 模塊標識
handle-text.js 的源碼如下:
define(function(require, exports, module) {
var $ = require('$')
var random = require('util').random
function handleText(text){
var min = random(30,70)
var max = random(50,120)
var rt = ''
for(var i = 0, len = text.length; i < len; i++){
rt += '<span style="font-size:' + random(min, max) + 'px;">' + text[i] + '</span>'
}
return rt
}
module.exports = handleText
})
編寫開發時頁面
開發過程中,我們就常常需要編寫一些測試用例,或者演示頁面。
這種情況下我們希望模塊是不需要打包的,並且可以查看日志,以便調試。
本例中,我們並沒有為單個模塊創建單元測試或者演示頁面。簡單起見,我們在 index.html 頁面中編寫了一些開發時的代碼,代碼如下:
<div style="text-align:center;font-size:48px;color:#999;"> Press the space key !</div>
<script src="assets/sea-modules/seajs/1.3.0/sea-debug.js"></script>
<script>
seajs.config({
alias:{
'$':'gallery/jquery/1.8.3/jquery.js',
'util':'http://www.cnblogs.com/util/src/util.js'
}
})
seajs.use(['$','./assets/hello/src/hello.js'],function($, Hello){
$(document).keypress(function(ev){
if(ev.which == 32){
new Hello()
}
})
})
</script>
注意:
- 引用 sea-debug.js,可以開啟 debug 功能。
- jquery(即 $ )作為 DOM 操作最常使用的模塊,總是需要通過 seajs.config 手工配置別名,確保項目內的統一。比如 1.8.3 版本。
- seajs.use 中的 '$' 為頂級 模塊標識,相對於 seajs 的 base 路徑, './assets/hello/src/hello.js' 為相對標識,相對於當前頁面 url。
現在運行 index.html 就能看到效果了,源碼上做任何的改動也能立馬體現,打開調試工具,你還能看到打出的 log。
打包部署
打包配置
結束編碼測試工作后,我們就要准備將模塊打包部署,以供正式環境使用了。打包相關的配置都寫在每個模塊的 package.json 中了。
先來看看 util 模塊的 package.json
{
"name":"util",
"parent":"../package.json",
"output":{"util.js":"."}
}
- name 為模塊名
- parent 指定用於繼承的父級配置,路徑相對於該配置文件。當你項目中的模塊有大量公共配置的時候推薦使用此項.
- output 指定了將 src/util.js 及其模塊內的依賴打包為 dist/util.js 。當然,這里 src/util.js 沒有模塊內依賴。
再接着看 hello 模塊的 package.json
{
"name":"hello",
"parent":"../package.json",
"output":{"hello.js":"."},
"dependencies": {
"$": "$",
"util":"hellospm/util/0.0.1/util"
}
}
然后我們還有一個 parent package.json
{
"root": "hellospm",
"version": "0.0.1"
}
絕大部分和 util 模塊的配置一樣,只是多了一項 dependencies,需要注意的是:
jquery 作為一個特殊的模塊,打包的時候並不指定具體的依賴,僅寫上 "$": "$" 即可。
回顧一下,就是因為這個原因,我們在剛剛創建的 index-debug.html 中,還需要為 jquery 配置別名: '$':'gallery/jquery/1.8.3/jquery.js' 。
接下來我們將以 util 模塊為例講解模塊的打包部署(hello 模塊的打包部署方式完全一樣)。
打包
命令行進入到 util/ ,運行:
spm build
SPM 會在 util/dist/ 目錄創建 util.js 和 util-debug.js 兩個文件。有興趣的讀者可以打開 util-debug.js 看看打包后的文件和源碼有何不同。
部署
為了方便演示,我們准備把打包好的模塊部署到本地。
進入 util/ ,運行命令:
spm deploy --to=../sea-modules
sea-modules/
hellospm/
util/
0.0.1/
util.js
util-debug.js
...
編寫正式頁面
勝利就在眼前,我們終於要完成這個項目了。現在我們要把測試用的 index.html 轉換成線上正式運行的 index.html,代碼如下:
<div style="text-align:center;font-size:48px;color:#999;"> Press the space key !</div>
<script src="assets/sea-modules/seajs/1.3.0/sea.js"></script>
<script>
seajs.config({
alias:{
'$':'gallery/jquery/1.8.3/jquery.js'
}
})
seajs.use(['$','./assets/sea-modules/hellospm/hello/0.0.1/hello.js'],function($, Hello){
$(document).keypress(function(ev){
if(ev.which == 32){
new Hello()
}
})
})
</script>
注意 index.html 前后的一些區別:
- index 引用的是 sea.js。
- SPM 在對模塊進行打包部署后,依賴關系已經處理好了,所以這里我們只用在 seajs.config 中配置 jquery($) 。
結束語
如果你耐心的看到這,那么恭喜你!現在你已經很了解 SeaJS 和 SPM 最常用的功能了。接下來,趕緊去自己的工作中去實踐一把吧,有任何建議和反饋歡迎反饋給我們:)