1. 程式人生 > >使用Node.js完成的第一個項目的實踐總結

使用Node.js完成的第一個項目的實踐總結

我們 web框架 -s 關閉 arr ber 代碼格式 oot mongoose

http://blog.csdn.net/yanghua_kobe/article/details/17199417

項目簡介

這是一個資產管理項目,主要的目的就是實現對資產的無紙化管理。通過為每個資產生成二維碼,來聯合移動終端完成對資產的審核等。這個項目既提供了Web端的管理界面也提供移動端(Andorid)的資產審核、派發等相關功能。
我們用Node.js構建該項目的Web端以及移動端的Serveice API。

項目主框架:Express 簡介

Express 是一個非常流行的Node.js的web框架。基於connect(node中間件框架)。提供了很多便於處理http請求等web開發相關的擴展。

Express簡單的結構圖:

Express的特性:

  • 基於Connect構建
  • 健壯的路由
  • 提供豐富的HTTP處理方法
  • 支持眾多視圖模板引擎(14+)
  • 內容協商
  • 專註於提供高性能
  • 環境基於配置
  • 快速構建可執行的應用程序
  • 高測試覆蓋率

前端框架簡介

Bootstrap

Bootstrap是Twitter推出的一個用於前端開發的開源工具包。它由Twitter的設計師MarkOtto和JacobThornton合作開發,是一個CSS/HTML框架。Bootstrap是簡潔、直觀、強悍的前端開發框架,讓web開發更迅速、簡單。
同時,很多基於Bootstrap的開源插件也讓Bootstrap社區更加活躍。

最新的Bootstrap3提供了非常強的定制化特性。包括Less,jQuery插件等。
Bootstrap 為您提供了所有這些基本的模塊- Grid、Typography、Tables、Forms、Buttons和Responsiveness。
此外,還有大量其他有用的前端組件,比如Dropdowns、Navigation、Modals、Typehead、Pagination、Carousal、Breadcrumb、Tab、Thumbnails、Headers等等。
有了這些,你可以搭建一個Web 項目,並讓它運行地更快速更輕松。
此外,由於整個框架是基於模塊的,你可以通過定制你自己的CSS來使得它滿足你的特殊需求。
它是基於幾種最佳實踐,我們認為這是一個很好的開始學習現代Web 開發的時機,一旦你掌握了HTML 和JavaScript/jQuery 的基本知識,你就可以在Web 開發中運用這些知識。

Ember.js

Ember.js是一個JavaScript的MVC框架,它由Apple前雇員創建的SproutCore2.0改名進化而來。
構建一個Ember應用程序,通常會使用到六個主要部件:應用程序(Application)、模型(Model)、視圖(View)、模板(Template)、路由(Routing)和控制器(Controller)。
這裏我們server端主要依賴express框架,它提供的這些功能跟express有些是相同的。我們主要應用了Ember的模板組件,Express對於它提供了很好的集成。我們只需要進行很簡單的配置即可:

[javascript] view plain copy print?技術分享技術分享
  1. app.set(‘view engine‘, ‘html‘);
  2. app.set(‘views‘, path.join(__dirname, ‘views‘));
  3. app.set("view options", {layout : false});
  4. app.register(‘.html‘, require(‘ejs‘));

測試框架簡介

should.js

should 是用於node.js的一個表述性、可讀性很強的測試無關的“斷言”庫。它是BDD風格的,用一個單例的不可枚舉的屬性訪問器擴展了Object的prototype,允許你表述對象應該展示的行為。
should的一個特性是可以支持鏈式斷言,比如:

[javascript] view plain copy print?技術分享技術分享
  1. user.should.be.an.instanceOf(Object).and.have.property(‘name‘, ‘tj‘);
  2. user.pets.should.be.instanceof(Array).and.have.lengthOf(4);

mocha

