[TOC]
## 模塊化
### import
[[MDN文檔,import](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import)]
#### 靜態`import`
**`import`** 語句用于導入由另一個模塊導出的綁定。無論是否聲明了?[`strict mode`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode "如果你想改變你的代碼,讓其工作在具有限制性JavaScript環境中,請參閱轉換成嚴格模式。"),導入的模塊都運行在嚴格模式下。
在瀏覽器中,`import`語句只能在聲明了`type="module"`的`script`的標簽中使用。
靜態的`import`是初始化加載的最優選擇,使用靜態`import`更容易從代碼靜態分析工具和[tree shaking](https://developer.mozilla.org/zh-CN/docs/Glossary/Tree_shaking)中受益。
語法
~~~js
// 直接導入默認值,在`default export`有效時可用。
import defaultExport from "module-name";
//導入默認值??,在`default export`有效時可用。
import defaultExport, { export [ , [...] ] } from "module-name";
// 導入整個模塊的內容(導入所有導出)
import * as name from "module-name";
// 導入單個導出
import { export } from "module-name";
// 導入時重命名(帶有別名)的導出
import { export as alias } from "module-name";
// 導入多個導出,導出文件與導入文件在同一個目錄里
import { export1 , export2 } from "module-name";
// 導入多個導出,導出文件與導入文件不在同一個目錄
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
// 導入時重命名多個導出
import { export1 , export2 as alias2 , [...] } from "module-name";
// myModule used as a namespace,在這種情況下,`default`導入必須首先聲明
import defaultExport, * as myModule from "module-name";
// 僅為副作用而導入一個模塊,這將運行模塊中的全局代碼, 但實際上不導入任何值。
import "module-name";
~~~
* **`defaultExport`**
將引用模塊默認導出的名稱。
* **`module-name`**
要導入的模塊。這通常是包含模塊的`.js`文件的相對或絕對路徑名,不包括`.js`擴展名。某些打包工具可以允許或要求使用該擴展;檢查你的運行環境。只允許單引號和雙引號的字符串。
* **`name`**
引用時將用作一種命名空間的模塊對象的名稱。
* **`export, exportN`**
要導入的導出名稱。
* **`alias, aliasN`**
將引用指定的導入的名稱。
#### 動態`import()`
希望按照一定的條件或者按需加載模塊的時候,動態`import()`是非常有用的。它不需要依賴`type="module"`的script標簽。
語法
~~~js
var promise = import("module-name");
~~~
可以將關鍵字`import`稱作動態導入模塊的函數,當使用它的時候,會返回一個`promise`。
`import()`加載模塊成功以后,這個模塊會作為一個對象,當作`then`方法的參數。因此,可以使用對象解構賦值的語法,獲取輸出接口。
~~~js
import('/modules/my-module.js')
.then((module) => {
// Do something with the module.
});
~~~
~~~js
//獲取導入的myModule.js(命名輸出接口)輸出接口,方法1
import('./myModule.js')
.then(({export1,export2})=>{
// ...
});
//獲取導入的myModule.js(default輸出接口)輸出接口,方法2,
import('./myModule.js')
.then(myModule=>{
console.log(myModule.default);
});
//獲取導入的myModule.js(default輸出接口)輸出接口,方法3,將default具名輸入
import('./myModule.js')
.then(({default:theDefault})=>{
console.log(theDefault);
});
//同時加載多個模塊
Promise.all([
import('./module1.js'),
import('./module2.js'),
import('./module3.js'),
])
.then(([module1,module2,module3])=>{
···
});
~~~
這種使用方式也支持`await`關鍵字。
~~~js
let module = await import('/modules/my-module.js');
~~~
`import()`也可以用在 async 函數之中。
~~~js
async function main(){
const myModule=await import('./myModule.js');
const {export1,export2}=await import('./myModule.js');
const [module1,module2,module3]=
await Promise.all([
import('./module1.js'),
import('./module2.js'),
import('./module3.js'),
]);
}
main();
~~~
#### 示例
* 標準導入
~~~js
//file.js
function getJSON(url, callback) {
let xhr = new XMLHttpRequest();
xhr.onload = function () {
callback(this.responseText)
};
xhr.open('GET', url, true);
xhr.send();
}
export function getUsefulContents(url, callback) {
getJSON(url, data => callback(JSON.parse(data)));
}
~~~
從輔助模塊file.js導入以協助處理AJAX JSON請求。
~~~js
//main.js
import { getUsefulContents } from '/modules/file.js';
getUsefulContents('http://www.example.com',
data => { doSomethingUseful(data); });
~~~
* 動態導入
~~~js
const main = document.querySelector("main");
for (const link of document.querySelectorAll("nav > a")) {
link.addEventListener("click", e => {
e.preventDefault();
import('/modules/my-module.js')
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
});
}
~~~
上例中,通過點擊按鈕,觸發動態`import()`去加載函數,然后執行。當然這不是唯一的方式,`import()`函數也可以支持`await`。
### export
[[MDN文檔,export](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/export)]
`export`語句用于在創建JavaScript模塊時,從模塊中導出函數、對象或原始值,以便其他程序可以通過`import`語句用于導入由另一個模塊導出的綁定。無論是否聲明了?strict mode ,導入的模塊都運行在嚴格模式下。
>[warning] 此特性目前僅在 Safari 和 Chrome 原生實現。它在許多轉換器中實現,如[Traceur Compiler](https://github.com/google/traceur-compiler),[Babel](http://babeljs.io/)或[Rollup](https://github.com/rollup/rollup)。
~~~js
// 命名導出
export { name1, name2, …, nameN };
export { variable1 as name1, variable2 as name2, …, nameN };
export let name1, name2, …, nameN; // also var
export let name1 = …, name2 = …, …, nameN; // also var, const
// 默認導出(函數)
export function FunctionName() {...}
// 默認導出(類)
export class ClassName {...}
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };
export * from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
~~~
* **`nameN`**
導出的標識符(用來被其他腳本的`import`導入)
#### 使用命名導出
在模塊中,我們可以使用以下代碼:
~~~js
// module "my-module.js"
function cube(x) {
return x * x * x;
}
const foo = Math.PI + Math.SQRT2;
export { cube,foo };
~~~
這樣的話,在其它腳本我們可以這樣使用:
~~~js
import { cube, foo } from 'my-module.js';
console.log(cube(3)); // 27
console.log(foo); // 4.555806215962888
~~~
#### 使用默認導出
1.
如果我們要導出一個值或模塊中的返回值,就可以使用默認導出:
~~~js
// module "my-module.js"
export default function cube(x) {
return x * x * x;
}
~~~
然后,在另一個腳本中,可以直接導入默認導出:
~~~js
// module "my-module.js"
import cube from 'my-module';
console.log(cube(3)); // 27?????
~~~
>[warning] 注意,不能使用`var`,`let`或`const`用于導出默認值`export default`。
2. 直接導出
~~~js
// conf.js
export default {
a:'11';
b:{m:'22',n:[]};
c:function(){}
};
~~~
~~~js
//main.js,conf.js與main.js在同一目錄內
import conf from './conf.js'
console.log(conf.a);
~~~
#### 模塊重定向
如果我們要從另一個模塊(有效地創建“重定向”)中導出默認值(default)和 星標(\*):
~~~js
// module "redirect-module.js"
export {default} from './other-module';
export * from './other-module';
~~~
## 深入理解module
1. [ES6 in Depth: Modules](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/), Hacks blog post by Jason Orendorff
2. [Axel Rauschmayer's book: "Exploring JS: Modules"](http://exploringjs.com/es6/ch_modules.html)
3. [export、exports、modules.exports 和 require 、import 的一些組合套路和坑](https://www.cnblogs.com/CyLee/p/5836069.html)
4. [Node中沒搞明白require和import,你會被坑的很慘](https://imweb.io/topic/582293894067ce9726778be9?utm_source=tuicool&utm_medium=referral)
5. [javascript 中的require /exports 和import/export](https://blog.csdn.net/qq_37755555/article/details/78688525)
6. [Es6中的模塊化Module,導入(import)導出(export)](https://mp.weixin.qq.com/s/NDA46vKoFuZt09Qx8SNf6Q)
- WebAPP
- Linux Command
- 入門
- 處理文件
- 查找文件單詞
- 環境
- 聯網
- Linux
- Linux目錄配置標準:FHS
- Linux文件與目錄管理
- Linux賬號管理與ACL權限設置
- Linux系統資源查看
- 軟件包管理
- Bash
- Daemon/Systemd
- ftp
- Apache
- MySQL
- Command
- Replication
- mysqld
- remote access
- remark
- 限制
- PHP
- String
- Array
- Function
- Class
- File
- JAVA
- Protocals
- http
- mqtt
- IDE
- phpDesigner
- eclipse
- vscode
- Notepad++
- WebAPI
- Javasript
- DOM
- BOM
- Event
- Class
- Module
- Ajax
- Fetch
- Promise
- async/await
- Statements and declarations
- Function
- Framwork
- jQurey
- Types
- Promise
- BootStrap
- v4
- ThinkPHP5
- install
- 定時任務
- CodeIgniter
- React.js
- node.js
- npm
- npm-commands
- npm-folder
- package.json
- Docker and private modules
- module
- webpack.js
- install
- configuration
- package.json
- entry
- modules
- plugins
- Code Splitting
- loaders
- libs
- API
- webpack-cli
- Vue.js
- install
- Compile
- VueAPI
- vuex
- vue-router
- vue-devtools
- vue-cli
- vue-loader
- VDOM
- vue-instance
- components
- template
- Single-File Components
- props
- data
- methods
- computed
- watch
- Event-handling
- Render Func
- remark
- 案例學習
- bootstrap-vue
- modal
- fontAwesome
- Hosting Font Awesome Yourself
- using with jquery
- using with Vue.js
- HTML
- CSS
- plugins
- Chart.js
- D3.js
- phpSpreadSheet
- Guzzle
- Cmder
- Git
- git命令
- git流程
- Postman
- Markdown
- Regular Expressions
- PowerDesigner
- 附錄1-學習資源