模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。 

模块化的好处

1)防止命名冲突

2)代码复用

3)高维护性

模块化规范产品

ES6之前的模块化规范有:

1)CommonJS => NodeJS、Browserify

2)AMD          => requireJS

3)CMD          => seaJS


ES6模块化数据暴露语法

模块化暴露数据的语法有三种:

1 分别暴露:

使用 export 单行暴露模块接口;

模块功能主要由两个命令构成:export 和 import

export 命令用于规定模块的对外接口;

import 命令用于输入其他模块提供的功能 ;

新建一个模块文件: m1.js

export let company = 'yinsui';           // export 单行暴露接口
export function say(){
console.log('hello javascript');
}

通过 export 把模块文件中的属性和方法暴露给引用文件;

再写一个引用模块的文件: index.html

<script type = "module">
import * as m1 from './module/m1.js';
console.log(m1);
m2.say();
</script>

在 script 里,使用 type = "module" 来引入模块;

注意格式:最好把模块文件放在文件夹中,并用 ./ 、/ 、../ 等方式引用;

import * as m1 from './moudle/m1.js'

测试接口:需要先安装个 web 环境再测试

可以使用 VSCode 的插件 Go Live ;也可以本地web服务器;我使用的是  phpstudy;

Javascript(笔记43) - ES6特性 - 模块化_模块化

2 统一暴露

统一暴露接口;使用 export 统一暴露接口;

新建 m2.js:

let company = 'yinsui';

function say(){
console.log('hello javascript');
}

export{company,say}; // export 统一暴露接口

在Hmtl中引入模块

<script type = "module">
import * as m2 from './module/m2.js';
console.log(m2);
m2.say();
</script>

Javascript(笔记43) - ES6特性 - 模块化_模块化


3 默认暴露:

使用 export default{} 方式暴露;

export default{
company:'yinsui',
say:function(){
console.log('hello javascript');
}
}

在 HTML 中引入模块:

<script type = "module">
import * as m3 from './module/m3.js';
console.log(m3);
m3.default.say();
</script>

Javascript(笔记43) - ES6特性 - 模块化_模块化

三种方式暴露语法的结果相同:


现在把三种暴露数据的写法放在一起:

// m1.js 第一种:分别暴露 
export let company = 'yinsui';
export function say(){
console.log('hello javascript');
}

// m2.js 第二种:统一暴露
let company = 'yinsui';
function say(){
console.log('hello javascript');
}
export{company,say};

// m3.js 第三种:默认暴露
export default {
company: 'yinsui',
say: function () {
console.log('hello javascript');
}
}

分别引入这三种暴露数据写法的模块:

注意:引入的写法 script 的类型  type = "module"

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模块</title>
</head>
<body>
<script type="module">
// 引入 m1.js 模块内容
import * as m1 from './module/m1.js';
// 引入 m2.js 模块
import * as m2 from './module/m2.js';
// 引入 m3.js 模块
import * as m3 from './module/m3.js';

console.log(m1);
m1.say();

console.log(m2);
m2.say();

console.log(m3);
m3.default.say();
</script>
</body>
</html>

ES6模块化引入(一)

ES6 暴露数据,上面讲了3种方法,引入模拟也有;


1 通用方式

<script type="module">
// 引入 m1.js 模块内容
import * as m1 from './module/m1.js';
// 引入 m2.js 模块
import * as m2 from './module/m2.js';
// 引入 m3.js 模块
import * as m3 from './module/m3.js';
</script>

2 解构赋值形式

<script type="module">
import { company, say } from './module/m1.js';
import { company as ys, say as ysSay } from './module/m2.js';
import { default as m3} from './module/m3.js';

console.log(company);
say();

console.log(ys);
ysSay();

console.log(m3);
m3.say();
</script>

为了预防重阳,分别用 as 做了重命名;

引入 m3.js 模块时,使用了默认对象的方式,引入时必须使用 as 重命名,返回的也是对象;

Javascript(笔记43) - ES6特性 - 模块化_javascript_04

3 简便形式

仅针对默认暴露 default;

<script type="module">
// 引入 m3.js 模块
import m3 from './module/m3.js';

console.log(m3);
</script>

ES6模块化引入(二)

大家发现,所有模块代码的引入都放在  script 里,需要引入的模块多了,代码也会很长;

<script type="module">
// 引入多个模块
</script>

所以,不如单独新建一个 app.js 模块用来专门引入 模块;

// app.js  引入模块专用

import * as m1 from './m1.js';
import * as m2 from './m2.js';
import * as m3 from './m3.js';

console.log(m1);
console.log(m2);
console.log(m3);

