淺談webpack模塊引用的五種方法

1、commonjs格式的require同步語法

const home = require('./Home');
… // 使用

 

2、commonjs格式的require.ensure異步語法

require.ensure([], require => {
  	const home = require('./Home');
  	… //使用
});

Home.js會被打包成一個單獨的chunk文件:1.fb874860b35831bc96a8.js,其名稱不具有可讀性,因此一般給require.ensure傳遞第三個參數。

require.ensure([], require => {
  	const home = require('./Home');
  	… //使用
}, bundle/home');

Home.js會被打包成一個具有指定文件名稱的chunk文件:home.fb874860b35831bc96a8.js,該文件在bundle目錄下。

在webpack.config.js文件中配置:

output: {
  	path: __dirname + '/public',
  	filename: '[name].js',
  	chunkFilename: '[name].bundle.js'
}

Home.js會被打包成一個具有指定文件名稱的chunk文件:home.bundle.js,該文件在bundle目錄下,而bundle目錄又在/public目錄下。

注意:如果在require.ensure的回調函數中引用了兩個以上的模塊,webpack會把它們打包在一起。

require.ensure([], require => {
  	const a = require('./a');
  	… //使用
  	const b = require('./b');
  	… //使用
}, bundle/a-b');

a.js和b.js會被打包成一個具有指定文件名稱的chunk文件:a-b.bundle.js,,該文件在bundle目錄下。如果不希望打包在一起,只能寫多個require.ensure分別引用每一個模塊。

給require.ensure傳遞的第一個參數可以是空數組,其實也可以是模塊,實現預加載懶執行。

require.ensure(['./Home'], require => {
   	const home = require('./Home');
   	… //使用
}, bundle/home');

Home.js會被下載下來,即所謂的預加載,但不會執行Home.js模塊中的代碼,當執行到onsthome = require('./Home')一句時才執行,即所謂的懶執行。

 

3、webpack自帶的require.include

require.include是webpack自身提供的,它可以實現require.ensure中的預加載功能,而不用把模塊寫在數組中。

require.ensure([],require => {
  	require.include('./Home');// 只加載不執行
  	… //使用
});

require.include的返回值是undefined,如果想使用模塊,需要再通過require引入。

require.ensure([],require => {
  	require.include('./Home');// 只加載不執行
  	const home = require('./Home'); // 執行
  	… //使用
}, bundle/home');

 

4、AMD異步加載

webpack既支持commonjs規範也支持AMD規範。

require(['./Home'], function(home){
  	… //使用
});

如果寫了多個模塊,那麼這些模塊都會被打包成一個文件。

require(['./a', './b'], function(a, b){
  	… //使用
});

a.js和b.js會被打包在一起,但AMD的方式無法傳入第三個參數來指定文件名稱。

require AMD與require.ensure的區別:

1)     require AMD傳遞一個模塊數組和回調函數,模塊都被下載下來且都被執行後才執行回調函數;

2)     require.ensure也是傳遞一個模塊數組和回調函數,但是模塊只會被下載下來,不會被執行,只有在回調函數中執行到require(模塊)一句時,該模塊纔會被執行。

在webpack.config.js文件中配置:

module.exports = {
 	entry: 'index.js'
	output: {
        	path: __dirname + '/public',
        	filename: '[name].js',
        	chunkFilename: '[name].bundle.js'
	}
}
eg1:require AMD

index.js:

require(["./a"], function(a) {
   	console.log("a");
    var b = require("./b");
   	console.log("b");
});
a.js:

console.log("1");
module.exports = 1;

b.js:

console.log("2");
module.exports = 2;

輸出:

1

a

2

b

 

eg2:require.ensure

index.js:

require.ensure(["./a"], require=> {
    console.log("a");
    var b = require("./b");
   	console.log("b");
    require("./a");
}, 'public/index');

a.js:

console.log("1");
module.exports = 1;

b.js:

console.log("2");
module.exports = 2;

輸出:

a

2

b

1

 

eg3:require.ensure

index.js:

require.ensure(["./a"], require=> {
    console.log("a1");
    var b = require("./a");
   	console.log("a2");
}, 'public/index');
require.ensure(["./b"], require=> {
    console.log("b1");
    var b = require("./b");
   	console.log("b2");
}, 'public/index');

a.js:

console.log("1");
module.exports = 1;

b.js:

console.log("2");
module.exports = 2;

輸出:

a1

1

a2

b1

2

b2

 

5、ES6的import

import會被轉化爲commonjs格式或是AMD格式,所以它不是一種新的模塊引用方式。babel默認會把ES6的模塊轉化爲commonjs規範,因此不需要再把它轉成AMD規範。

import home from './Home';

等價於

const home = require('./Home'); 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章