javascript - ES6 import {} from ’..’后綴名的問題
問題描述
最近在看阮一峰的ES6入門。下圖中圈出來的地方不太理解。
文中說到.js后綴不可省略。但是下文中又出現(xiàn)了如下寫法:
// lib.jsexport let counter = 3;export function incCounter() { counter++;}// main.jsimport { counter, incCounter } from ’./lib’;console.log(counter); // 3incCounter();console.log(counter); // 4
這里import { counter, incCounter } from ’./lib’;不是省略了.js后綴名嗎。對(duì)比了一些人家寫的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';卻又把后綴名完整寫出來了。
請(qǐng)教一下各路大神,解答一下疑問:import..from的后面究竟在什么情況下要寫.js這類的后綴名,什么時(shí)候不需要寫。還是因?yàn)閯e人用工具配置了什么東西所以才不需要寫后綴名。萬(wàn)分感謝!!!
問題解答
回答1:請(qǐng)先區(qū)分瀏覽器原生解析還是打包工具預(yù)處理。瀏覽器原生瀏覽器在解析 import 語(yǔ)句時(shí)是需要后綴的,更確切地說,瀏覽器認(rèn) import 后面這個(gè)字符串為一個(gè) URL 地址。這個(gè)和你在 CSS 文件里寫 background-image: url(./path/to/a.jpg) 是一回事。瀏覽器會(huì)根據(jù)當(dāng)前文件以及頁(yè)面的 BaseURL 等相關(guān)信息,得出這個(gè)被依賴的資源的 URL 地址,進(jìn)而向服務(wù)器發(fā)送 HTTP 請(qǐng)求。后綴在 HTTP 請(qǐng)求的 URL 地址中并不是那么重要,瀏覽器認(rèn)的是 HTTP 響應(yīng)頭里的 Content-Type,只要托管你的 js 或圖片的資源服務(wù)器能正確響應(yīng)瀏覽器的 HTTP 請(qǐng)求,你可以隨便定義后綴(當(dāng)然,一般資源服務(wù)器會(huì)有一個(gè)從文件擴(kuò)展名到 HTTP 響應(yīng)頭 MIMEType 的映射,你可以添加其他自定義后綴,使得服務(wù)器能正確響應(yīng),但是最好按約定的進(jìn)行配置),甚至可以掛羊頭賣狗肉,URL叫http://a.com/b.jpg 返回內(nèi)容是響應(yīng)頭為 application/javascript 的一段文本字符。
打包工具打包工具的場(chǎng)景下,為了兼容性,js 中的 import 語(yǔ)句都會(huì)被翻譯成用 ES5 實(shí)現(xiàn)的模塊管理的導(dǎo)入語(yǔ)句,比如 webpack 的 __webpack_require__, 瀏覽器最后加載的是打包后的 bundle 文件,并沒有執(zhí)行 import 語(yǔ)句(大部分瀏覽器至今尚未實(shí)現(xiàn)import)。 這個(gè)時(shí)候,我們寫的 import 后面到底要不要后綴,全憑工具自己定義規(guī)則啊,只要工具在編譯打包時(shí)能找到被依賴模塊。比如webpack可以設(shè)定先找 .ts 如果沒有再找 .es 再找 .js, 如果是一個(gè)文件夾,就看文件夾里有沒有 index.js,甚至從node_modules目錄中去查找 ...
總結(jié):轉(zhuǎn)譯打包工具:不用寫
原生支持ES6的node:不用寫
原生支持ES6的瀏覽器:能通過URL在服務(wù)器上找到就行,如果真到了HTTP2盛行,ES6完全被瀏覽器實(shí)現(xiàn),文件不用打包的時(shí)候,打包工具會(huì)有辦法輕松處理的。
總總結(jié):別寫回答2:個(gè)人見解:
比如說:react、react-dom、vue等都是貢獻(xiàn)者發(fā)布的 NPM package(也就是打包好的模塊),使用NPM安裝后都會(huì)存放到node_modules目錄下,這些都是上文所提到的module
而JS文件并不是一個(gè)module,(這里說的不完全)
在ES6中提供了模塊化,(使用import、export定義模塊)
在Node.js中,采用CommonJS規(guī)范定義模塊
推薦一篇文章
回答3:.js不能省略,主要是為了可讀,以及區(qū)分。假設(shè)你目錄下有個(gè)自己寫的模塊test,還有一個(gè)自己寫的js文件test.js。模塊是以文件夾形式存在的,然后你用import ’./test’,你無(wú)法確定你加載的是模塊還是test.js(雖然,在ES6中,一個(gè)JS文件也算是一個(gè)模塊)。
你看到的這種代碼import React from 'react',并不是省略了.js,而是直接省略了/index.js。這是一個(gè)由npm安裝的包,在node_modules文件夾下面,其實(shí)它導(dǎo)入的是node_modulesreactindex.js,是整個(gè)包的入口文件,然后由index.js再去加載react需要用到的其他子js文件
注意,在node.js里,暫時(shí)還不支持ES6的import語(yǔ)法,所以需要通過require()引入包,用module.exports和exports暴露包中的可引入部分。
詳細(xì)請(qǐng)看MDN文檔
相關(guān)文章:
1. vim - docker中新的ubuntu12.04鏡像,運(yùn)行vi提示,找不到命名.2. mysql - 在不允許改動(dòng)數(shù)據(jù)表的情況下,如何優(yōu)化以varchar格式存儲(chǔ)的時(shí)間的比較?3. docker網(wǎng)絡(luò)端口映射,沒有方便點(diǎn)的操作方法么?4. css - chrome下a標(biāo)簽嵌套img 顯示會(huì)多個(gè)小箭頭?5. docker-compose中volumes的問題6. javascript - 網(wǎng)頁(yè)打印頁(yè)另存為pdf的代碼一個(gè)問題7. java - 關(guān)于File的問題?8. 一個(gè)網(wǎng)頁(yè)怎么連接到數(shù)據(jù)庫(kù)抓取信息呢9. 建議首頁(yè)視頻往頂部放10. 怎么php怎么通過數(shù)組顯示sql查詢結(jié)果呢,查詢結(jié)果有多條,如圖。
