Webpack实战:入门、进阶与调优
上QQ阅读APP看书,第一时间看更新

2.1.3 导入

在CommonJS中使用require进行模块导入。如:


// calculator.js
module.exports = {
    add: function(a, b) {return a + b;}
};
// index.js
const calculator = require('./calculator.js');
const sum = calculator.add(2, 3);
console.log(sum); // 5

我们在index.js中导入了calculator模块,并调用了它的add函数。

当我们require一个模块时会有两种情况:

·require的模块是第一次被加载。这时会首先执行该模块,然后导出内容。

·require的模块曾被加载过。这时该模块的代码不会再次执行,而是直接导出上次执行后得到的结果。

请看下面的例子:


// calculator.js
console.log('running calculator.js');
module.exports = {
    name: 'calculator',
    add: function(a, b) {
        return a + b;
    }
};

// index.js
const add = require('./calculator.js').add;
const sum = add(2, 3);
console.log('sum:', sum);
const moduleName = require('./calculator.js').name;
console.log('end');

控制台的输出结果如下:


running calculator.js
sum: 5
end

从结果可以看到,尽管我们有两个地方require了calculator.js,但其内部代码只执行了一遍。

我们前面提到,模块会有一个module对象用来存放其信息,这个对象中有一个属性loaded用于记录该模块是否被加载过。它的值默认为false,当模块第一次被加载和执行过后会置为true,后面再次加载时检查到module.loaded为true,则不会再次执行模块代码。

有时我们加载一个模块,不需要获取其导出的内容,只是想要通过执行它而产生某种作用,比如把它的接口挂在全局对象上,此时直接使用require即可。


require('./task.js');

另外,require函数可以接收表达式,借助这个特性我们可以动态地指定模块加载路径。


const moduleNames = ['foo.js', 'bar.js'];
moduleNames.forEach(name => {
    require('./' + name);
});