最近在看阮一峰的ES6入門。下圖圈出來的地方不太懂。
#文中說到.js後綴不可省略。
但是下文中又出現如下寫法:
// lib.js
export let counter = 3;
export function incCounter() {
counter++;
}
// main.js
import { counter, incCounter } from './lib';
console.log(counter); // 3
incCounter();
console.log(counter); // 4
這裡import { counter, incCounter } from './lib';
不是省略了.js
後綴名嗎。
比較了一些人家寫的react程式碼:
import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import App from "./containers/App.jsx";
import Store from "./store/Store";
import React from "react";
這裡也省略了.js
後綴,但是import App from "./containers/App.jsx";
卻又把後綴名完整寫出來了。
請教一下各路大神,解答一下疑問:import..from的後面究竟在什麼情況下要寫.js
這類的後綴名,什麼時候不需要寫。還是因為別人用工具配置了什麼東西所以才不需要寫後綴名。
萬分感謝! ! !
請先區分瀏覽器原生解析還是打包工具預處理。
瀏覽器原生
瀏覽器在解析 import 語句時是需要後綴的,更確切地說,瀏覽器認 import 後面這個字串為一個 URL 位址。這個和你在 CSS 檔案裡寫
background-image: url(./path/to/a.jpg)
是一回事。瀏覽器會根據目前文件以及頁面的 BaseURL 等相關訊息,得出這個被依賴的資源的 URL 位址,進而向伺服器發送 HTTP 請求。字尾在HTTP 請求的URL 位址中並不是那麼重要,瀏覽器認的是HTTP 回應頭裡的Content-Type,只要託管你的js 或圖片的資源伺服器能正確回應瀏覽器的HTTP 請求,你可以隨便定義後綴(當然,一般資源伺服器會有一個從檔案副檔名到HTTP 回應頭MIMEType 的映射,你可以添加其他自訂後綴,使得伺服器能正確回應,但是最好按約定的進行設定),甚至可以掛羊頭賣狗肉,URL叫http://a.com/b.jpg 回傳內容是回應頭為application/javascript 的一段文字字元。
打包工具
打包工具的場景下,為了相容性,js 中的import 語句都會被翻譯成用ES5 實現的模組管理的導入語句,比如webpack 的
__webpack_require__
, 瀏覽器最後加載的是打包後的bundle 文件,並沒有執行import 語句(大部分瀏覽器至今尚未實作import)。 這時候,我們寫的 import 後面到底要不要後綴,全憑工具自己定義規則啊,只要工具在編譯打包時能找到被依賴模組。例如webpack可以設定先找.ts
如果沒有再找.es
再找.js
, 如果是一個資料夾,就看資料夾裡有沒有index.js
,甚至從node_modules
目錄中去找...總結:
轉譯打包工具:不用寫
原生支援ES6的node:不用寫
原生支援ES6的瀏覽器:能透過URL在伺服器上找到就行,如果真到了HTTP2盛行,ES6完全被瀏覽器實現,文件不用打包的時候,打包工具會有辦法輕鬆處理的。
總結:別寫
個人見解:
比如說:react、react-dom、vue等都是貢獻者發布的
NPM package
(也就是打包好的模組),使用NPM安裝後都會存放到node_modules目錄下,這些都是上文目錄下,這些都是上文目錄下所提的module而JS檔案並不是一個module,(這裡說的不完全)
在ES6中提供了
模組化
,(使用import、export定義模組)在Node.js中,採用CommonJS規範定義模組
推薦一篇文章
.js
不能省略,主要是為了可讀,以及區分。假設你目錄下有個自己寫的模組test
,還有一個自己寫的js檔test.js
。模組是以資料夾形式存在的,然後你用import './test'
,你無法確定你載入的是模組還是test.js
(雖然,在ES6中,一個JS檔案也算是一個模組) 。你看到的這種程式碼
檔import React from "react"
,並不是省略了.js
,而是直接省略了/index.js
。這是一個由npm安裝的包,在node_modules
資料夾下面,其實它導入的是node_modulesreactindex.js
,是整個包的入口文件,然後由index.js
加載react
react需要再去用到的其他子
js
暴露包中引入的部分。注意,在node.js裡,暫時還不支援ES6的
import語法,所以需要透過
require()引入包,用m
odule.exports和
exports