經過ES6 Module看import和require區別

前言

說到import和require,你們平時開發中必定很多見,尤爲是須要前端工程化的項目如今都已經離不開node了,在node環境下這二者都是大量存在的,大致上來講他們都是爲了實現JS代碼的模塊化,那爲何會出現兩種方案呢,又有什麼不一樣呢?javascript

模塊化的不一樣解決方案

追根溯源,JS這門腳本語言設計伊始就是沒有模塊化的,因此早期的全局變量容易形成命名衝突。但隨着web項目愈來愈大,JS的代碼量也與日俱增,因而社區就自發約定了幾種模塊化的方案:requirejs遵循AMD,seajs遵循CMD,node的module遵循CommonJS規範,雖然寫法上有所不一樣,都是爲了可以間接實現模塊化的基礎上保持較爲一致的代碼風格。html

隨着ES2015的發佈,官方標準定義了一種模塊化的方案,那就是import、export。但是,標準畢竟是標準,各大瀏覽器和node終端要實現標準仍是有一段距離的,目前來講都2018年了主流瀏覽器都還沒實現,還得依賴轉換工具(例如babel)轉爲ES5的代碼以後瀏覽器才能解析。因此這也就解釋了爲何咱們的工程化代碼中nodeJS遵循的CommonJS規範和ES6的模塊化方案並存的現象。前端

二者的區別

  • import是ES6標準中的模塊化解決方案,require是node中遵循CommonJS規範的模塊化解決方案
  • 後者支持動態引入,也就是require(${path}/xx.js),前者目前不支持,可是已有提案
  • 前者是關鍵詞,後者不是
  • 前者是編譯時加載,必須放在模塊頂部,在性能上會比後者好一些,後者是運行時加載,理論上來講放在哪裏均可以
  • 前者採用的是實時綁定方式,即導入和導出的值都指向同一個內存地址,因此導入值會隨着導出值變化。然後者在導出時是指拷貝,就算導出的值變化了,導入的值也不會變化,若是想要更新值就要從新導入
  • 前者會編譯成require/exports來執行

用法上的區別

import導入模塊

  • 導入模塊根據模塊導出時的寫法有不一樣寫法,具體能夠參考這裏,若是模塊是普通導出:java

// test.js
var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export {firstName, lastName, year}; // demo.js
import { firstName } from './test.js' console.log(firstName); // 'Michael'
import * as test from './test.js' console.log(test); //Module{} 全部內容
import { firstName as key, lastName as value } from './test.js' console.log(key + '--' + value);  // Michael--Jackson
  • 帶有默認值時,也是咱們平常開發中經常使用的方式:
// test.js
var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export default { firstName, lastName, year }; // demo.js
import test from './test.js' console.log(test); // {firstName: "Michael", lastName: "Jackson", year: 1958}

實際上這個default就是一個語法糖,只不過defaul是一個關鍵字,在這裏等同於node

import { default as test } from './test.js'

特別注意的是,export命令規定的是對外的接口,必須與模塊內部的變量創建一一對應關係。能夠理解爲export導出的是一種引用關係而不是一個具體的值,它們的實質是,在接口名與模塊內部變量之間,創建了一一對應的關係,例以下面這樣就會報錯:webpack

export 1; var m = 1; export m;

可是改成用花括號包起來變成對象以後就成了輸出引用關係就能夠正常導出了:es6

var m = 1; export { m }

 

require導入模塊

 

  • require導入模塊就沒那麼複雜了,導出時是什麼樣,導入時就仍是什麼樣:
// test.js
var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; module.exports = { firstName, lastName, year }; // demo.js
const test = require('./test.js'); console.log(test); // {firstName: "Michael", lastName: "Jackson", year: 1958}

 

  • 還有一種不經常使用的用法,直接導出:
// test.js
var year = 1958; exports.year = year; // demo.js
const test = require('./test.js'); console.log(test); // {year: 1958}

 

  • 須要注意的是,module.exports導出以後,後面的代碼就對導出的模塊無效了,例如上例中
// test.js
module.exports = { firstName, lastName, year }; exports.name = '222'; // demo.js
const test = require('./test.js'); console.log(test); // {firstName: "Michael", lastName: "Jackson", year: 1958}
  • 特別說明一下,因爲require是能夠在任意地方引入的,因此,咱們在開發中用~引入圖片的方式實際上等效於require:
<img src="~assets/img/icon/red_logo.png" class="logo" alt="">
//等效於
<img :src="require('assets/img/icon/red_logo.png')" class="logo" alt="">

總結

import和require就是兩種不一樣的JS模塊化實現方式而已,因爲以前npm生態的不少包都是基礎CommonJS規範寫的,因此至關一段時間以內必然是import和require這兩種模塊引入方式共存的。web

整體來講時代老是發展的,ES6做爲語言規範是早晚會被各大主流瀏覽器支持的,否則也就稱不上主流瀏覽器了。因此爲了長遠考慮,咱們仍是儘可能使用ES6的import來引入模塊,等之後瀏覽器支持了咱們也就能夠少改一些代碼了。npm

參考

 

注1:

JS報錯:Cannot use import statement outside a modulesegmentfault

在使用import和export的時候,type類型錯誤會致使沒法使用模塊化功能:

<script type="text/javascript">
  import test from './test/js';
  console.log(test);
</script>

 

須要將type中text/javascript改成module,模塊化的功能方能生效:

<script type="module"> import test from './test.js'; console.log(test); </script>

 

注2:

JS報錯:require is not defined

報錯緣由:
瀏覽器端不能識別require關鍵字,require是node.js環境下的,在node_modules文件夾裏面的模塊下面常見require

解決方法:
經過工具browserify或者是webpack把js文件編譯一下,轉成瀏覽器端可識別的。

//安裝browserify ,我這裏是全局安裝

npm install -g browserify

// 編譯

browserify ./source/module.js -o ./dist/dist.js

便可在dist目錄下看到打包後的dist.js文件。 
browserify 後面的第一個參數表示要打包的前端程序的入口,-o或者>表示打包後的輸出文件。browserify會根據入口文件中的require或者import(ES6,須要安裝babel)自動完成依賴分析,並將依賴文件打包爲一個單文件。
————————————————
版權聲明:本文爲CSDN博主「giao00000」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/wml00000/article/details/84181227

 

原文出處:

西風瘦碼,ES6學習筆記(二)—— 經過ES6 Module看import和require區別,http://www.javashuo.com/article/p-ckzwyfvj-dm.html

相關文章
相關標籤/搜索