包
在模塊的基礎(chǔ)上進一步組織JavaScript代碼
用途: 可以讓開發(fā)者通過npm直接下載,與cocoapods作用相同挪哄,與bower的用途相似
存放網(wǎng)站
我們做的包吧秕,需要先在npm網(wǎng)站上,上傳一下迹炼,配置東西:package.json寇甸,然后npm install -- npm -- git這個過程才能完成,否則npm install失敗
與iOS的包上傳cocoapods一樣疗涉,先在github中創(chuàng)建,然后clone下載吟秩,然后新建podspec文件咱扣,然后上傳github,然后pod truck將podspec文件推送到cocoapods涵防,就行
"道理都一樣:1.得有個代碼存放地 2.自己的代碼包得有個spec描述文件 3.這個描述文件得在npm闹伪、cocoapods中存在"
參考鏈接:http://www.reibang.com/p/f146fa5358d5?mType=Group
bower
bower與npm導入包的功能在一定程度上相似
但是側(cè)重點不同:
簡單的說,npm是進行后端開發(fā)中壮池,使用的模塊安裝工具偏瓤,
而bower,是前端的模塊安裝工具椰憋。
比如厅克,在安裝express,socket.io時橙依,當然使用的是npm证舟,那么比如bootstrap,jquery等前端框架窗骑,需要使用bower
bower是國外的女责,直接install,是去國外服務(wù)器下載(速度太慢)创译,淘寶鏡像的作用抵知,就是復制了一份,放在了自己的服務(wù)器上,我們直接訪問淘寶的鏡像地址刷喜,就可以install
bower可以幫我們自動下載第三方的依賴庫(第三方中有個json文件残制,里面記錄了第三方的一些基本信息: 名字 版本 網(wǎng)址 依賴庫等等)
依賴庫下載以后,這個第三方不刪除吱肌,這個依賴庫是不能通過命令行刪除的痘拆,提示,有第三方正在依賴它
參考鏈接:https://yq.aliyun.com/ziliao/40449
包的組成
- 包結(jié)構(gòu)
- 包描述文件package.json
配置文件為啥用json格式氮墨?
方便解析讀取纺蛆,格式簡單清晰
npm install -g fast-init
fast-init 是一個基于node的命令行工具,可以快速生成一個包的文件標準結(jié)構(gòu)
作用: 集成快捷鍵规揪,可以一鍵生成指定的文件
類似代碼塊桥氏,這個可以叫文件塊
命令行應用名字 -h
可以查看該應用工具的所有指令,還有解釋
package.json
包的描述文件猛铅,一定程度上相當于iOS項目第三方庫中的podspec文件
package.json文件內(nèi)部就是一個JSON對象字支,該對象的每一個成員就是當前項目的一項設(shè)置,
比如name就是項目名稱奸忽,version就是項目的版本號
在模塊的加載機制中堕伪,有一個main屬性是非常重要的,它很大意義上決定了包要導出的模塊位置
參考文獻 package.json全字段解析 http://blog.csdn.net/woxueliuyun/article/details/39294375
模塊化
一個js文件在node里面我們就理解為一個模塊
在一個模塊內(nèi)變量栗菜、函數(shù)欠雌、對象都屬于這個模塊,對外是封閉的疙筹。
module.exports用來曝露屬性和方法的富俄,因為模塊有封裝性,需要打破封裝性曝露方法和屬性來
require()方法來實現(xiàn)模塊化(具體會在下面Global模塊詳述)
模塊三兄弟:require而咆、module霍比、exports
模塊化:
seajs
requirejs
這兩個實現(xiàn)模塊化的第三方,到了nodejs中暴备,都已經(jīng)原生實現(xiàn)了悠瞬,api也基本相同,還是require()
REPL(Read-eval-print-loop) 交互式運行環(huán)境
Node.js給我們提供一個交互式運行環(huán)境——REPL涯捻,在這個環(huán)境中我們可以做一些簡單的應用程序的測試或調(diào)試阁危。進入命令行窗口,輸入”node”命令并按下回車鍵汰瘫,即可進入REPL運行環(huán)境狂打。
方便測試
JavaScript代碼的運行環(huán)境,repl和chrome的控制臺很像
- 通過在控制臺中輸入
node
敲回車就可以計入 REPL 運行環(huán)境 - 通過在REPL運行環(huán)境中 連續(xù)按兩次
Ctrl+C
或者輸入.exit就可以退出 REPL 運行環(huán)境
基本操作:
- 變量混弥、函數(shù)趴乡、對象
- 直接運行函數(shù)
- 使用下劃線对省,表示上一個命令的返回結(jié)果
全局對象global
global表示Node所在的全局環(huán)境,類似于瀏覽器的window對象
在html中晾捏,一個網(wǎng)頁蒿涎,一個ifream一個window
nodejs中,一個項目全局惦辛,也就一個global
在前者中
var a = 123 / a =123 都是加到window中的
在nodejs中
var定義的是當前js文件的變量
a=123/global.a=123都是加給global的
我們可以在REPL環(huán)境中直接查看global對象
總結(jié):
global就表示Node中的全局命名空間劳秋,任何全局變量、函數(shù)或?qū)ο蠖际莋lobal的一個屬性
在一個模塊中定義的變量胖齐、函數(shù)或方法只在該模塊中可用玻淑,但可以通過exports對象將其傳遞到模塊外部
global常見的一些屬性與函數(shù)
__dirname和__filename
exports和module
process
Class:Buffer
setInterval()和clearInterval()
setTimeout()和clearTimeout()
console
require()
__dirname 和 __filename
__dirnamee 用來找到當前文件夾的路徑
__filename 用來去到當前文件的路徑
不知道代碼要才哪使用的時候,用于靈活的寫代碼取路徑的時候呀伙。
它們屬于模塊作用域补履,可以直接使用
它們兩個用來獲取路徑的,一般用于操作文件路徑的時候剿另,才會用到箫锤,一般在讀取文件的時候,最好使用絕對路徑的方式雨女,通過這倆家伙拼接
module(每個模塊谚攒,可用看做就是每個js文件)
Node內(nèi)部提供一個Module構(gòu)造函數(shù),所有模塊都是Module的實例
每個模塊內(nèi)部氛堕,都有一個module對象,代表當前模塊馏臭。
module.id 帶有絕對路徑的模塊文件名
module.filename 模塊的文件名,帶有絕對路徑
module.loaded 表示模塊是否已經(jīng)完成加載
module.parent 返回一個對象岔擂,表示調(diào)用該模塊的模塊。
module.children 返回一個數(shù)組浪耘,表示該模塊要用到的其他模塊乱灵。
module.exports 模塊對外輸出的值
Module的exports屬性
module.exports屬性表示當前模塊對外輸出的接口,其它文件加載該模塊,實際上就是讀取module.exports屬性
點兒導出單個函數(shù)七冲、對象或者值的時候非常有用痛倚,本質(zhì)上就是少了一個.(點)
exports
為了方便,Node又為每個模塊提供一個exports變量澜躺,指向module.exports
相當于在每個模塊頭部蝉稳,有這樣一行命令:
var exports = module.exports;
結(jié)果就是:
在對外輸出模塊接口時,可以向exports對象添加方法
注意:不能直接給exports或者module.exports直接賦值掘鄙,因為這樣等于切斷了exports和module.exports的聯(lián)系耘戚,export就無效了,用屬性的形式去賦值的時候二者都有效
module.exports=123;已經(jīng)使用過一次了操漠,exports就不生效了
module.exports.a=12;這樣使用,exports是還可以使用的
process
process 是一個全局可用對象收津,用來和我們現(xiàn)在啟動中的node進行交互的
process.version取版本號
在控制臺做標準輸出
process.stdout.write(`123123`);
process.pid:當前進程的進程號。
process.version:Node的版本,比如v0.10.18撞秋。
process.platform:當前系統(tǒng)平臺长捧,比如Linux。
process.env:指向當前shell的環(huán)境變量吻贿,比如process.env.HOME串结。
process.stdout:指向標準輸出。
process.stdin:指向標準輸入舅列。
process.stderr:指向標準錯誤肌割。
nodejs中的console
斷言 是用來測試用的
斷言就是假定一個條件,如果條件成立則不輸出任何內(nèi)容剧蹂,如果條件不成立則報錯還要輸出想要輸出的內(nèi)容声功。
console.assert(條件,條件不成立輸出的內(nèi)容);
var foo=3;
console.assert(foo==3,"失敗");
time() timeEnd()成對出現(xiàn),計算在兩個方法中間的代碼的運行時間宠叼,傳入的參數(shù)要一致
console.time('test');
console.timeEnd('test');
require()
在Node.js中先巴,require命令用于加載模塊文件
基本功能:
讀取并執(zhí)行一個JavaScript文件
然后返回該模塊的exports對象
如果沒有發(fā)現(xiàn)指定模塊,會報錯
require的實現(xiàn)原理
把代碼從文件中讀出來,用匿名函數(shù)的方式頭尾包裝冒冬,返回modules.exports對象伸蚯,曝露出想要曝露出來的屬性、方法简烤、對象剂邮。
加載規(guī)則:
1. 參數(shù)字符串以 “/”開頭:表示從系統(tǒng)根目錄開始尋找該模塊文件
2. 參數(shù)字符串以“./”開頭:表示從當前目錄出發(fā)
3. 參數(shù)字符串以“../”開頭:表示從上一級目錄出發(fā)
4. 參數(shù)字符串不以以上三種開頭,說明要加載的不是一個文件横侦,而是一個包模塊挥萌。此時則先在核心模塊(nodejs原生提供)當中找,然后再尋找NPM模塊(即第三方模塊包枉侧,或自己寫的模塊包)引瀑。在尋找NPM模塊包時,會從當前目錄出發(fā)榨馁,向上搜索各級當中的node_modules文件夾當中的文件憨栽,但若有兩個同名文件,則遵循就近原則翼虫。
1屑柔、加載核心模塊(nodejs原生提供)的時候,不需要傳入路徑珍剑,因為Node.js已經(jīng)將核心模塊的文件代碼編譯到了二進制的可執(zhí)行文件中了,在加載的過程中掸宛,原生的核心模塊的優(yōu)先級是是最高的
2、之前在使用require的方式來加載一個文件時招拙,如果該文件在當前目錄當中旁涤,則參數(shù)字符串當中必須以./開頭翔曲,不能直接寫文件名。若在參數(shù)字符串當中直接寫文件名劈愚,則代表載入的是一個模塊包瞳遍,模塊包必須放在一個特定名字的文件夾當中,即node_modules菌羽。
3掠械、在加載一個自己編寫的模塊的時候,最好使用__dirname 和 你要加載的模塊的文件名拼接
4注祖、若直接寫包名
先在包內(nèi)的node_modules目錄下查找猾蒂,再去父級目錄下的node_modules目錄下查找,
依次向上查找是晨,直到根目錄肚菠。
5、require 優(yōu)先從緩存加載
common.js規(guī)范----->加載后罩缴,會將對象緩存下來蚊逢,再次需要加載時,是去緩存中取module.exports
使用require來加載文件的時候箫章,參數(shù)字符串可以省略后綴名
.js烙荷、.json、.node
.js會當做JavaScript腳本文件解析
.json會以JSON格式解析:Node.js通過fs讀文件的形式讀取出來的檬寂,然后通過JSON.parse()轉(zhuǎn)換成一個對象
.node會以編譯后的二進制文件解析(后綴為node的文件是c/c++寫的一些擴展模塊)
若參數(shù)字符串為一個目錄(文件夾)的路徑终抽,則自動先查找該文件夾下的package.json文件柒凉,然后再再加載該文件當中main字段所指定的入口文件著隆。(若package.json文件當中沒有main字段,或者根本沒有package.json文件溯壶,則再默認查找該文件夾下的index.js文件作為模塊來載入镣屹。)
Node.js會通過同步阻塞的方式看這個路徑是否存在
依次嘗試圃郊,直到找到為止,
如果找不到野瘦,報錯
參考文獻 http://www.infoq.com/cn/articles/nodejs-module-mechanism/