创建一个新的Node 项目非常简单:创建一个文件夹,运行npm init
就好了。
npm命令会问几个问题,一直回车(回答yes)就行了。
mkdir my_module
cd my_module
npm init -y
npm init -y 命令中的参数-y 表示yes, 这样npm 会创建一个全部使用默认值的package.json文件。
如果你想要更多的控制权,去掉参数-y,你就能看到npm提出的一系列问题,包括授权许可、作者姓名,等等。完成之后看一下 package.json,你会在其中发现自己提供的那些答案。你也可以手动编辑,但记得必须是有效的JSON。
OK,现在空项目有了,可以创建模块了
模块既可以是一个文件,也可以是包含一个或多个文件的目录。
如果模块是一个目录,Node通常会在这个目录下找一个叫index.jis的文件作为模块的人口(这个默认设置可以重写)。
典型的模块是一个包含exports对象属性定义的文件,这些属性可以是任意类型的数据,比如字符串、对象和函数。
为了演示如何创建基本的模块,我们在一个名为currency.js的文件中添加一些做货币转换的函数。
其中有两个函数,分别对加元和美元进行互换。
【定义一个Node 模块(currency.js)】
const canadianDollar = 0.91;
function roundTwo(amount) {
return Math.round(amount * 100) / 100;
}
exports.canadianToUS = canadian => roundTwo(canadian * canadianDollar);
exports.USToCanadian = us => roundTwo(us / canadianDollar);
exports对象上只设定了两个属性。
也就是说引人这个模块的代码只能访问到canadian-ToUs 和 uSTocanadian这两个函数。而变量canadianDollar作为私有变量仅作用在canadianToUS和 USToCanadian的逻辑内部,程序不能直接访问它。
使用这个新模块要用到Node的require 函数,该函数以所用模块的路径为参数。
Node 以同步的方式寻找模块,定位到这个模块并加载文件中的内容。
Node查找文件的顺序是先找核心模块→然后是当前目录→最后是node_modules。
【require 和 同步I/O】
require 是Node 中少数几个同步I/O操作之一。
由于经常用到模块,并且一般都是在文件顶端引入,所以把 require做成同步的有助于保持代码的整洁、有序,还能增强可读性。
但在I/O密集的地方尽量不要用require。所有同步调用都会阻塞Node,直到调用完成才能做其他事情。比如你正在运行一个 HTTP 服务器,如果在每个进入的请求上都用了require,就会遇到性能问题。所以require和其他同步操作通常放在程序最初加载的地方。
【引入一个模块(test_currency.js)】
const currency = require('./currency');
console.log('50 Canadian dollars equals this amount of US dollars:');
console.log(currency.canadianToUS(50));
console.log('30 US dollars equals this amount of Canadian dollars:');
console.log(currency.USToCanadian(30));
执行效果:
用路径./ 来表明模块和程序脚本放在同一个目录下。
如果在require 模块时把./ 放在前面,Node 会在被执行程序所在的目录下寻找这个模块。且在引入时,.js 扩展名可以忽略。
在 Node定位到并计算好你的模块之后,require 函数会返回这个模块中定义的exports对象中的内容,然后你就可以用这个模块中的两个函数做货币转换了。
如果想把这个模块放到子目录中,比如 lib/,只要把require语句改成下面这样就可以了:
const currency = require('./lib/currency');
组装模块中的exports对象是在单独的文件中组织可重用代码的一种简便方法。