9、模块化

一、作用域

//作用域分类:
//1、全局作用域:同名变量使用var声明时,后者会覆盖前者
//2、局部作用域:产生于函数内部
//3、eval作用域
//4、块级作用域:带有{}的语法之中,如:if..else forEach

//模块作用域:产生在每一个js文件之中,相当于每一个文件之中,不管是变量还是函数。。。
//只要是在文件中,则作用域只能在这个文件中使用,其他文件想要使用,则必须让这个文件的值做“暴露”

二、什么是模块化

是将一个完整的js文件按照不同的功能拆分成每一个小的js文件,然后再将这些小的js文件合并在一起,完成最终的功能,那么这种拆分的过程被称作模块化
模块化规范主要包含:CommonJS、ES6

1、在node中每一个js文件就被称作一个模块;
2、模块内部代码对于外部来说都是默认不可见的,如果想要在外部使用,需要向外部暴露
3、模块化规范主要包含:CommonJS、ES6

模块化的作用:
1、防止命名冲突
2、将整体代码进行拆分;
3、提高了代码的灵活度以及复用性;
4、增强了代码的维护性;

三、CommonJS模块化规范

主模块文件需要使用哪一个子模块文件,需要用require引用
每一个模块都是一个独立的模块,如果文件没有暴露出来,则是一个空对象。
CommonJS使用exports和require来导出、导入模块;
ES6使用export和import来导出、导入模块;
模块需要提前编译打包处理,因为浏览器默认不识别CommonJS模块化语法的代码(require),想要服务端支持CommonJS,则需要借助于browserify工具包,browserify也称为CommonJS的浏览器端的打包工具。

四、CommonJS——模块暴露

//暴露方式一:暴露任意数据(Number,String,Boolean,Object,Array,Function) 
//这种方式用得最多
module.exports = a;
//这个语句只可以出现一次,若要反复出现,则表明module反复调用exports这个属性多次,则会发生覆盖
//若要一次性暴露多个数据:
//数组————下标访问,相对麻烦 ×
//对象————键名键值相同时,可以简写 √
module.exports = {a,b,c};
//在主模块导入模块时,直接解构
const {a,b,c} = require('./m1')

function getRand(min,max) {
	return Math.floor(Math.random()*(max-min+1)+min);
}
module.exports = getRand

//暴露方式二:
//module.exports.键名 = 键值
let a = 100;
module.exports.a = a;

//暴露方式三:
//exports.键名 = 键值
exports.a = a
//不能写成 exports = 键值

五、CommonJS——模块导入

模块的分类:
1、内置模块 fs
2、第三方模块 express body-parser ejs
3、自定义模块(文件导入)

<1>require文件在引入时:

1、 如果没有添加文件后缀,会默认按照.js/.json后缀的方式引入文件;
2、如果require后面的文件不是.js / .json ,需要明确写出后缀,否则就会报错(JSON文件中不能加暴露模块语法)
3、 如果引入的文件类型是.txt这类记事本文件,则也可以在require引入时,程序将把这个文件里面的内容当作js程序来读,所以需要写暴露模块语法,即使这个文件是txt文件
4、 require中的./和…/路径,其实就是文件之间在目录层级中的路径关系,而非在终端之中!
【注】:require在文件引入时,不能用绝对路径__dirname

<2>require在引入文件夹时:

如果是文件夹则会默认加载该文件夹下的package.json文件main属性对应的文件;
(初始化之后就会产生package.json文件, main指主入口文件)
如果require中路径是一个文件夹名,则会在当前文件夹下查找package.json配置文件main主入口文件(一般是index.js文件)
如果恰好存在,则直接执行package.json中的文件名,假设这个文件名是index.js,require(‘./demo/index.js’)
如果package.json中的main里面的属性的文件名不存在,而存在其他名称的js文件,则在执行的时候,会自动在require中补全。

<3>require在引入模块时:

内置模块——const fs = require(‘fs)’
第三方模块——const express = require(‘express’)
【注】:require引入的模块包首先在当前所在的文件夹src中先查找node_modules目录里是否存在… ,如果不存在则自动向上一个文件夹目录的node_modules里查找是否存在,如果还不存在则一直向上查找,如果没找到则报错(类似于JS中的作用域链的查找关系一样)

六、CommonJS——browserify

browerify是一个npm的包(全局安装)
作用是将CommonJS的模块化代码,打包成浏览器端可以识别的JS文件
(如:require是node端的CommonJS语法,没有办法在浏览器端识别)
npm i browserify -g
browserify 入口文件 -o ./dist/bundle.js(在终端输命令)
然后在客户端引文件:
【注】:入口文件使用’ ./ '(将src目录下的app.js文件 输出到 dist目录下的bundle.js)
【注】:dist文件夹和bundle.js文件都不需要自己新建
【注】:-o , output 输出

browserify工作原理

七、ES6模块化规范——模块暴露

ES6模块化的代码,在node端无法直接运行,在浏览器端也无法直接运行。
先使用 babel 将es6模块化语法转换为CommonJS,这样可以在node端运行,
再使用 browserify将CommonJS转换为客户端浏览器能识别的语法

//暴露方式一:分别暴露 
//export + 变量声明
//分别暴露适合于通用形式的导入以及解构方式的导入
export let 变量1 =1

//暴露方式二:统一暴露 
//export {变量1,变量2...}
let 变量1 = ...
let 变量2 = ...
export{变量1,变量2,变量3...};

//暴露方式三:默认暴露(适合于通用形式和默认形式的导入)
//export default 值
//后面的值的类型不限,需要什么类型就导出什么类型
//默认暴露和默认导入是一对一的
export default 100;
export default {d,e}

八、ES6模块化规范——模块导入

//导入方式1:通用形式的导入(适合于分别暴露和统一暴露)
//import * as 别名 from '子模块文件路径'
import * as m1 from './m1';
console.log(m1.a)

//导入方式2:解构赋值形式导入(用得最多)
//import {} from '子模块文件路径',{}里面写的是子模块中export后面的变量名
import {b,c} from './m1'
//是子模块文件中的export后面的变量名

//导入方式3:默认形式的导入
import m1 from './m1'

九、babel转化ES6代码并打包

//Step1:创建根目录:demo
//Step2:创建文件夹src : app.js(主模块文件) m1.js(m1模块文件)
//Step3:创建文件夹public:index.html(客户端文件)
//Step4:安装全局包 
npm i babel-cli -g

//Step5:安装局部包(在项目的文件夹下安装)
npm i babel-preset-es2015

//Step6:创建文件.babelrc(配置文件都要在项目的文件夹下安装) 
{
	"presets":[
		"es2015"  //将es6的代码转化成es5
	]
}
//run control是指babel执行命令时以什么样的规则(将ES6转换为ES5)

//Step7:在终端的项目文件夹下,运行命令:
babel ./src -d ./build (转换为CommonJS代码,可以在node端运行)
//项目目录中自动创建build文件夹
//babel后边要加一个文件夹
//-d 表示是destination
//运行命令的结果:
//src/app.js -> build/app.js
//src/m1.js -> build/m1.js

//Step8:在终端的项目文件夹下,运行命令:
browserify ./build/app.js -o ./dist/bundle.js(可以在客户端浏览器运行)
//项目目录中自动创建dist文件夹

//Step9:客户端测试
<script src="../dist/bundle.js"></script>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值