[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-学习资源