Mocha是一個簡單、靈活、有趣的javascript測試框架。它可以同時適用於node.js跟瀏覽器端。可以很輕松得完成同步、異步測試,對產生異常的測試用例提供靈活以及準確的報告。可以通過接口實現BDD、TDD、QUnit風格。

mocha + should.js

mocha是可以實現BDD模式的測試框架,而should.js是BDD模式的斷言庫。把它們結合起來,可以組建出一個非常靈活,並且不失表述性的測試框架。我們所有給終端的接口,都基於它們完成了測試。

項目組件 - node modules

mysql

功能簡介:MySQL- node.js平臺MySQL驅動,支持事務、連接池、集群、sql註入檢測、多做參數傳遞寫法等特性。
主頁地址:https://github.com/felixge/node-mysql

eventproxy

功能簡介:eventproxy- node.js 異步回調代理。主要用來解決node中深層次回調嵌套的問題,支持很多異步模式:多類型異步、重復異步、持續型異步。
主頁地址:https://github.com/JacksonTian/eventproxy

validator

功能簡介:javascript的驗證工具集,支持兩種模式:check(校驗)/sanitize(處理),同時提供了可擴展的錯誤處理。
主頁地址:http://github.com/chriso/node-validator

ejs

功能簡介:embered.jsjavascript 模板引擎(可以跟express集成,作為服務端模板引擎)
主頁地址:https://github.com/visionmedia/ejs

loader

功能簡介:loader- 資源加載工具,可以區分開發模式、發布模式;在發布模式下可進行資源壓縮、合並。以實現減少靜態資源帶寬並且便於實現客戶端緩存
主頁地址:https://github.com/TBEDP/loader

canvas

功能簡介:canvas - node.js 常用的圖形圖像處理庫,是很多其它庫的基礎依賴庫
主頁地址:https://github.com/learnboost/node-canvas

captchagen

功能簡介:captchagen-node.js常用驗證碼圖片處理庫,依賴上面的canvas庫
主頁地址:http://github.com/wearefractal/captchagen

crypto-js

功能簡介:crypto-js- javascript 常用加密庫、hash庫封裝,支持sha-x / md5 / hash等各種加密、hash算法
主頁地址:http://github.com/wearefractal/captchagen

nodemailer

功能簡介:nodemailer- 郵件發送工具,支持SMTP等郵件發送協議
主頁地址:http://github.com/andris9/nodemailer

qrcode

功能簡介:qrcode- node.js服務端的qrcode生成器。支持多種輸出類型(dataUrl/file/bitArray)
主頁地址:http://github.com/soldair/node-qrcode

pdfkit

功能簡介:qrcode- node.js服務端的qrcode生成器。支持多種輸出類型(dataUrl/file/bitArray)
主頁地址:http://github.com/soldair/node-qrcode

excel

功能簡介:excel- node.js excel解析器,支持xlsx(Excel2007+)
主頁地址:https://github.com/trevordixon/excel

excel-export

功能簡介:excel-export- node.js excel生成器,支持導出excel
主頁地址:https://github.com/functionscope/Node-Excel-Export

net-ping

功能簡介:net-ping- node.js 對ping的封裝,用於測試目標主機是否可達
主頁地址:https://bitbucket.org/stephenwvickers/node-net-ping

debug

功能簡介:debug- node.js debug工具,對console.log的封裝,支持多種顏色輸出。
主頁地址:https://github.com/visionmedia/debug

項目組織結構

NPM - Node.js 模塊依賴管理工具

npm是管理node.js模塊依賴的工具,依賴於開源技術的優勢就是你有非常多的優秀庫可以幫助你快速構建一個系統,但就像一把雙刃劍,由於開源導致版本的升級不可控。這時,一個集中性的模塊依賴管理工具的優勢就十分明顯。它負責幫你管理開源項目的版本,你只需要添加對某個開源模塊的依賴即可。

unix/Linux下安裝npm:

[javascript] view plain copy print?技術分享技術分享
  1. curl http://npmjs.org/install.sh | sudo sh

如何在項目中使用npm管理你的依賴:

