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]
总结:
- nodejs不支持import from方法,需要配置.babelrc文件,babel-node的方式执行
- module.exports用在暴露一个函数或变量的情况下,此时不能用exports代替,nodejs不允许对exports重新赋值,exports只是对module.exports的全局引用,重新赋值exports会切断两者之间的引用,最初被定义为一个可以添加属性的空对象。exports.done 只是module.exports.done的简写。module.exports = exports = done
- 如果一个程序既有module.exports又有exports,最终暴露的是module.exports。