Javascript 模块基础

CommonJS 规范与实现

正如当年为了统一 JavaScript 语言标准,人们制定了 ECMAScript 规范一样,如今为了统一 JavaScript 在浏览器之外的实现,CommonJS 诞生了。CommonJS 试图定义一套普通应用程序使用的 API,从而填补 JavaScript 标准库过于简单的不足。CommonJS 的终极目标是制定一个像 C++ 标准库一样的规范,使得基于 CommonJS API 的应用程序可以在不同的环境下运行,就像用 C++ 编写的应用程序可以使用不同的编译器和运行时函数库一样。为了保持中立,CommonJS 不参与标准库实现,其实现交给像 Node.js 之类的项目来完成。

模块(Module)和包(Package)是 Node.js 最重要的支柱。开发一个具有一定规模的程序不可能只用一个文件,通常需要把各个功能拆分、封装,然后组合起来,模块正式为了实现这种方式而诞生的。在浏览器 JavaScript 中,脚本模块的拆分和组合通常使用 HTML 的 script 标签来实现。Node.js 提供了 require 函数来调用其他模块,而且模块都是基于文件的,机制十分简单。

CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。

为了方便,Node.js 为每个模块提供一个 exports 变量,指向 module.exports。这等同在每个模块头部,有一行这样的命令:

var exports = module.exports;

如果你觉得,exports 与 module.exports 之间的区别很难分清,一个简单的处理办法,就是放弃使用 exports,只使用 module.exports。

什么是模块

模块是 Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是 JavaScript 代码、JSON 或者编译过的 C/C++ 扩展。

在 Node.js 中,创建一个模块非常简单,因为一个文件就是一个模块,我们要关注的问题仅仅在于如何在其他文件中获取这个模块。Node.js 提供了 exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。

加载模块

在 Node.js 中,我们可以直接通过 require 获取核心模块,例如 require(‘fs’) 。核心模块拥有最高的加载优先级,换言之如果有模块与其命名冲突,Node.js 总是会加载核心模块。

覆盖 exports

有时候我们只是想把一个对象封装到模块中,例如:

// singleobjct.js
function Hello() {
    var name;
    this.setName = function (thyName) {
        name = thyName;
    };
    this.sayHello = function () {
        console.log('Hello ' + name);
    };
}

exports.Hello = Hello;

此时我们在其他文件中需要通过 require(‘./singleobject’).Hello 来获取 Hello 对象,这略显冗余,可以用下面方法稍微简化。

// hello.js
function Hello() {
  var name;
  this.setName = function(thyName) {
    name = thyName;
  };
  this.sayHello = function() {
    console.log('Hello ' + name);
  };
}
module.exports = Hello;

这样就可以直接获得这个对象了:

// gethello.js
var Hello = require('./hello');
hello = new Hello();
hello.setName('Yu');
hello.sayHello();

总结

CommonJS 模块的特点如下:

  • 所有代码都运行在模块作用域,不会污染全局作用域。
  • 独立性是模块的重要特点就,模块内部最好不与程序的其他部分直接交互。
  • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
  • 模块加载的顺序,按照其在代码中出现的顺序。

https://neveryu.github.io/2017/03/07/commonjs/

把常量定义在一个模块中

例如:

// constants.js
export const ALABAMA = 1;
export const ALASKA = 3;
export const ARIZONA = 4;

// test1.js
import * as constants from './constants';
console.log(constants.ALABAMA);
console.log(constants.ALASKA);

// test2.js
import {ALABAMA, ALASKA} from './constants';
console.log(ALABAMA);
console.log(ALASKA);

后面这段没看懂,原样照贴:

Additional tip: if you don’t want your constants to be mixed up with other values, you can use symbols. Each symbol is a unique value.

// constants.js
export const ALABAMA = Symbol('ALABAMA');
export const ALASKA = Symbol('ALASKA');
export const ARIZONA = Symbol('ARIZONA');

https://www.reddit.com/r/javascript/comments/3bo42p/sharing_constants_in_es6_modules/

你可能感兴趣的:(nodejs,Javascript,javascript)