(1)在項目的根目錄下創建一個package.json文件

在dependencies下添加所需要依賴的模塊,示例如下: 打開terminal,進入項目的根目錄下: [javascript] view plain copy print?技術分享技術分享
  1. $ cd projectPath
安裝這些module到本地repository: [javascript] view plain copy print?技術分享技術分享
  1. $ npm install

這時你會發現,項目的根目錄下多了一個node_modules文件夾,那裏面就是從npm遠程庫裏下載的模塊然後“安裝”到你的項目中的。
現在,你就可以在你的項目中應用你依賴的這些modules了。你可以通過require關鍵字來使用他們。比如,

[javascript] view plain copy print?技術分享技術分享
  1. require("eventproxy");

Node.js 模塊加載機制

node.js的模塊加載基於CommonJS規範。
在Node.js中,將模塊分為兩大類:
(1)原生模塊
原生模塊在Node.js源代碼編譯的時候編譯進了二進制執行文件,加載速度最快。
(2)文件模塊
node.js依賴modulepath(模塊路徑)來加載module,而modulepath的生成規則主要是從當前文件目錄開始查找node_modules文件夾,然後依次進入父目錄查找父目錄下的node_modules目錄直至到根目錄下得node_modules目錄。所以在require的時候,如果帶上module的路徑,則按照該路徑查找,如果沒有就按照上面的node_modules文件夾向上追溯查找,如果都沒有找到,則拋出異常。

自動化部署

項目環境的構建、部署都是自動化的。
我們假設項目最終會發布在任意版本的Ubuntuserver上。在安裝Git的前提下,通過如下命令去clone項目到本地:

[javascript] view plain copy print?技術分享技術分享
  1. git clone git://github.com/yanghua/FixedAssetManager_Server.git
項目doc下有四個shell文件:
  • node_install_ubuntu.sh - 在ubuntuserver上安裝node.js的腳本
  • node-canvas-install_ubuntu.sh - 在Ubuntuserver上安裝node-canvas的腳本
  • mysql_install_ubuntu.sh - 在Ubuntu server上安裝mysql的腳本
  • dispatch.sh - 部署項目的腳本

將它們copy到當前用戶的home目錄下,依次執行即可。整個過程幾乎實現了無需人為幹涉的“自動化”。

pm2 - 線上監控管理工具

pm2是非常優秀工具,它提供對基於node.js的項目運行托管服務。它基於命令行界面,提供很多特性:
  1. 內置的負載均衡器(使用nodecluster module)
  2. 以守護進程運行
  3. 0s(不間斷)重啟
  4. 為ubuntu/ CentOS 提供啟動腳本
  5. 關閉不穩定的進程(避免無限死循環)
  6. 基於控制臺監控
  7. HTTP API
  8. 遠程控制以及實時監控接口
pm2使用nodecluster構建一個內置的負載均衡器。部署多個app的實例來達到分流的目的以減輕單app處理的壓力。

異常監控與郵件推送

node.js 到處都是異步調用。常用的try/catch同步捕獲異常並處理的方式,在這裏不起作用了。這是因為很多callback已經離開了當時try的上下文,導致無法獲取異常產生的堆棧信息。基於這個問題,我們對異常處理的模式按類型進行區分處理:

(1)http請求異常
這種異常Express就可以進行處理。如果是非法請求,在路由的時候,對未匹配的請求進行統一處理:

[javascript] view plain copy print?技術分享技術分享
  1. app.get("*", others.fourofour);

(2)業務異常

這種異常通常不會影響到程序的運行,我們以不同的異常代碼返回給前端或者終端,來給調用端友好的提示。

(3)應用程序級別的異常或必須處理的錯誤

這種情況下,應用程序可能沒有辦法處理異常,也有可能由應用程序拋出。對於這種應用程序級別的異常。我們用兩種方式來catch:

