import - node.js中require一個npm install的module做了什麼事情?

【字号: 日期:2022-09-06浏览:26作者:雯心

问题描述

刚刚发现require的module也会影响到后续的require,以moment和moment-timezone举例,也就是说:

/app.js

var moment = require(’moment’);console.log(moment.tz()); // 这样会报错,因为moment.tz()是moment-timezone这个module才有的function/*TypeError: moment.tz is not a function*/

但是如果我先require了moment-timezone,后续我再require了moment,npm install moment,我依然可以require(’moment’)而且这个moment就可以使用moment-timezone的功能,如下

/app.js

require(’moment-timezone’)var moment = require(’moment’);console.log(moment.tz()); //moment.utc('2017-06-27T06:59:14.475+00:00')

我不明白的点是,为什麽require(’moment-timezone’)之后,即使我没有npm install moment 我还是可以require(’moment’);而不会报错呢?这样的node modules是经过什麽设计或有什麽特殊的名词可以造成这样的行为吗?

顺带一提,如果上面的moment-timezone可以这样设计,假设我今天发佈了一个叫做noname的module在npm上供人使用,只要程序上先执行了require(’noname’); ,是否可以改了后续require(’express’)这个module的return内容,做到类似以下的作用:

require(’noname’);var express = require(’express’);express.thisIsMyExpress();//这是被我换过的express module

问题解答

回答1:1. 为什麽require(’moment-timezone’)之后,即使我没有npm install moment我还是可以require(’moment’)而不会报错呢?

查看moment-timezone依赖

$> npm info moment-timezone dependencies { moment: ’>= 2.9.0’ }

可以看出moment-timezone是依赖了moment的,这表示在安装moment-timezone时会自动安装moment,所以不需要再单独安装也可以使用。

2. 为什么require(’moment-timezone’)会影响后续var moment = require(’moment’)中`moment`的赋值

查看moment-timezone源码

1 //! moment-timezone.js 2 //! version : 0.5.13 3 //! Copyright (c) JS Foundation and other contributors 4 //! license : MIT 5 //! github.com/moment/moment-timezone 6 7 (function (root, factory) { 8 'use strict'; 9 10 /*global define*/ 11 if (typeof define === ’function’ && define.amd) { 12 define([’moment’], factory); // AMD 13 } else if (typeof module === ’object’ && module.exports) { 14 module.exports = factory(require(’moment’)); // Node 15 } else { 16 factory(root.moment);// Browser 17 } 18 }(this, function (moment) { 19 'use strict';

第14行可以看到moment-timezone修改了require(’moment’),众所周知npm模块是会缓存的,所以后续var moment = require(’moment’)被影响

顺便提一句,直接修改模块就和修改全局变量一样,并不是很好的实践。此处moment-timezone模块基本上算是`moment`模块的补丁,是一个特例.

相关文章: