天天看點

Nodejs的解讀(二)

nodejs的子產品

 nodejs的子產品允許從被引入的檔案中選擇要暴露給我們的函數和變量,如果子產品傳回的函數或變量不止一個,我們可以通過設定exports對象的屬性來指明,如果子產品隻傳回一個函數或變量,則使用module.exports屬性。

CommonJS子產品引入 

a子產品下面的index.js

const canadianDollars = .9;  //a 子產品的私有變量

function roundTwo (amount) {  // a子產品的是有方法,a子產品外面是通路不到
  return Math.round(amount * 100) / 100;
}

//對外面暴露的的兩個方法
exports.canadianToUs = canadian => roundTwo(canadian * canadianDollars)
exports.UsToCanadian = us => roundTwo(us / canadianDollars)
           

 我們要require的子產品順序是先查找nodejs的核心子產品,然後是目前的目錄,最後是node_modules,

require是nodejs中的少有的幾個同步的方法,一般都是在檔案頂端引入,保持代碼的整潔。

//nodejs的子產品規範引入CommonJS
const currency = require('./a');
console.log(currency)  //{ canadianToUs: [Function], UsToCanadian: [Function] }
           

ES6(es2015)方式引入

這裡有個坑,nodejs目前還不支援es6的import ,from方法,需要我們做相關的配置來相容 

全局安裝es-checker,運作會列出相關的支援情況

nelsen-mac:nodeshizhan mac$ es-checker

ECMAScript 6 Feature Detection (v1.4.1)

Variables
  √ let and const
  √ TDZ error for too-early access of let or const declarations
  √ Redefinition of const declarations not allowed
  √ destructuring assignments/declarations for arrays and objects
  √ ... operator

Data Types
  √ For...of loop
  √ Map, Set, WeakMap, WeakSet
  √ Symbol
  √ Symbols cannot be implicitly coerced

Number
  √ Octal (e.g. 0o1 ) and binary (e.g. 0b10 ) literal forms
  √ Old octal literal invalid now (e.g. 01 )
  √ Static functions added to Math (e.g. Math.hypot(), Math.acosh(), Math.imul() )
  √ Static functions added to Number (Number.isNaN(), Number.isInteger() )

String
  √ Methods added to String.prototype (String.prototype.includes(), String.prototype.repeat() )
  √ Unicode code-point escape form in string literals (e.g. \u{20BB7} )
  √ Unicode code-point escape form in identifier names (e.g. var \u{20BB7} = 42; )
  √ Unicode code-point escape form in regular expressions (e.g. var regexp = /\u{20BB7}/u; )
  √ y flag for sticky regular expressions (e.g. /b/y )
  √ Template String Literals

Function
  √ arrow function
  √ default function parameter values
  √ destructuring for function parameters
  √ Inferences for function name property for anonymous functions
  × Tail-call optimization for function calls and recursion

Array
  × Methods added to Array.prototype ([].fill(), [].find(), [].findIndex(), [].entries(), [].keys(), [].values() )
  √ Static functions added to Array (Array.from(), Array.of() )
  √ TypedArrays like Uint8Array, ArrayBuffer, Int8Array(), Int32Array(), Float64Array()
  √ Some Array methods (e.g. Int8Array.prototype.slice(), Int8Array.prototype.join(), Int8Array.prototype.forEach() ) added to the TypedArray prototypes
  √ Some Array statics (e.g. Uint32Array.from(), Uint32Array.of() ) added to the TypedArray constructors

Object
  √ __proto__ in object literal definition sets [[Prototype]] link
  √ Static functions added to Object (Object.getOwnPropertySymbols(), Object.assign() )
  √ Object Literal Computed Property
  √ Object Literal Property Shorthands
  √ Proxies
  √ Reflect

Generator and Promise
  √ Generator function
  √ Promises

Class
  √ Class
  √ super allowed in object methods
  √ class ABC extends Array { .. }

Module
  × Module export command   //不支援
  × Module import command   //不支援
           

全局安裝babel-cli,項目安裝babel-preset-es2015,建立.babelrc檔案

{
    "presets": [
        "es2015"
    ],
    "plugins": []
}
           
//es6的方式引入
import { canadianToUs, UsToCanadian } from './a';
console.log(canadianToUs, UsToCanadian)  //[Function] [Function]
           

 然後再指令行執行babel-node就可以正常列印

nelsen-mac:nodeshizhan mac$ babel-node module/
[Function] [Function]
           

b子產品下面的index.js

class Currency {
  constructor(dollar) {
    this.dollar = dollar
  }
  roundToDecimals (amount) {
    return Math.round(amount * 100) / 100
  }
  canadianToUs (canadian) {
    return this.roundToDecimals(canadian * this.dollar)
  }
  UsToCanadian (us) {
    return this.roundToDecimals(us * this.dollar)
  }
}

//exports = Currency 是錯誤的暴露方式

module.exports = Currency;  //這是正确的方式
           

module下面的index.js

const Currency = require('./b');
console.log(Currency)  //[Function: Currency]
const curr = new Currency(.9);
console.log(curr.canadianToUs(50))  //45
           

es6的執行方法 babel-node module/

//es6的導入方法
import Currency from './b';
console.log(Currency) //[Function: Currency]
           

總結:

  1. nodejs不支援import from方法,需要配置.babelrc檔案,babel-node的方式執行
  2. module.exports用在暴露一個函數或變量的情況下,此時不能用exports代替,nodejs不允許對exports重新指派,exports隻是對module.exports的全局引用,重新指派exports會切斷兩者之間的引用,最初被定義為一個可以添加屬性的空對象。exports.done 隻是module.exports.done的簡寫。module.exports = exports = done
  3. 如果一個程式既有module.exports又有exports,最終暴露的是module.exports。