[1]利用Express提供的應用程序的異常處理機制: [javascript] view plain copy print?技術分享技術分享
  1. app.error(function(err, req, res, next) {
  2. mailServie.sendMail({
  3. subject : "FixedAssetManager_Server[App Error]",
  4. text : err.message + "\n" + err.stack + "\n" + err.toString()
  5. });
  6. if (err instanceof PageNotFoundError) {
  7. res.render("errors/404");
  8. } else if (err instanceof ServerError) {
  9. res.render("errors/500");
  10. }
  11. });

[2]應用程序已經無法響應處理了,則利用node.js提供的,對於進程級別的異常處理方式: [javascript] view plain copy print?技術分享技術分享
  1. process.on("uncaughtException", function (err) {
  2. mailServie.sendMail({
  3. subject : "FixedAssetManager_Server[App Error]",
  4. text : err.message + "\n" + err.stack + "\n" + err.toString()
  5. });
  6. });
這兩種應用程序級別的異常,優先級都比較高,因此我們采用了郵件通知的策略,來輔助開發人員進行快速定位並修復。

靜態資源優化:壓縮合並與緩存

web應用中對於資源的定義大致分為:靜態資源、動態資源兩種。動態資源通常是可變的,需要進行相應處理的,而靜態資源在線上通常都是不會變的。常見的靜態資源有:javascript文件、css文件、圖片文件等。對於這些靜態文件,我們通過設置過期時間來進行緩存。而對於文本文件,由於瀏覽器的解析行為,對他們進行合並或者壓縮都不會產生影響。
這裏需要提到我們在組件中介紹的Loader。在項目剛被clone下來的時候,需要先執行makebuild來對項目進行初始化。在初始化的過程中,Loader會對項目的views文件夾中的文件進行掃描。它通常會掃描html界面:查找類似於如下的片段:

[html] view plain copy print?技術分享技術分享
  1. <!-- style -->
  2. <%- Loader("/public/stylesheets/login.min.css")
  3. .css("/public/libs/bootstrap/css/bootstrap.min.css")
  4. .css("/public/stylesheets/login.css")
  5. .done(assets)
  6. %>
  7. <!-- script -->
  8. <%- Loader("/public/libs/js/login.min.js")
  9. .js("/public/libs/jquery/jquery-1.10.2.min.js")
  10. .js(‘/public/libs/bootstrap/js/bootstrap.min.js‘)
  11. .js("/public/libs/CryptoJS_v3.1.2/rollups/sha256.js")
  12. .js("/public/libs/js/login.js")
  13. .done(assets)
  14. %>
去查找.css()以及.js()方法中的這些路徑參數,並對這些文件進行合並或壓縮混淆(這取決於配置),來產生一份assets.json(資產列表)文件。這裏面定義了一些鍵值對,鍵為上面代碼段中Loader()方法後面跟的參數,值為具體合並後文件的路徑。這樣,Loader會根據配置來判斷加載類型。如果當前為開發模式或者為debug模式,則調用.js()/.css(),基於其中的路徑參數來生成<script/> <link />。如果為發布模式,則根據.done()裏的assets鍵值對,結合Loader()的參數,來輸出合並後的文件。以減少前端http請求數量以及總大小。對publich文件夾下的文件,設置靜態文件緩存: [javascript] view plain copy print?技術分享技術分享
  1. //config for production env
  2. app.configure("production", function () {
  3. app.use(‘/public‘, express.static(staticDir, { maxAge: maxAge }));
  4. app.use(express.errorHandler());
  5. app.set(‘view cache‘, true);
  6. });
因為設置了緩存,在重新改動這些靜態文件再發布的時候,如果緩存時間太長,則客戶端的靜態文件可能不會被替換。對於這個問題,Loader通過在文件的後綴追加一個版本號來作為參數。這樣,當重新生成assets.json的時候每個文件會產生新的版本號,瀏覽器會請求“新文件”替換掉客戶端老的緩存文件。

Restful風格的URL

