模块化机制

JavaScript在ES6之前一直没有标准的模块化机制,这对编写大型项目非常不利。之后出现了CommonJS规范(用于NodeJS),AMD规范等,实现了JavaScript的模块化机制。ES6根据这些已有的规范,推出了语言级的模块化标准。

export和import

export 暴露模块内容

export可以暴露变量、类或是方法。下面代码中,通过export暴露了类的定义:

point.js

export class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    toString() {
        return '(' + this.x + ',' + this.y + ')';
    }
}

export class ColorPoint extends Point{
    constructor(x, y, color) {
        super(x, y);
        this.color = color;
    }

    toString() {
        return '(' + this.x + ',' + this.y + ',' + this.color + ')';
    }
}

import 引入模块内容

在另一个文件中可以通过import引入模块中暴露的变量、方法或类:

index.js

import {Point,ColorPoint} from './point';

let c = new ColorPoint(1, 2, 'RED');
console.log(c.toString());

我们可以将其理解为解构赋值,export输出一个含有多个导出内容的对象,import时使用对应的字段来接收。point则是文件名,其后缀.js可以省略,当然写上也没有问题。

注:实际上,使用CommonJS模块规范的Node无法运行上述代码,浏览器中也无法直接运行,但我们可以配置webpack工具将上述代码打包来进行测试,具体请参考webpack相关章节。

一次暴露多个内容

let i = 1;
let foo = function () {
};
export {i, foo};

前面的写法中,我们直接把export关键字加到了class前面,这里我们也可以使用大括号,一次暴露多个内容。

export default 默认导出

我们可以使用export default指定一个默认导出内容。

export default class ColorPoint extends Point{ ... }

引用时就可以不必使用大括号了:

import ColorPoint from './point';

默认导出的内容,实际上我们可以对其任意命名,比如上述导入代码写作import aaa from './point';也是可以的。

使用as命名

非默认导出的内容,我们可以使用as关键字给暴露的内容指定一个别名。

export {i as magicNum, foo};

编写独立模块

封装模块

上面我们学习了如何在工程内导入文件定义的内容,那么如何编写一个独立的模块,发布到npm仓库,再在其他工程引入呢?

这也其实比较简单,关键是创建好package.json就行了。

package.json

{
  "name": "mylib",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

package.json中,最重要的两个字段:

  • name:模块名,我们从其他工程引入该模块代码时需要这个名字
  • main:入口文件,我们模块导出的内容都需要在这个入口文件中统一暴露

index.js

export default {
    add: function(a, b) {
        return a + b;
    }
};

这样,我们就编写好一个模块了。

至于如何发布模块,请参考npm相关章节。

加载node_modules中的模块

我们在工程中安装好模块后,模块的代码会拷贝到node_modules中。工程node_modules目录下的模块,会在模块的默认搜索路径下,因此我们不需要手动指定如../../util这种相对路径,在任意位置都能引用。

假设我们的模块名为mylib,其入口文件为index.js,那么index.js中暴露的内容就可以import mylib from 'mylib';这种写法引入。

导入模块代码:

import mylib from 'mylib';

如果模块暴露多个内容,也是可以用import { a, b, c} from 'mylib';这种形式引入多个内容的。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap