require 和 import,都是為了JS子產品化使用。最近項目中,因為多人協同開發,出現了一個項目中同時使用了require 和 import 引入依賴的情況。正常情況下,一個項目中最好是對引入方式做一個規範。下面我們就來看一下require 和 import的差別:
一.require
require是Commonjs的規範,node應用是由子產品組成的,遵從commonjs的規範。用法:
a.js
function test (args) {
// body...
console.log(args);
}
module.exports = {
test
};
b.js
let { test } = require('./a.js');
test('this is a test.');
require的核心概念:在導出的檔案中定義module.exports,導出的對象類型不予限定(可為任意類型)。在導入的檔案中使用require()引入即可使用。本質上,是将要導出的對象,指派給module這個對象的exports屬性,在其他檔案中通過require這個方法來通路exports這個屬性。上面b.js中,require(./a.js) = exports 這個對象,然後使用es6取值方式從exports對象中取出test的值。
二.import
import是es6為js子產品化提出的新的文法,import (導入)要與export(導出)結合使用。用法:
a.js:
export function test (args) {
// body...
console.log(args);
}
// 預設導出子產品,一個檔案中隻能定義一個
export default function() {...};
export const name = "lyn";
b.js:
// _代表引入的export default的内容
import _, { test, name } from './a.js';
test(`my name is ${name}`);
三、commonjs子產品與ES6子產品的差別
1.commonjs輸出的,是一個值的拷貝,而es6輸出的是值的引用;
2.commonjs是運作時加載,es6是編譯時輸出接口;
文章目錄
概念
一、ES6子產品化的使用
1、es6中的export
2、es6中的import
二、CommonJs規範的使用
1、CommonJs中的exports
2、CommonJs中的require
三、CommonJs規範與ES6中import的差別
1、引入子產品的不同點
2、引入子產品的性能不同點
3、暴露子產品的不同點
四、在nodeJs中怎麼使用
概念
CommonJs是一種子產品化規範,在ES6之前的,用于伺服器端nodeJs和浏覽器端。
ES6标準釋出後,子產品化标準是以export指令導出接口,以import引入子產品。
但是在node子產品中,我們依舊很多地方采用的是CommonJS規範
即:使用module.exports導出接口,使用require引入子產品。
這兩種方式我們或多或少都有用過,隻是不了解這是2種不同的規範
一、ES6子產品化的使用
es6中子產品化靠export { }暴露導出子產品,靠import ... from '...'引入子產品
1、es6中的export
子產品js使用export指令輸出變量
注意:這裡輸出的必須是變量,而不能是值(包括方法)
注意:export指令不需要=,隻要後面跟一個變量即可
正确示例:
// 直接暴露
export var test = 'Michael';
// 設定變量暴露
var test = 'Michael';
export {
test
}
錯誤示例:
// 直接暴露
export 1; //報錯
// 設定變量暴露
var test = 1;
export test; //報錯
以上錯誤的原因,是因為export指令後面不是變量而是一個值,即使是指派給了test,它也是一個值(方法同理)。
正确用法中是把值包在了對象裡{ test }
2、es6中的import
目标檔案,使用import ... form '...'引入子產品(前提是暴露子產品正确)
import指令引入沒什麼坑,主要延伸是結合ES6的解構指派
普通引入示例
import fs from 'fs' //引入整個fs子產品
var test = fs.star(....) //調用fs子產品中的star方法
解構引入示例
import { stat,readFile } from 'fs' //引入fs子產品中的stat,readFile方法,其餘不引入
var test = star(....) //調用fs子產品中的star方法
二、CommonJs規範的使用
CommonJs規範靠exports.xx = xx或module.exports = { xx }暴露導出子產品。
靠var xx = require('...')或var { stat, exists, readFile } = require('fs');引入子產品
1、CommonJs中的exports
注意:這裡的exports不是一個指令
注意:這裡的exports是有s的,且後面需要使用=,這裡我的了解,exports自身是變量,引入就是依靠這個變量進行的
使用exports示例
var test = 1;
exports.test = test;
使用module.exports示例
var test = 1;
module.exports = {
test
}
2、CommonJs中的require
導入也沒什麼坑,同樣可以使用解構
普通引入示例
var fs = require('fs') //引入整個fs子產品
var test = fs.star(....) //調用fs子產品中的star方法
解構引入示例
var { stat,readFile } = require('fs') //引入fs子產品中的stat,readFile方法,其餘不引入
var test = star(....) //調用fs子產品中的star方法
三、CommonJs規範與ES6中import的差別
1、引入子產品的不同點
require('xx')可以直接作為一個對象,也就是可以直接當成變量來使用,不指派。如:require('xx').star(...)
而es6的import ... form ...是固定寫法,不能操作
2、引入子產品的性能不同點
CommonJs規範的引入require('xx')是“運作時加載”
而es6的import ... form ...是按需引入,編譯過程按照import指令來選擇編譯
3、暴露子產品的不同點
在上面使用介紹,暴露子產品的差別已經很明顯了:
es6的export指令不用=暴露一個變量(一般為對象)
CommonJs的exports.xx=xx,是依靠exports變量自身來暴露的
四、在nodeJs中怎麼使用
我們都知道es6是絕對通用的規範,且會更新到es7、es8等。而既然es6有子產品化的方法,那麼CommonJs規範将逐漸被替換。
但是現在而言,import、export等很多es6指令,還需要依靠編譯成es5來實作。
比如在vue-cli當中,es6的使用就需要依賴webpack的babel進行編譯成es5。
是以在nodeJs中如果不引入babel或其他方法來編譯es5的話,依舊需要老老實實使用CommonJs規範。
ndoeJs使用es6import、export指令的解決方法,可以看阮一峰老師的ECMAScript6,.mjs字尾檔案名
.