Restful以“Resource”為核心概念,認為URL是用來表示一種資源。而不應該表示一個動作或者其他的東西。而動作,比如“CRUD”正好對應http的四個method:get/post/put/delete。本項目中,我們大部分的URL以Restful風格為主,但沒有嚴格貫徹執行。

前端內容模板化、組件化

前端我們采用的是ejs的模板來構建,它很好得實現了html的片段化、組件化。有一個基礎的模板,別的都只是一塊html片段。它們在服務端完成組合、解析,生成完整的html流輸出到客戶端。
這樣的開發模式,使得前端代碼的劃分比較清晰,組件化也使得代碼的復用變得更容易。

makefile

在項目初始化的過程中,我們使用makefile文件來使得一些動作自動化運行。比如我們之前提到過的構建assets.json來合並文件的動作,就是通過執行makebuild文件來完成的。

增強的Debug模塊

目前,Node.js還沒有很強大的調試工具。常用的輔助診斷方式就是打log。但繁多的日誌輸出,混雜在http log裏實在是不方便判斷。我們在項目中使用了debug module來進行debug,他支持對log加不同顏色的key word並且還支持timestamp。你在一大堆日誌中,一眼就足以區分是從哪個module或者組件輸出的。我們在項目中對不同的layer應用不同的關鍵字:

[javascript] view plain copy print?技術分享技術分享
  1. var debug4Ctrller = require("debug")("controller");
  2. var debug4Proxy = require("debug")("proxy");
  3. var debug4Lib = require("debug")("lib");
  4. var debug4Test = require("debug")("test");
  5. var debug4Other = require("debug")("other");

將其置為全局:

[javascript] view plain copy print?技術分享技術分享
  1. global.debugCtrller = debug4Ctrller;
  2. global.debugProxy = debug4Proxy;
  3. global.debugLib = debug4Lib;
  4. global.debugTest = debug4Test;
  5. global.debugOther = debug4Other;
這樣你在controller層的log就可以以如下方式log: [javascript] view plain copy print?技術分享技術分享
  1. debugCtrller("XXX %s", "YYY");

這樣在Terminal中,輸出的log會按照不同的顏色進行區分,辨別性明顯增強:

一切都可自動化——Grunt

Grunt是Javascript任務運行器。

為什麽需要任務運行器?

對於需要反復重復的任務,例如壓縮、編譯、單元測試、代碼檢查等,自動化工具可以減輕你的勞動,簡化你的工作。

為什麽使用Grunt?

Grunt 有龐大的生態圈,並且每天都在增長。你可以自由地選擇數以百計的插件,幫助你自動化地處理任務。 用Grunt構建現有項目 1:全局安裝grunt命令行接口: [javascript] view plain copy print?技術分享技術分享
  1. npm install -g grunt-cli

2:在項目的根目錄下新建一個Gruntfile.js文件,該文件為grunt的配置、初始化文件 3:在packaget.json文件的devDependencies項中,添加grunt核心依賴以及需要的插件依賴: 註如果不想手動添加這些依賴,可以直接打開Terminal,在項目根路徑下運行: [javascript] view plain copy print?技術分享技術分享
  1. npm install grunt --save-dev

依賴會被自動寫入package.json的devDependencies項中。

關於Gruntfile的編寫規則,詳細請查看,Gruntjs中文文檔。 目前項目中用到的幾個gruntplugin:
  • jshint: 用於對JS語法進行強制檢查
  • csslint: 用於對css語法進行強制檢查
  • uglify: 用於壓縮項目文件
Gruntfile配置的寫法非常靈活並且隨意,支持對文件進行正則匹配等特性。

統一的代碼風格

對於多人協作的項目,代碼風格顯得尤為重要。對於代碼風格的統一,我們采用軟硬結合的方式。軟指的是自動化格式工具;硬指的是強制檢查工具。

自動格式化工具

目前項目中,兩人都采用SublimeText作為代碼編輯器。借助,SublimeText多如牛毛的插件,可以簡化很多重復性工作,帶來顯著的效率提升。這裏介紹幾個格式化工具:
  • alignment:等號對齊排版插件
  • JSFormat:JS代碼格式化排版工具
  • HTML-CSS-JS Prettify 代碼格式化工具
