Node.js基礎隨筆

1. 爲何要學Node.js

  • 基本的網頁開發:前端(css/html/js),服務端(node.js/java/php等),運維部署
  • 做爲前端開發,經過Node.js學習服務端,能夠在js不用學習另外一門新語言基礎上,較容易上手

2. Node.js是什麼?

  • 把Chrome的v8引擎(JavaScript引擎)移植出來,開發獨立的JavaScript運行環境。代碼只是特殊格式的字符串,JavaScript引擎能夠去執行和解析。
  • node.js的特性:事件驅動和非堵塞IO模型
  • npm:世界上最大的開源生態系統,大多數js相關的包都放在npm上,方便開發人員下載使

3. Node.js的JavaScript(沒有DOM和BOM)

  • ECMAScript: js基礎語法
  • 核心模塊
(在Node.js這個執行環境中爲JavaScript提供一些服務器級別的api,這些api大多包裝到一個具名的核心模塊中)
    - fs 文件操做模塊
    - http 網絡服務構造模塊
    - OS 操做系統模塊
    - path 路徑處理模塊
    - url 路徑操做模塊
複製代碼
  • 第三方模塊: art-template(npm 下載)
  • 自定義模塊: 本身建立的文件

3.1 瀏覽器的JavaScript

  • ECMAScript:js基礎語法: 變量、運算符、流程控制(分支語句,循環結構)、數組、函數、內置對象(Math/Date/String/Array/Object)
  • 文檔對象模型(DOM: 處理網頁內容的方法和接口(api)。
  • 瀏覽器對象模型(BOM: 與瀏覽器進行交互的方法和接口(api)。

4. 模塊系統

node沒有全局做用域。在Node.js中,經過require方法加載和執行多個JavaScript腳本文件。文件與文件之間因爲是模塊做用域,即便加載執行多個文件,能夠徹底避免變量命名衝突污染。可是某些狀況下,模塊與模塊是須要進行通訊的,可經過require方法得加載文件模塊導出的接口對象。即:php

  • 模塊做用域
  • 經過require方法,加載文件模塊和執行裏面的代碼
  • 經過require方法,得加載文件模塊導出的接口對象exports

4.1 接口對象

每一個模塊都提供一個接口對象,默認爲空對象,把須要被外部訪問的成員掛載在exports接口對象css

  • 導出多個成員(存在對象中)
b.js中
    exports.a = 123
    exports.b = 'hello'
    exports.c = function () {
        console.log('ccc')
    }
    exports.d = {
        foo: 'bar'
    }
    
    a.js中
    var bExports = require('./b')//require加載模塊時,可省略後綴名
    console.log(bExports.d)
複製代碼
  • 導出單一成員(直接拿到一個字符串、函數或對象等等)
b.js中
    module.exports = 'hello'
    module.exports = function () {
        console.log(ccc)
    }
    module.exports = {
      add: function () {
        return x + y
      },
      str: 'hello'
    }
    會發生覆蓋,只拿到最後一個
    
    a.js中
    var bExports = require('./b')
    console.log(bExports)
複製代碼
  • 原理
//在 Node 中,每一個模塊內部都有一個本身的 module 對象,還有一個成員exports(也是一個對象) 
    當對外導出成員,只須要把導出的成員掛載到 module.exports 中
    var module = {
      exports: {
        foo: 'bar',
        add: function (x, y){
            return x + y
        }
      }
    }
    //添加或導出成員 modeule.exports.xxx = xxx,爲了簡化你的操做,專門提供了一個變量:exports 等於 module.exports
    var exports = module.exports
    //當二者一致時,能夠經過任何一個添加和導出內部成員如:
    exports.a = 'hello'
    module.exports.b = 'hi'
    //當一個模塊須要導出單個成員的時候,只能給module.exports賦值,給 exports直接 賦值是無論用的,由於exports的指向發生改變,而模塊的接口對象是module.exports。
    //同理,給 module.exports 從新賦值,指向改變,斷開和exports的引用
複製代碼

4.2 require的加載規則html

即根據模塊標識來加載即:require('模塊標識符')
  1.本身寫的模塊
    路徑形式的模塊:1./ 當前目錄,不可省略 , 2../ 上一級目錄,不可省略 3.js 後綴名能夠省略
      var b = require('./foo.js')
      var b = require('./foo')
  2.核心模塊
    核心模塊的本質也是文件,已經被編譯到了二進制文件中(下載後,編譯在node.exe),咱們只須要按照名字來加載就能夠了
      var http = require('http')
      var fs = require('fs')
  3.第三方模塊
       凡是第三方模塊都必須經過 npm 來下載
       使用的時候就能夠經過 require('包名') 的方式來進行加載纔可使用
       如: var template = require('art-template')
       整個加載過程當中:
        先找到當前文件所處目錄中的 node_modules 目錄
        node_modules/art-template
        node_modules/art-template/
        node_modules/art-template/package.json
        node_modules/art-template/package.json 文件中的 main 屬性
        main 屬性中就記錄了 art-template 的入口模塊
        若是 package.json文件不存在或者main指定的入口模塊是也沒有,自動找該目錄下的 index.js,index.js 是做爲一個默認備選項
        若是以上全部任何一個條件都不成立,進入上一級目錄找 node_modules
        按照這個規則依次往上找,直到磁盤根目錄還找不到,最後報錯:Can not find moudle xxx
        一個項目有且僅有一個 node_modules 並且是存放到項目的根目錄
- 優先從緩存加載:再次加載某個模塊,不會執行裏面的代碼,但能夠從緩存中拿到其中的接口對象,這樣能夠避免重複加載,提升模塊加載效率
複製代碼

5. npm( node package manager)

5.1npm命令行工具

- npm --version版本
- npm install --global npm 升級
- npm init自動初始化package.json文件
- npm init -y跳過嚮導,快速生成
- npm install一次性把package.json文件的dependencies選項的全部依賴項下載回來
- npm install art-template只下載
- npm install art-template --save下載並保存到dependencies選項
- npm uninstall art-template刪除,依賴項依然存在
- npm install art-template --save刪除同時刪除依賴信息
複製代碼

5.2 解決npm被牆的問題

npm存儲包文件的服務器在國外,有時會速度很慢。前端

淘寶開發團隊把npm在國內做了個備份淘寶 NPM 鏡像java

安裝淘寶cnpmnode

在任意目錄執行均可以
--global表示安裝到全局,而不是當前目錄
npm install --global cnpm
cnpm intstall art-template
若是不想安裝cnpm又想用淘寶的服務器下載
npm install art-template --registry=http://registry.npm.taobao.org
每次手動添加後面的參數很麻煩,能夠把這個選項加入配置文件中
npm config set registry=http://registry.npm.taobao.org
查看npm配置信息是否成功
npm config list
通過上面命令的配置,之後全部的```npm install```均可以經過淘寶服務器來下載
複製代碼

5.3 package.json 包描述文件

每一個項目都應該有個package.json文件,經過npm init自動初始化出來git

PS E:\迅雷下載\14Nodejs教程精講(7天+5天贈送)\nodejs資料(7天)\03\code> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (code)
version: (1.0.0) 0.0.1
description:
entry point: (index.js) main.js
test command:
git repository:
keywords:
author: zhanglichun
license: (ISC)
About to write to E:\迅雷下載\14Nodejs教程精講(7天+5天贈送)\nodejs資料(7天)\03\code\package.json:

{
  "name": "code",
  "version": "0.0.1",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "zhanglichun",
  "license": "ISC"
}
複製代碼

再經過npm install art-template --save來下載第三方包,web

{
  "name": "code",
  "version": "0.0.1",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "zhanglichun",
  "license": "ISC",
  "dependencies": {
    "art-template": "^4.13.2"
  }
}
複製代碼

package.json文件多了dependencies這個選項,可保存第三方包的依賴信息。數據庫

若是node_modules不當心被刪,可經過npm install,自動地把package.json裏的dependencies中全部的依賴項下載回來apache

5.4 修改完代碼自動重啓

問題:每次修改完有關Node.js的代碼時,都要在命令行工具(cmd等)ctrl+c重啓

解決:使用第三方命令行工具nodemon ,來幫咱們解決修改代碼頻繁啓動服務器的問題

nodemon是基於Node.js開發的第三方命令行工具,使用時咱們須要獨立安裝

--global是全局安裝,在任意目錄執行該命令均可以
npm install --global nodemon
複製代碼

安裝完畢,經過nodemon app.js啓動服務,它會監視文件變化,當文件發生變化時,自動重啓服務器

6. web服務端開發

  • 端口號:
    • IP地址定位的是計算機
    • 端口號定位的是具體應用程序
    • 全部聯網通訊的軟件都必需要端口號
  • Content-Type
    • 在服務端默認響應發送的數據內容是utf8編碼,瀏覽器在不知道服務器響應內容的編碼的狀況下會按照當前操做系統的默認編碼去解析,中文操做系統默認是gbk,特別文本類型的數據,會出現防止中文解析亂碼問題,解決方法就是正確的告訴瀏覽器我給你發送的內容是什麼編碼的。
    • 不一樣的資源對應的 Content-Type 是不同,具體參照:tool.oschina.net/commons
  • 狀態碼
    • 301 永久重定向,瀏覽器會記住,除非清除瀏覽器數據

    • 302 臨時重定向,瀏覽器不會記住,會從新發出請求

      res.statusCode=302/res.setHeader('Location','/')

7. Node.js中其餘成員

在每個模塊中,除了require、exports等模塊相關的API外,還有兩個特殊成員

__dirname 動態獲取當前文件模塊所屬目錄的絕對路徑

__filename 動態獲取當前文件的絕對路徑

在文件操做中,相對路徑是是不可靠的,由於在node文件操做路徑被設計爲相對於執行 node 命令所處的終端路徑,因此在文件操做中的相對路徑都統一轉爲 動態的絕對路徑

在拼接過程當中,爲了不手動拼接帶來的低價錯誤,使用path.join(__dirname, './a.txt')來輔助拼接

補充:模塊中的路徑標識和這裏的路徑無關

9. 模板引擎

  • 客戶端渲染 如商品評論等 不利於seo搜索引擎優化,客戶體驗更好
    • 如:整個頁面,局部刷新獲取數據庫的數據,可經過Ajax向服務端發出請求數據接口(鏈接服務器,獲取要展現的數據),響應返回數據,再經過模板引擎在客戶端渲染數據
  • 服務端渲染 如商品列表 有利於seo搜索引擎優化
    • 如:經過Node.js創建服務端,發出請求,讀取文件,經過模板引擎在服務端渲染數據,把響應返回
var fs = require('fs')
    var template = require('art-template')
    var server = http.createServer()
    var wwwDir = 'D:/movie/www/'
    server.on('request', function (req, res) {
      // 1.準備模板===讀取template-apache.html
      fs.readFile('./template-apache.html', function (err, data) {
        if (err) {
          return res.end('404 Not Found')
        }
        // 2.準備數據===獲取www目錄列表
        fs.readdir(wwwDir, function (err, files) {
          if (err) {
            return res.end('404 Not Found')
          }
          // 3.使用模板引擎生成html內容,返回客戶端
          var htmlStr = template.render(data.toString(), { files: files })
          res.end(htmlStr)
        })
      })
    })
    server.listen(3000, function (req, res) {
      console.log('running.....')
    })
    
    template-apache.html的模板
    <tbody id="tbody">
          {{each files}}
          <tr>
            <td data-value=""><a class="icon dir" href="/D:/Movie/www/">{{$value}}/</a></td>
            <td class="detailsColumn" data-value="0"></td>
            <td class="detailsColumn" data-value="1509589967">2017/11/2 上午10:32:47</td>
          </tr>
          {{/each}}
        </tbody>
複製代碼

9. 其它

9.1 文件操做路徑和模塊路徑

文件操做路徑

在文件操做的相對路徑中能夠省略 ./
   ./data/a.txt 相對於當前目錄
   data/a.txt   相對於當前目錄
   /data/a.txt  絕對路徑,當前文件模塊所處磁盤根目錄
   c:/xx/xx...  絕對路徑
fs.readFile('./data/a.txt', function (err, data) {
  if (err) {
    console.log(err)
    return console.log('讀取失敗')
  }
  console.log(data.toString())
})
複製代碼

模塊路徑

在模塊加載中,相對路徑中的不能省略./,同時後綴名能夠省略
require(./data/a.txt) require(./data/a) 相對於當前目錄
require(data/a.txt) 報錯:Cannot find module 'data/a.txt'
require('/data/foo.js') C盤下沒有,報錯:Cannot find module 'C://data/a.txt'
複製代碼

9.2 代碼風格

  • javaScript Standard Style
    • 代碼分號的問題:不寫分號,但要在[]/()/``/前加分號,否則會報錯
  • Airbnb JavaScript Style

9.3 each

  • art-template的each, 是 art-template 模板引擎支持的語法,只能在模板字符串中使用
{{each 數組}}
    <li>{{ $value }}</li>
    {{/each}} 
複製代碼
  • js數組的foreach,不支持ie8如下版本
;['abc', 'd', 'efg'].forEach(function (item, index) {
      console.log(item)
    })
複製代碼
  • jQuery的each
    • 能夠在不兼容 forEach 的低版本瀏覽器中使用 jQuery 的 each 方法遍歷數組
$.each(['abc', 'd', 'efg'], function (index, item) {
      console.log(item)
    })
複製代碼
  • 遍歷 jQuery 選擇器選擇到的僞數組實例對象
$('div').each(function (index, item) {
      console.log(item)
    })
複製代碼
  • jQuery 由於原型是object,它的實例對象不能使用 forEach 方法。若是想要使用必須轉爲數組纔可使用
[].slice.call(jQuery實例對象
    原理是
    Array.prototype.mySlice = function () {
      var start = 0
      var end = this.length
      var tmp = []
      for (var i = start; i < end; i++) {
        // fakeArr[0]
        // fakeArr[1]
        // fakeArr[2]
        tmp.push(arguments[i])
      }
      return tmp
    }
    var fakeArr = {
      0: 'abc',
      1: 'efg',
      2: 'haha',
      length: 3
    }
    // 因此你就獲得了真正的數組。 
    [].mySlice.call(fakeArr)
複製代碼

9.4 軟件開發版本

  • 通常是這些客戶端軟件、技術框架開發者比較理解的多,升級後,須要人去下載
  • 作網站不多涉及到版本的概念,不須要下載,只需輸入url地址,
x.x.x 
    好比:2(新增功能比較多,甚至可能去除了某些功能).5(加入了新功能).0(修復bug,提高性能)
複製代碼
相關文章
相關標籤/搜索