Es6模块化
总结
一、常用的模块化代码:CommonJS、ES6
二、CommonJS语法
2.1 暴露
- 暴漏任意数据
module.exports = 值;
- 暴露多个数据
module.exports.键名 = 值;
- 使用exports的方式暴露
exports.键名 = 值
2.1 导入
let test = require("文件路径")
- 文件:
require('./文件名')
require('../文件名')
省略文件后缀基本上是.js/.json为后缀的文件,除了这两个必须将后缀写清楚
文件中路径的./和…/是文件和文件之间在目录的层级上的路径,而非终端中的路径
- 文件夹:
require('./文件夹名') require('../文件夹名')
需要在这个文件夹里面查找package.json里面main属性的文件名,默认是index.js
如果在这个目录中这个文件则执行运行;
如果没有,有其他名称的文件,路径将自动补全:
require(‘./文件夹名/文件名’) require(‘…/文件夹名/文件名’)
- 模块名:
内置模块、第三方模块
如果是第三方模块名在当前文件夹下的node_modules目录里面没有找到,则自动上上一个文件目录的node_modules查找
注意事项:
- 如果没有添加文件后缀,会默认按照.js/.json后缀的方式引入文件,同时有js和json同名的文件,没有添加文件后缀 js文件权重高
- 其他文件后缀名,会按照.js方式载入
- 如果是文件夹则会默认加载该文件夹下的package.json文件中main属性对应的文件
- 如果是内置模块或者是npm安装的模块,直接使用包名字即可
- npm引入包时,如果当前文件夹下的node_modules没有,则会自动向上查找
三、ES6模块化语法
-
3.1 暴露
- 分别暴露:export 变量声明
export let 变量 = 值;
- 统一暴露:
export {变量1,变量2...}
- 默认暴露:
export default 值;
值的数据类型是所有的常用数据类型(number、string、boolean、array、object、funciton)
- 分别暴露:export 变量声明
-
3.2 导入
- 适合于(分别暴露和统一暴露)的导入形式有两种:
- 通用形式的导入:
import * as 别名 from '子模块文件路径'
这里的*表示所有,as表示别名 from来自于哪一个目标文件 - 解构形式的导入:
import {} from '子模块文件路径'
{}里面写什么是子模块中export后面的变量名
- 适合于默认暴露的导入形式有两种:
- 通用形式的导入:
import * as 别名 from '子模块文件路径'
- 默认形式的导入:
import 变量名 from '子模块文件路径'
注意:常见的错误写法 export default let a = 10;
三、browserify的使用
- 全局安装
npm i -g browserify
- 执行命令
browserify 入口文件 -o ./dist/bundle.js
列:browserify ./build/app.js -o ./dist/bundle.js
打包出能让浏览器识别的js - 然后运行
<script src="./dist/bundle.js"></script>
四、babel转化ES6代码并打包
注意:除了将ES6的语法转换之外,还会将ES6的模块化语法,转化为CommonJS模块化语法
- 全局安装
npm i babel-cli -g browserify
-
局部安装
注意:在项目的文件夹下安装
npm i babel-preset-es2015
-
创建.babelrc文件
这个文件是babel运行的配置文件
{
"presets":[
"es2015" //将es6的代码转化成es5
]
}
- 使用 Babel 将 ES6 编译为 ES5 代码
babel ./src -d ./build
js/src打包入口文件路径
js/build 打包出口文件路径
- 使用Browserify编译js上一步生成的js
browserify ./build/main.js -o ./dist/build.js
./build/main.js 入口文件路径
./dist/build.js 出口文件路径
- test.html页面引入测试
<script type="text/javascript" src="js/build/build.js"></script>
模块化规范
一、什么是模块化
是将一个完整的js文件按照不同的功能拆分成每一个小的js文件,然后再将这些小的js文件合并在一起,完成
最终的功能,那么这种拆分的过程被称作模块化
在node中每一个js文件就被称作一个模块;
模块内部代码对于外部来说都是默认不可见
的,如果想要在外部使用,需要向外部暴露
模块化规范主要包含:CommonJS
、ES6
二、模块化的作用
- 防止命名冲突
- 将整体代码进行拆分
- 提高了代码的灵活度以及复用性
- 增强了代码的维护性
三、CommonJS模块化规范
首先,规范是纸面上的东西,而NodeJS模块化就是遵循了CommonJS模块化规范
。
-
规范
- 说明:http://shouce.jb51.net/webpack/commonjs.html
- 每一个文件都可以被当做一个模块
- 在服务器端:
模块的加载时运行是同步加载的,相当于是需要等待前一个require中的内容加载完毕之后,在执行下一个require
- 在浏览器端:
模块需要提前编译打包处理,因为浏览器默认不识别CommonJS模块化语法代码,只有服务端执行CommonJS,想要浏览器端支持CommonJS,那么需要借助于工具browserify
- 说明:http://shouce.jb51.net/webpack/commonjs.html
-
基本语法
-
暴露模块
- 方式1
-
module.exports = value;
- 方式2
exports.xxx = value;
-
引入模块
语法:require(xxx)
第三方模块:xxx为模块名,例如:express、body-parser、express-session、cookie-parser
自定义模块:xx为模块文件路径
-
实现
- 服务器端实现:
- NodeJS:http://nodejs.cn/
- 浏览器端实现:
- Browserify:https://browserify.org/ 也称为CommonJS的浏览器端的打包工具
- 区别Node和Browserify
- Node.js运行时动态加载模块(同步)
- Browserify是在编译时就会加载打包(合并)require的模块
- 服务器端实现:
四、CommonJS具体使用
① 建立utils.js文件
function test(){
...
}
② 向外暴露
- 暴露任意数据
module.exports = test; //注意任意类型都可以向外暴露,不一定非要是函数
- 暴露多个数据
module.exports.键名1 = 值1;
module.exports.键名2 = 值2;
module.exports.键名3 = 值3;
- 使用exports的方式暴露
exports.键名 = 值;
不要使用exports = 值的形式来暴露数据,因为会被解析成exports = module.exports = {}
因为,一旦使用了exports = 这种形式,则原本属于它暴露的功能就不存在了
解释:module.exports本身就是一个对象
③ 建议app.js文件
直接在该文件中使用test()方法是会报错的,需要先导入对应的模块文件
const u = require("./utils.js");
u(); //u相当于是utils.js下的test函数,所以可以直接拿来调用
- require方法的参数是需要传入一个目标模块文件的路径(相对路径,绝对路径也可以)
- require方法的返回值是目标模块中『module.exports』向外暴露的值
五、模块导入
使用require()语法即可导入对应的文件路径
let test = require("文件路径")
注意事项:
- 如果没有添加文件后缀,会默认按照.js/.json后缀的方式引入文件,同时有js和json同名的文件,没有添加文件后缀 js文件权重高
- 其他文件后缀名,会按照.js方式载入
- 如果是文件夹则会默认加载该文件夹下的package.json文件中main属性对应的文件
- 如果是内置模块或者是npm安装的模块,直接使用包名字即可
- npm引入包时,如果当前文件夹下的node_modules没有,则会自动向上查找
六、browserify
-
概述
browerify是一个npm的包,作用是将
CommonJS
的模块化代码,打包成浏览器端可以识别的JS文件自动的根据文件之间的相互依赖关系进行查找打包,最终输出一个单独的js文件
-
全局安装
npm i -g browserify
- browserify使用
browserify 入口文件 -o ./dist/bundle.js
列:browserify ./build/app.js -o ./dist/bundle.js
解释:
-o参数(output) 有输出之意
./dist/bundle.js:为输出的路径(任意定义)
-
打包后再次使用浏览器运行
<script src="./dist/bundle.js"></script>
案例1:
创建app.js、m1.js、m2.js等文件
app.js
let m1 = require('m1');
let m2 = require('m2');
console.log(m1,m2)
m1.js
module.exports = {
name:'尚硅谷'
}
m2.js
var a = 10;
var b = 20;
exports.a = a;
exports.b = b;
src目录为源文件目录(程序员编写的源代码)
dist发布文件的文件夹,里面放置的是打包后的文件
七、ES6的模块化规范
-
作用:可以将依赖模块进行编译打包处理
-
语法:
-
暴露模块(exports):
- 分别暴露:exports 暴露内容 (适合统一方式导入和解构方式导入)
export const a = 100; export var b = 200; export let c = 300; export function d(){ console.log('ddd';) }
- 统一暴露:export {xx,xx} (适合统一方式导入和解构方式导入)
let a = 300; const b = 200; export { a,b }
注意:这里非对象属性的简写方式,而是一种语法要求
-
默认暴露:export default 暴露内容
(适合统一方式导入和简便方式导入,更适合简便方式)
export default { name:'尚硅谷', pos:['北京','上海','深圳','西安','武汉'] }
-
引入模块(import)
- 通用形式导入
import * as m1 from './m1'
这里的*表示所有,as表示别名 from来自于哪一个目标文件
- 解构赋值形式导入【使用的比较多,应对每一种暴露方式】
import {a,b,c} from './m1'; import {default as m3} from './m3';
- 简便方式导入 【只能针对默认暴露】
import m1 from './m1'
-
八、babel转化ES6代码并打包
在默认情况下NodeJS默认不支持
ES6模块化语法,浏览器端默认也不支持
ES6模块化语法
则咱们可以使用babel,它是一个工具,利用babel这个工具就可以将ES新特性的代码(ES6/7/8/9/10/11…)
等转化成ES5代码
注意:除了将ES6的语法转换之外,还会将ES6的模块化语法,转化为CommonJS模块化语法
- 全局安装
npm i babel-cli -g browserify
-
局部安装
注意:在项目的文件夹下安装
npm i babel-preset-es2015
-
创建.babelrc文件
这个文件是babel运行的配置文件
{
"presets":[
"es2015" //将es6的代码转化成es5
]
}
- 使用 Babel 将 ES6 编译为 ES5 代码
babel js/src -d js/build
- 使用Browserify编译js上一步生成的js
browserify js/build/main.js -o js/build/build.js
- test.html页面引入测试
<script type="text/javascript" src="js/build/build.js"></script>