對於2,3兩個插件,選擇他們的原因是:他們開放了代碼風格的定義規則,而不是強制應用它們自己的規則。你可以任意定義你想讓它格式化的代碼風格,比如:

你只需要在項目的根目錄下,創建一個.jsbeautifyrc文件,裏面對縮進,空格等進行定義即可覆蓋默認配置。這非常方便那些已經習慣了自己有一套代碼風格的人使用這些插件。

更難能可貴的是,對於一個項目你可以有多個.jsbeautifyrc文件進行配置。他們的優先級取決於這些配置文件靠近待格式化文件的程度(某種意義上就是這些配置文件在目錄層次的深度)。這非常切換我們的需求:因為node項目前後端都是js。對於後端我們采用的是4空格縮進,對於前端JS我們采用的2空格縮進。那麽我們只需要在前端JS文件夾下,新建一個新的.jsbeautifyrc配置文件,copy上面的配置,然後將indent_size修改為2即可。

強制檢查工具

自動格式化工具只是一種“效率工具”,不足以形成“強制規定”。這裏我們輔以代碼檢查工具,來強制要求代碼風格、語法規範。

檢查工具在GruntSection已經列出,在commit代碼之前,必須運行檢查,並確保沒有任何Warnning跟Error。

Express 2.x to 3.x 接口適配與調整

1、ejs 服務端模板的調整:
原先的模板配置方式是采用在html文件,設置: [javascript] view plain copy print?技術分享技術分享
  1. <% layout(‘layout‘) -%>

來標識一個component會套用某個模板,而在3.x中ejs模板引擎,改為采用middleware的方式使用:(需要安裝一個module:express-partials) [javascript] view plain copy print?技術分享技術分享
  1. app.use(require(‘express-partials‘)());

與此同時,3.x專門提供了一個設置引擎的接口: [javascript] view plain copy print?技術分享技術分享
  1. app.engine(‘html‘, require(‘ejs‘).renderFile);

替代了原先2.x的: [javascript] view plain copy print?技術分享技術分享
  1. app.register(‘.html‘, require(‘ejs‘));

2、處理錯誤的方式改變:

2.x處理錯誤有專門的一個API:

