首頁  >  問答  >  主體

javascript - ES6 import {} from '..'後綴名的問題

最近在看阮一峰的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這類的後綴名,什麼時候不需要寫。還是因為別人用工具配置了什麼東西所以才不需要寫後綴名。
萬分感謝! ! !

阿神阿神2674 天前1198

全部回覆(3)我來回復

  • 迷茫

    迷茫2017-06-26 10:54:54

    請先區分瀏覽器原生解析還是打包工具預處理。

    瀏覽器原生

    瀏覽器在解析 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目錄中去找...

    總結:

    1. 轉譯打包工具:不用寫

    2. 原生支援ES6的node:不用寫

    3. 原生支援ES6的瀏覽器:能透過URL在伺服器上找到就行,如果真到了HTTP2盛行,ES6完全被瀏覽器實現,文件不用打包的時候,打包工具會有辦法輕鬆處理的。

    總結:別寫

    回覆
    0
  • ringa_lee

    ringa_lee2017-06-26 10:54:54

    個人見解:

    1. 比如說:react、react-dom、vue等都是貢獻者發布的NPM package(也就是打包好的模組),使用NPM安裝後都會存放到node_modules目錄下,這些都是上文目錄下,這些都是上文目錄下所提的module

    2. 而JS檔案並不是一個module,(這裡說的不完全)

      • 在ES6中提供了模組化,(使用import、export定義模組)

      • 在Node.js中,採用CommonJS規範定義模組

    3. 推薦一篇文章

    回覆
    0
  • 过去多啦不再A梦

    过去多啦不再A梦2017-06-26 10:54:54

    1. .js不能省略,主要是為了可讀,以及區分。假設你目錄下有個自己寫的模組test,還有一個自己寫的js檔test.js。模組是以資料夾形式存在的,然後你用import './test',你無法確定你載入的是模組還是test.js(雖然,在ES6中,一個JS檔案也算是一個模組) 。

    2. 你看到的這種程式碼import React from "react",並不是省略了.js,而是直接省略了/index.js。這是一個由npm安裝的包,在node_modules資料夾下面,其實它導入的是node_modulesreactindex.js,是整個包的入口文件,然後由index.js加載reactreact需要再去用到的其他子js

    3. 注意,在node.js裡,暫時還不支援ES6的import語法,所以需要透過require()引入包,用module.exportsexports

      暴露包中引入的部分。

    詳細請看MDN文件🎜

    回覆
    0
  • 取消回覆