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后綴文件名 本文參考阮一峰老師的ECMAScript6 與一些關於js編譯與運行的博客
.