[javascript] view plain copy print?技術分享技術分享
  1. app.error(function(err, req, res, next) {
  2. //error logic handle
  3. };

3.x退而采用middleware的方式來處理:

[javascript] view plain copy print?技術分享技術分享
  1. app.use(function(err, req, res, next) {
  2. //error logic handle
  3. }

更多express2.x to 3.x的改變,可以看看官方給出的變更列表

從EventProxy 到 async 切換

eventproxy是淘寶前端團隊開發的一個node.js事件處理代理。用於輔助開放人員組織代碼的執行順序,對於很多需要幹預執行順序與過程的代碼,避免了node.js深層嵌套的callback模式。

async跟eventproxy出於同樣的目的。但在API的設計模式上有所差異。async的API的風格偏向於“整合”,Eventproxy偏向於“拆分”。

Mongodb for node.js:mongoose的使用

model的定義

MongoDB裏數據的集合稱之為collection。而每個collection都有一個schema與之對應,可以簡單的理解為是對其數據的定義(類型與結構)。

對應到mongoose裏,一個schema是一個model,形如: 好處:mongodb直接存儲了json文件,mongoose內部完成了對model數據對象的mapping,並自動繼承了一些基本操作接口。這樣的model是真正意義上的“充血模型”,而不是很多編譯型語音內構建的“貧血模型”式的model。

給每個層定義索引文件

程序設計的一個重要指標:模塊性。在c/c++裏有頭文件,在面向對象語言裏有pagckage/namespace的概念。他們的目的之一就是提升模塊性,降低耦合度。

在node.js中,我們也可以采用類似c/c++的headfile的模式,以層為單位。將對外可見的以文件為單位的module以一個獨立的文件對外開放(通常我們稱其為index.js文件)。形如: 對於任何文件內的訪問權限跟可見性,我們都可以采用exports關鍵字予以控制。

supertest 模擬 http request 測試

supertest是一個用於模擬http request的module,可借助其進行web功能測試。

它提供了基於描述的API鏈式調用,可以非常容易得模擬http請求測試,形如:

密碼采用混入salt值的方式進行加密

密碼只是采用hash方式進行“加密”,還是相當不安全的。隨著現在計算能力的增強以及字典規模的擴大,簡單的md5已經非常不安全。一旦被拖庫,密碼很容易就會被破解。關於密碼的問題,除了采用(SSL加密數據傳輸鏈路)一直都沒有非常成熟的解決方案。所以,問題就退而求其次轉變為如何提升破解難度的問題。而在密碼中混入salt,是一直非常經濟而有效的方式。這裏我們處理用戶身份認證的方式是:

入庫之後的加密密碼 = sha3 (md5 (passwrod) + salt)

其中:salt的計算方式為:sha256(userName)

解決linux解壓縮包中文亂碼

在windows上打包的zip壓縮包,在ubuntu上解壓縮後,凡是文件名含有中文的都出現了亂碼。產生這一問題的原因是:在windows上壓縮文件,通常采用系統默認編碼(通常是gbk或gb2312),而傳到Linux上去,在linux上通常都默認采用的utf8編碼,所以需要進行解碼。

項目中有需要在服務器上對上傳上來的zip壓縮包解壓縮的步驟,默認調用的是shell命令(unzip命令)。網上很多提供的解決方案是通過提供"-O"參數,顯示指定編碼。但未能成功,因為在現在版本的unzip裏,該參數已經失效了。通過unzip幾經折騰,還是無法解決亂碼問題,於是轉而采用7z來進行解壓縮,並顯式指定英文環境ASCII編碼(通過LANG=C),示例: [javascript] view plain copy print?技術分享技術分享
  1. LANG=C 7z e `source zip file path` -o`target path`

其中參數“e”表示釋放所有文件到目標路徑(遞歸所有壓縮包中的子文件夾),參數“-O”指定解壓到的路徑(註意參數-O跟輸出路徑中間無空格)。

這一步只是完成了解壓,文件名這時還是亂碼的。此時需要linux上專門的轉碼工具——convmv來進行編碼轉換!

如果該命令不存在,可以先apt-getinstall一下,然後運行如下命令: [javascript] view plain copy print?技術分享技術分享
  1. convmv -f cp936 -t utf8 -r --notest -- `target path`/*

該命令的意思是:對`targetpath`下的所有文件,從cp936編碼轉換成utf8編碼,其中的--notest表示不進行測試,直接轉換。如果你想確保轉碼安全,可以先進行測試,看是否會產生亂碼,然後再進行轉碼,測試命令如下: [javascript] view plain copy print?技術分享技術分享
  1. convmv -f cp936 -t utf8 -r -- *

這是你只要關註文件名是否會產生亂碼,無需關註目錄名,如果沒有亂碼,就可以安全轉換了。

如果文件內容有亂碼,可以借助如下命令對文件進行轉碼: [javascript] view plain copy print?技術分享技術分享
  1. iconv -f cp936 -t utf8 -o output.txt input.txt

備註:我這邊遇到的是,在一個壓縮包內部有文件夾的情況下,在windows壓縮,在ubuntu下解壓縮產生了中文亂碼。但如果只是選中幾個文件直接壓縮,在ubuntu下不做轉碼,中文照常顯示。

源碼 & 總結 & TODO

由於邊摸索邊構建,在代碼規範性上還有待進一步重構。同時,對CNode官方社區的開源代碼表示感謝,它真的讓我們學到了許多。 本文所述項目開源在github

使用Node.js完成的第一個項目的實踐總結