Webpack 入门指南 - 2.模块

这一次我们谈谈模块问题。

通常我们希望这个项目可以分为多个独立的模块,比如,上一次提高的 hello 函数,如果我们定义为一个模块,其它模块引用之后,直接调用就好了。在前端怎么使用模块呢?这可说来话长了。

如果我们把 hello 函数定义在文件 hello.js 中,内容如下:

function hello(){
    alert("Hello, Webpack!");
}

然后把主入口函数 index.js 的内容写成下面的内容,你应该会得到一个错误信息。

require("./hello");

hello();

对话框是弹不出来的。错误信息如下:

Uncaught ReferenceError: hello is not defined, 明明定义了 hello 函数,却偏偏说找不到。

1. CommonJs 模块

CommonJs 是目前比较流行,也是出现较早的模块技术,它诞生于 NodeJs,使用起来其实比较简单。

首先,它把一个独立的文件看成一个模块,比如上面的 hello.js 文件,就可以当成一个模块。模块的名称就是文件名称,但是可以不用提供扩展名 .js,直接使用文件名就可以。

在导入一个模块的时候,使用 require 函数,注意是函数,并不是关键字,JavaScript 并没有提供这个关键字。函数的参数就是模块名称,不过,要注意模块分为两种,自定义的模块和系统模块。

自定义的模块必须使用 . 或者 .. 开头的相对路径,如果都在同一个目录下,也需要使用 . 来表示当前路径,比如上面用到的 require("./hello")。

不是使用 . 或者 .. 开始的相对路径的,都称为系统模块,系统模块的路径其实在 node_modules 文件夹中,每个子文件夹就是一个系统模块。

require 函数的返回结果就是模块导出的内容。

我们的模块没有导出任何内容。所以,虽然被 index 引用了,但是在 index 中却是无法访问的。这也说明模块中定义的函数其实是局部函数,并不是通常意义上的全局函数了。

我们要在模块中导出内容怎么办呢,CommonJs 提供了 exports 对象。

在 CommonJs 模块中,希望导出的内容必须通过 exports 对象,这是 CommonJs 系统提供的系统对象,我们可以直接使用。导出的内容以键值对的形式定义到这个对象上,键就是导出的名称,值就是准备导出的内容。

比如,我们希望将 hello 函数导出为名为函数的函数,好像挺绕的,其实很简单。