前言:一个大的项目必定会使用模块化技术,使用模块化就会使用相应的模块化规范,现在比较流行的模块化规范有以下2种: CommonJS、ES6e
官网: http://wiki.commonjs.org/wiki/Modules
每个文件都是一个模块。
CommonJS模块化的代码既可在服务端(node)运行,也可在浏览器(browser浏览器)端运行。(es6模块化只能写浏览器端)
服务器端:模块化的代码可直接运行。
浏览器端:模块化的代码要经过 Browserify (http://browserify.org)编译(类比:es6的箭头函数不能直接被浏览器所识别,需要借助babel编译)。
第一种方式: module.exports = value
第二种方式: exports.xxx = value
引入第三方模块:require(xxx),xx为模块名
引入自定义模块: require(xxx),xxx为模块文件路径


module1.js使用module.exports语法,暴露出一个对象。app.js中引入该暴露的对象,并使用
/*
module1使用module.exports = xxxx 去暴露,xxx就是暴露的内容
*/
//没有暴露data和msg(被保护了)
const data = 'atguigu'
const msg = 'hello'
module.exports = {
showData (){
console.log(data);
},
showMsg(){
console.log(msg);
}
}
// 暴露的本质是module.exports的内容
// 引入的内容是什么,取决于暴露的是什么
const m1 = require('./module1') //引入自定义模块
m1.showData()
m1.showMsg()
module2.js使用exports语法,往暴露的对象中添加属性。app.js中引入该暴露的对象,并使用
/*
module2使用exports.xxxxx = value 去暴露,value就是暴露的内容,xxxxx是他的名字
(注意:module.exports和exports不能混用,若混用了,以module.exports
其实,最终暴露的对象,只认module.exports,只不过刚开始exports的引用初始值就被赋值为module.exports了)
*/
exports.data = 'atguigu2'
exports.msg = 'hello2'
exports.sum = function (a,b){
console.log(a+b);
}
exports.sub = function (a,b){
console.log(a-b);
}
const m2 = require('./module2') //引入自定义模块
const m22 = require('./module2') //引入自定义模块
console.log(m2==m22) // true
console.log(m2.data);
console.log(m2.msg);
m2.sum(1,2)
m2.sub(3,4)
npm init --yes,在当前文件夹中,初始化包管理配置(会生成package.json文件,安装包时,会将包安装在当前文件的node_modules文件夹中)
(当使用require引入第三方模块时,会先从当前文件夹中寻找node_modules文件夹,并从中找到对应的模块,如果没找到,则会到当前文件夹的父文件夹中寻找node_modules文件夹,并从中找到对应的模块)
npm install uniq,安装uniq包
引入,并使用
// app.js
const uniq = require('uniq') // 引入第三方模块模块(只需要写模块名)
const arr = [1,3,3,4,2,5]
console.log(uniq(arr));
上述符合commonJs模块化规范的代码,使用node命令能够正常执行,但是浏览器并不能识别commonJs模块化的语言,需要使用browserify来编译之后,才能被浏览器使用,browserify官网:https://browserify.org/。
//
const data = 'atguigu'
const msg = 'hello'
module.exports = {
showData (){
console.log(data);
},
showMsg(){
console.log(msg);
}
}
//
const m1 = require('./module1') // 引入自定义模块
const uniq = require('uniq') // 引入第三方模块
m1.showData()
m1.showMsg()
const arr = [1,3,3,4,2,5]
console.log(uniq(arr));
//
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<!-- 直接引入app.js,将不可用,因为app.js使用了CommonJs模块化语法,浏览器并不能识别 -->
<script type="text/javascript" src="./app.js"></script>
</body>
</html>
首先需要安装browserify
# 全局安装
npm i browserify -g
编译指定文件
browserify ./app.js -o ./build.js
在index.html中引入build.js
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Documenttitle>
head>
<body>
<script type="text/javascript" src="./build.js">script>
body>
html>
(ES6就是ES2015,es6推出新语法、模块化规范、Promise,es7提出async/await)
每个文件都是一个模块。
要借助 Babel(能把ES6代码编译成ES5的代码,jsx语法转为js)和Browserify依次编译代码,才能在浏览器端运行。
Babel中文网: https://www.babeljs.cn/
分别暴露: export 暴露内容
统一暴露: export {暴露内容1,暴露内容2}
默认暴露: export defalut 暴露内容
方法1: import {xxx,yyy} from ‘./module1’
方法2: import module3 from ‘./module3’
若使用分别暴露、统一暴露的方式暴露内容,那么就要用方法1引入。
若使用默认暴露的方式暴露内容,那么就要用方法2引入。
//
/*
module1中使用【分别暴露】
*/
export const data = 'atguigu'
export const msg = 'hello,0826'
export function showData(){
console.log(data);
}
export function showMsg(){
console.log(msg);
}
/*错误写法
const mistake = 'mistake '
export mistake
*/
//
import {data,msg,showData,showMsg} from './module1'
console.log(data)
console.log(msg)
showData()
showMsg()
//
/* 直接引入app.js,因为app.js中使用了es6的模块化语法,而不能识别报错 */
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<script type="text/javascript" src="./app.js"></script>
</body>
</html>
准备相关依赖包(为编译代码做准备)
全局安装: babel-cli、Browserify,执行命令如下:
npm install babel-cli browserify -g
npm install babel-preset-es2015
定义 .babelrc 文件(前面有.)
{
"presets":["es2015"]
}
# 将当前文件夹中的src下的文件,通过babel 编译到 当前的build文件夹下
babel ./src -d ./build
browserify ./build/app.js -o ./build/index.js
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Documenttitle>
head>
<body>
<script type="text/javascript" src="../build/build.js">script>
body>
html>

1. 创建文件结构如下
-3_ES6_modular
-src
-app.js
-module1.js
-index.html
-.babelrc,内容如下:
{
"presets": ["es2015"]
}
2. 准备相关包
npm install babel-cli browserify -g
npm install babel-preset-es2015
3. babel编译为ES5,命令如下:babel ./src -d ./build
browserify继续编译,命令如下:browserify ./build/app.js -o ./build/build.js
备注:命令不要记!!我们学习的是模块化的暴露、引入语法,不是命令,以后也不敲命令。
4. index.html页面中引入build/build.js
//
/*
module1中使用【分别暴露】
*/
export const data = 'atguigu'
export const msg = 'hello,0826'
export function showData(){
console.log(data);
}
export function showMsg(){
console.log(msg);
}
//
/*
module2中使用【分别暴露】,但暴露了一个和module1重名的一个data
*/
export const data = '北七家镇宏福科技园'
/*
module3中使用【统一暴露】
*/
const school = '尚硅谷'
const person = {
name:'老刘',
age:19,
sex:'女'
}
function getLaoliu(){
console.log(person);
}
//统一暴露(精简版)---用的多
export {school,person,getLaoliu}
//统一暴露(完整版) (所以上面精简版这不是对象的简写形式)
// export {school as a,person as b,getLaoliu as c}
/*
module4中使用【默认暴露】-----只能暴露一次!!!!
(右侧得为一个表达式,所谓的表达式就是,能获得值,比如左边使用var xxx = 右边,能接收到值)
*/
export default {
name:"wc",
age:5,
}
//
// 同时使用多种暴露方式
//使用【分别暴露】
export const teacher1 = {name:'强哥',age:15}
export const teacher2 = {name:'歌神',age:17}
//使用【统一暴露】
const stu1 = {name:'王宇',age:18}
const stu2 = {name:'宇航',age:19}
export {stu1,stu2}
export {stu1 as stu11,stu2 as stu22}
//使用【默认暴露】
export default {
school:'尚硅谷',
address:'宏福科技园',
subjects:['前端','java','大数据']
}
//
//引入【分别暴露】的模块(这里的都不是解构赋值,根本不符合解构赋值的语法)
import {data,showData,showMsg} from './module1'
//引入【分别暴露】的模块+重命名
import {data as data2} from './module2'
//引入【分别暴露】的模块+打包引入
import * as module1 from './module1'
//引入【统一暴露】的模块(统一暴露和分别暴露,最后引入的方式都是一样的)
import {school,person,getLaoliu} from './module3'
//引入【默认暴露】的模块
import module4 from './module4'
//引入多种暴露方式的模块(module5是默认暴露,其它是分别暴露或统一暴露)
import module5,{teacher1,teacher2,stu1,stu2,stu11,stu22} from './module5'
console.log(module5);
console.log(teacher1);
console.log(teacher2);
console.log(stu1);
console.log(stu2);