在HTML中只引入 app.js 这一个模块文件就可以了。 

注意:除了路径正确之外,还要加上 type = "module" ; 

<script src="./module/app.js" type="module"></script>

引入完成后,看控制台:

Javascript(笔记43) - ES6特性 - 模块化_模块化_05


项目当中,一般不会这样引入,主要还是因为兼容性的问题;

一般会使用 babel 等代码转换和打包的工具;


babel 代码转换打包

可能有人会问,chrome 浏览器已经很强大了,能识别ES6的语法,为什么还要用转换?

是的,ES6+是可以支持,但标准每年都在更新,各浏览器是否支持新的语法就说不定了。


安装工具

安装这几个:babel-cli , babel-preset-env , browserify(webpack)

babel-cli 是  babel 命令行的工具;

babel-preset-env 是预设包,能把最新的 ES6 + 的语法转换成 ES5;

browserify 是打包工具 ;没有使用 webpack 是因为配置比较麻烦,一般项目中还是会用 webpack; 

在终端命令行初始化:

>npm init --yes
>npm i babel-cli babel-preset-env browserify -D

Javascript(笔记43) - ES6特性 - 模块化_ES6_06

安装完一堆 packages .

 

切换安装镜像

有些朋友可能会遇到: “sill idealTree buildDeps”  就卡住了,大概是因为国外服务器下载不稳定,切换到国内淘宝的镜像上来,可以先看一下安装源在哪:

> npm config get registry
https://registry.npmjs.org/

我这里就显示的官网,改成淘宝镜像地址:

> npm config set registry https://registry.npm.taobao.org 
> npm config get registry
https://registry.npm.taobao.org

淘宝镜像(感谢):

原来:​​​​​https://registry.npm.taobao.org​

现在:​​​​https://registry.npmmirror.com/​​   


使用工具

安装成后,执行转换:参数可以做成配置文件,这里省略了,就直接传参;

> npx babel module -d dist --presets=babel-preset-env

意思是把 model 文件夹下的 js 转换,并生成新的文件夹 dist 下;

对比一下:

原来的 module/m1.js

export let company = 'yinsui';
export function say(){
console.log('hello javascript');
}

转换后的 dist/m1.js

'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.say = say;
var company = exports.company = 'yinsui';
function say() {
console.log('hello javascript');
}

原来的 module/app.js

import * as m1 from './m1.js';
import * as m2 from './m2.js';
import * as m3 from './m3.js';

转换后的 dist/app.js

'use strict';

var _m = require('./m1.js');

var m1 = _interopRequireWildcard(_m);

var _m2 = require('./m2.js');

var m2 = _interopRequireWildcard(_m2);

var _m3 = require('./m3.js');

var m3 = _interopRequireWildcard(_m3);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

暴露的语法发现了一些变化,转换成 common.js 规范下的语法了;

然而,这个语法浏览器还是不能识别,需要打包;


打包

打包的语法:

> npx browserify dist/app.js -o dist/bundle.js

此时,在 dist 目录下,就生成了一个新的文件  bundle.js 是打包好,可以直接调用的 js。

<script src="dist/bundle.js"></script>

也可以调用这个打包好的模块里的方法;

如果我们还要修改 js 代码的话,可在引入的 app.js 里修改,如:

import * as m1 from './m1.js';
import * as m2 from './m2.js';
import * as m3 from './m3.js';

m1.say();
m2.say();
m3.default.say();

我们加了三行自己的代码,要执行的话,还得再走一遍 babel 的转换和打包,来重新生成 bundle.js ;

> npx babel module -d dist --presets=babel-preset-env
> npx browserify dist/app.js -o dist/bundle.js

此时页面中引入的 bundle.js 就是重新转换和打包过的代码:

<script src="dist/bundle.js"></script>

执行结果:

Javascript(笔记43) - ES6特性 - 模块化_模块化_07

这样的话,不管浏览器是否支持ES6,都能正常执行了;


模块化引入JQuery包

引入其他包的方法也是类似;

先安装一下 JQuery 包;

> npm i jquery

在我们的  module/app.js 中引入 JQuery 并写代码,改变背景颜色 ;

import $ from 'jquery';  // const $ = require("jquery");  common.js 写法
$('body').css('background','pink'); // 修改背景色

重新转换和打包:

> npx babel module -d dist --presets=babel-preset-env
> npx browserify dist/app.js -o dist/bundle.js

此时,我们新建一个文件 :  index.html ,并引入 bundle.js ,在 web 服务器下浏览 index.html ,就可以看到背景颜色被改变了;

// index.html
<script src="dist/bundle.js"></script>