add:ES6模块化

This commit is contained in:
qianguyihao 2018-04-14 22:43:16 +08:00
parent 0e32bfc661
commit b87401d112
3 changed files with 159 additions and 96 deletions

View File

@ -218,7 +218,7 @@ app.js
其他的参数,一路回车即可。效果如下: 其他的参数,一路回车即可。效果如下:
20180410_1425.png ![](http://img.smyhvae.com/20180410_1425.png)
于是,根目录下会自动生成`package.json`这个文件。点进去看一下: 于是,根目录下会自动生成`package.json`这个文件。点进去看一下:
@ -248,12 +248,12 @@ app.js
安装成功后,根目录下会自动生成相应的文件: 安装成功后,根目录下会自动生成相应的文件:
20180410_1450.png ![](http://img.smyhvae.com/20180410_1450.png)
需要说明的是我的node版本是 v8.10.0v8以上对应的 npm 版本是 v5.6.0,版本比较高,因此,当我输入完`npm install uniq`之后,`package.json`中就会自动添加`uniq`包的依赖: 需要说明的是我的node版本是 v8.10.0v8以上对应的 npm 版本是 v5.6.0,版本比较高,因此,当我输入完`npm install uniq`之后,`package.json`中就会自动添加`uniq`包的依赖:
20180410_18-55.png ![](http://img.smyhvae.com/20180410_1855.png)
如果有些童鞋的npm版本较低就需要手动去添加依赖另一种方式是可以使用`npm install uniq --save`命令,这个多出来的`--save`就可以自动添加依赖。 如果有些童鞋的npm版本较低就需要手动去添加依赖另一种方式是可以使用`npm install uniq --save`命令,这个多出来的`--save`就可以自动添加依赖。
@ -272,7 +272,7 @@ app.js
可以看出,这个包可以起到数组去重的作用。 可以看出,这个包可以起到数组去重的作用。
### 3、自定义模块 & 代码运行 ### 3、自定义模块
1module1.js 1module1.js
@ -557,25 +557,19 @@ GitHub<https://github.com/seajs/seajs>
- 自然直观的代码组织方式。 - 自然直观的代码组织方式。
![](http://img.smyhvae.com/20180303_2107.png)
20180303_2107.png
### RequireJSAMD、SeaJSCDM、CommonJS、ES6 的对比 ### RequireJSAMD、SeaJSCDM、CommonJS、ES6 的对比
1、RequireJS 和 AMD 1、RequireJS 和 AMD
![](http://img.smyhvae.com/20180303_1653.png)
20180303_1653.png
异步模块定义,特点是依赖前置。 异步模块定义,特点是依赖前置。
2、SeaJS 和 CMD 2、SeaJS 和 CMD
同步模块定义。 同步模块定义。
```javascript ```javascript
@ -592,7 +586,7 @@ GitHub<https://github.com/seajs/seajs>
3、CommonJS 3、CommonJS
20180303_1701.png ![](http://img.smyhvae.com/20180303_1701.png)
以上三个都是 ES5里面的规范。 以上三个都是 ES5里面的规范。
@ -600,7 +594,7 @@ GitHub<https://github.com/seajs/seajs>
ES6的特性export/import ES6的特性export/import
20180303_1704.png ![](http://img.smyhvae.com/20180303_1704.png)

View File

@ -41,8 +41,6 @@ define(['module1', 'module2'], function (m1, m2) {
- 第二个参数是function里面带了形参 m1 和 m2分别代表了 module1 和 module2。这个形参的作用是前面依赖的模块一旦声明了就可以一一对应地注入到 function中去从而在 function 内部使用依赖的模块。这种方式称之为**显式声明依赖注入**。 - 第二个参数是function里面带了形参 m1 和 m2分别代表了 module1 和 module2。这个形参的作用是前面依赖的模块一旦声明了就可以一一对应地注入到 function中去从而在 function 内部使用依赖的模块。这种方式称之为**显式声明依赖注入**。
### 引入模块的方式 ### 引入模块的方式
在主模块中引入其他的模块: 在主模块中引入其他的模块:
@ -57,21 +55,16 @@ require(['module1', 'module2'], function (m1, m2) {
}) })
``` ```
### RequireJS是AMD的实现 ### RequireJS是AMD的实现
- <http://www.requirejs.org/> - <http://www.requirejs.org/>
- <http://www.ruanyifeng.com/blog/2012/11/require_js.html> - <http://www.ruanyifeng.com/blog/2012/11/require_js.html>
## RequireJS的使用举例自定义模块 ## RequireJS的使用举例自定义模块
### 1、创建项目结构 ### 1、创建项目结构
在工程文件中新建如下目录: 在工程文件中新建如下目录:
@ -87,10 +80,9 @@ js
index.html index.html
``` ```
所有的代码写完之后,项目结构如下: 所有的代码写完之后,项目结构如下:
20180411_1331.png ![](http://img.smyhvae.com/20180411_1331.png)
### 2、下载require.js并导入 ### 2、下载require.js并导入
@ -101,13 +93,12 @@ index.html
在官网下载`require.js`文件: 在官网下载`require.js`文件:
20180411_1127.png ![](http://img.smyhvae.com/20180411_1127.png)
然后将`require.js`文件拷贝到项目的`js/libs/`目录中。 然后将`require.js`文件拷贝到项目的`js/libs/`目录中。
这样的话,就导入成功了。 这样的话,就导入成功了。
### 3、自定义模块 ### 3、自定义模块
1dataService.js 1dataService.js
@ -128,7 +119,6 @@ define(function () {
这模块没有依赖。 这模块没有依赖。
2alerter.js 2alerter.js
```javascript ```javascript
@ -166,13 +156,14 @@ requirejs(['myAlerter'], function (alerter) {
})(); })();
``` ```
这个模块,依赖了`myAlerter`这个模块,模块名是我自己起的。并且,我们在文件的上方做了映射,将`myAlerter`这个名字和`alerter.js`文件关联了起来。 这个模块,依赖了`myAlerter`这个模块,模块名是我自己起的。并且,我们在文件的上方做了映射,将`myAlerter`这个名字和`alerter.js`文件关联了起来。
我们来讲一下最上方的几行代码(即`requirejs.config`里的内容)的意思: 我们来讲一下最上方的几行代码(即`requirejs.config`里的内容)的意思:
目前为止我们可以看到文件3依赖了文件2文件2依赖了文件1。`paths`里做的就是映射:将键`myDataService`和`dataService.js`进行关联,将键`myAlerter`和`alerter.js`文件进行关联。 - 我们可以看到文件3依赖了文件2文件2依赖了文件1
- `paths`里做的就是映射:将键`myDataService`和文件`dataService.js`进行关联,将键`myAlerter`和文件`alerter.js`进行关联。
另外,再讲一下注释里的`baseUrl`的用法:如果没有这个注释,那么`paths`里的路径,是从**当前这个文件**main.js的角度出发的如果加了一行`baseUrl`,表明它是 paths 里所有路径的最开头的部分,`baseUrl`的路径是从**项目的根目录**的角度出发的。 另外,再讲一下注释里的`baseUrl`的用法:如果没有这个注释,那么`paths`里的路径,是从**当前这个文件**main.js的角度出发的如果加了一行`baseUrl`,表明它是 paths 里所有路径的最开头的部分,`baseUrl`的路径是从**项目的根目录**的角度出发的。
@ -204,66 +195,10 @@ requirejs(['myAlerter'], function (alerter) {
运行 index.html打印结果如下 运行 index.html打印结果如下
20180411_1740.png ![](http://img.smyhvae.com/20180411_1740.png)
项目源码:[2018-04-11-RequireJSDemo](https://download.csdn.net/download/smyhvae/10341963) 项目源码:[2018-04-11-RequireJSDemo](https://download.csdn.net/download/smyhvae/10341963)
```javascript
```
```javascript
```
```javascript
```
```javascript
```

View File

@ -33,7 +33,7 @@
``` ```
## ES6模块化的使用举例) ## ES6模块化的使用举例(自定义模块
### 1、初始化项目 ### 1、初始化项目
@ -94,7 +94,7 @@ index.html
1module1.js 1module1.js
```java ```javascript
//暴露模块:采用分别暴露的方式 //暴露模块:采用分别暴露的方式
export function foo1() { export function foo1() {
@ -106,16 +106,122 @@ export function foo2() {
} }
export let arr = [1, 2, 3, 4, 5]; export let arr = [1, 2, 3, 4, 5];
``` ```
4main.js 2module2.js
ES6的 import 语法中,在引入时,要求用**对象解构赋值**的形式。而不是用 `import myModule from ...`这种形式。【重要】 ```javascript
//暴露模块:采用统一暴露的方式
function fn1() {
console.log('我是 module2 中的 fn1');
}
function fn2() {
console.log('我是 module2 中的 fn2');
}
//统一暴露
export { fn1, fn2 };
```
3module3.js
```javascript
//暴露模块:采用默认暴露的方式。
//默认暴露的方式可以暴露任意数据类型,暴露的是什么数据,接收到的就是什么数据
//语法格式export default value;
export default () => {
console.log('我是 module3 中 default 方式暴露的函数');
};
```
这里,我们采取了一种新的暴露方式(默认暴露),在暴露时,加上了`default`这个关键字。代码里暴露了一个箭头函数稍后我们注意在main.js里是怎么引入module3.js的。
注意,我们只能写一次 default也就是说只能进行一次默认暴露。
4module4.jsdefault方式暴露多个属性
```javascript
//暴露模块:采用默认暴露的方式。
//默认暴露的方式可以暴露任意数据类型,暴露的是什么数据,接收到的就是什么数据
//语法格式export default value;
export default {
name: '我是 module4 中 default 方式暴露的属性 name',
foo() {
console.log('我是 module4 中 default 方式暴露的函数 foo');
}
}
```
这里,我们依旧采取了默认暴露的方式,只能写一次 default。代码里暴露了一个对象对象里存放了一个属性、一个方法。稍后我们注意在main.js里是怎么引入module4.js的。
如果我想暴露多个属性、多个对象怎呢很简单把你想要暴露的所有内容都放在default里包成一个对象。你看module4.js就是如此 同时暴露了多个属性&方法。
5main.js
这个是主模块。现在,我们来看一下,它如何引入上面的四个模块。
```javascript
//主模块。引入其他的模块
import { foo1, foo2 } from './module1'; //采用解构赋值的形式进行导入。注意,括号里的对象名,要和 module1 中的对象名一致。
import { fn1, fn2 } from './module2'; //采用解构赋值的形式进行导入。注意,括号里的对象名,要和 module1 中的对象名一致。
import myModule3 from './module3'; //module3 模块是采用 default 方式进行暴露的myModule4 这个名字是我随便起的
import myModule4 from './module4'; //module4 模块是采用 default 方式进行暴露的myModule4 这个名字是我随便起的
//调用module1、module2中的内容
foo1();
foo2();
fn1();
fn2();
//调用module3中的内容
myModule3();
//调用module4中的内容
console.log(myModule4.name); //module4中的属性
myModule4.foo(); //module4中的方法
```
我们可以看出:(具体请看注释,非常重要)
- module1和module2是采用**常规暴露**的形式,在引入它们时,模块名要一致。而且,要求用**对象解构赋值**的形式,而不是用 `import myModule from ...`这种形式(否则会报错 undefined
- module2和module3是采用**默认暴露**的形式,在引入它们时,模块名随便起。
6index.html
在这里引入main.js即可。
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="dist/main.js"></script>
</body>
</html>
```
### 4、编译转换 ### 4、编译转换
@ -127,16 +233,16 @@ ES6的 import 语法中,在引入时,要求用**对象解构赋值**的形
1利用 babel 将 ES6 转换为 ES5 1利用 babel 将 ES6 转换为 ES5
``` ```
babel src -d build //build目录会自动生成 babel src -d build //build目录会自动生成
``` ```
上方命令的意思是,将`src`目录下的所有ES6文件转化为ES5文件并放在`build`目录下(`build`目录会被自动创建)。 上方命令的意思是,将`src`目录下的所有ES6文件转化为ES5文件并放在`build`目录下(`build`目录会被自动创建)。
转化成ES5之后我们发现如果直接在 index.html 中加载`build`目录下的ES5文件也是会报错的因为浏览器不认识`main.js`里的`require`关键字: 转化成ES5之后我们发现如果直接在 index.html 中加载`build`目录下的ES5文件也是会报错的因为浏览器不认识`main.js`里的`require`关键字:
20180414_1410.png
于是,我们还要进行一次转换。 于是,我们还要进行一次转换。
@ -151,6 +257,34 @@ dist/main.js就是我们需要引入到 index.html 里的文件。
以后我们每次修改完ES6的代码就要执行上面的两个命令重新生成新的js文件。 以后我们每次修改完ES6的代码就要执行上面的两个命令重新生成新的js文件。
运行效果:
20180414_1615.png
工程文件:
- [2018-04-13-ES6Demo.rar](https://download.csdn.net/download/smyhvae/10348940)
## ES6模块化的使用举例第三方模块
下载 jQuery 包:
```
npm install jquery@1 //下载jQuery 1.X 的版本里最新的
```
在main.js 中引入上面的 jQuery
```
import $ from 'jQuery';
```
然后我们就可以通过`$`这个符号去写jQuery的代码了。