模块化
CommmonJS导入导出数据
在common.js 当中每个js文件都存在一个空对象 {} 。 使用exports控制对象{},来对{}添加属性。
抽取:2->3 是es6新语法
在 CommonJS 标准中,导出数据有两种⽅式:
第⼀种⽅式: module.exports = value
第⼆种⽅式: exports.name = value
注意点如下:
-
每个模块内部的: this 、 exports 、 modules.exports 在初始时,都指向同⼀个空对象,该空对象就是当前模块导出的数据,如下图:
-
⽆论如何修改导出对象,最终导出的都是
module.exports
的值。 -
exports 是对 module.exports 的初始引⽤,仅为了⽅便给导出象添加属性,所以不能使⽤
exports = value
的形式导出数据,但是可以使⽤module.exports= xxxx
导出数据。
通过解构将school.name 直接在引入的时候赋值
解构赋值:从数组和对象中提取数据,并将它们赋值给变量,在处理函数返回值、从对象或数组中提取属性、处理嵌套数据结构、以及传递函数参数时非常有用。它使代码更简洁、更易读,并减少了访问嵌套数据时的冗余代码。
对象参数解构
function greet({ name, age }) {
console.log(`Hello, ${name}. You are ${age} years old.`);
}
const person = { name: 'Alice', age: 25 };
greet(person); // Hello, Alice. You are 25 years old.
数组参数解构
function sum([a, b]) {
return a + b;
}
const numbers = [1, 2];
console.log(sum(numbers)); // 3
如果引入两个js文件时,两个js文件中存在相同变量,则通过取别名的方式解决变量重名问题
const {name,slogan,getTel} = require('./school.js')
const {name:stuName,motto,getTel:stuTel} = require('./student.js')
扩展理解
理解js模块之间的变量为什么是隔离的:
⼀个JS模块在执⾏时,JS代码是被包裹在⼀个内置函数中执⾏的,所以每个模块都有⾃⼰的作⽤域,我们可以通过如下⽅式验证这⼀说法: console.log(arguments.callee.toString())
得到以下代码:也就是js文件的代码都被包裹在function (exports, require, module, __filename, __dirname) {}
之中
function (exports, require, module, __filename, __dirname) {
const name = '张三'
const motto = '相信明天会更好!'
function getTel () {
return '13877889900'
}
function getHobby () {
return ['抽烟', '喝酒', '烫头']
}
module.exports = { name, motto, getTel }
console.log(arguments.callee)
console.log(arguments.callee.toString())
// exports.name = name
// exports.motto = motto
// exports.getTel = getTel
}
Uncaught ReferenceError: require is not defined 问题解决
浏览器本身没有模块化技术(各js模块文件的数据引入以及数据导出),因此不能直接直接在index.html文件中直接进行
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>index</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
const { name, slogan, getTel } = require('./school.js')
const { name: stuName, motto, getTel: stuTel } = require('./student.js')
出错原因:
Node.js 默认是⽀持 CommonJS 规范的,但浏览器端不⽀持,所以需要经过编译,
node环境下commonJS代码被包裹了函数function (exports, require, module, __filename, __dirname){}
因此不会出现上面的 require is not defined错误,但是浏览器环境中不支持模块化,因此报错。
解决方法:
使用 browserify 对index.js进行编译生成build.js,使得浏览器端认识build.js的模块化代码,步骤如下:
-
第一步:安装全局browserfy: npm i browserify -g
-
第二步:编译
browserify index.js -o build.js
build.js代码如下:
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ const {name,slogan,getTel} = require('./school.js') const {name:stuName,motto,getTel:stuTel} = require('./student.js') console.log(name) console.log(slogan) console.log(getTel()) console.log(stuName) console.log(motto) console.log(stuTel()) },{"./school.js":2,"./student.js":3}],2:[function(require,module,exports){ const name = '尚硅谷' const slogan = '让天下没有难学的技术!' function getTel (){ return '010-56253825' } function getCities(){ return ['北京','上海','深圳','成都','武汉','西安'] } module.exports = {name,slogan,getTel} },{}],3:[function(require,module,exports){ const name = '张三' const motto = '相信明天会更好!' function getTel (){ return '13877889900' } function getHobby(){ return ['抽烟','喝酒','烫头'] } module.exports = {name,motto,getTel}
-
第三步:页面引入
<script src="./build.js" type="text/javascript"></script>
ES6模块化规范
ES6模块化是一个官方标准,是浏览器与服务端均支持的规范
ES6数据的导入和导出
不同于CommonJS的exports.xxx ,ES6采用的是 export xxx 将数据导出
const name = '张三'
const motto = '相信明天会更好!'
function getTel () {
return '13877889900'
}
function getHobby () {
return ['抽烟', '喝酒', '烫头']
}
export { name, motto, getTel }
ES6默认是不支持服务器
造成错误的原因是:type="text/javascript"
的script标签无法引入ES6模块化语法
<script src="./index.js" type="text/javascript"></script>
修改为 type="module 识别模块化语法
<script src="./index.js" type="module"></script>
问题:服务端Node.js无法运行es6语法
(node:52143) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/xxx/Documents/005-java-sgg/yushen notes/【前端模块化】/code/5_ES6规范/index.js:1
import { getTel, motto, name } from './student.js'
^^^^^^
SyntaxError: Cannot use import statement outside a module
解决方法:
创建package.json文件
{
"type":"module"
}
注意:{} 花括号有时候代表对象,有时候也作为标记(类似对象)出现
统一导出: 这里的花括号不支持对象的写法 export { name:name,slogan,getTel} 因此不是对象
const name = {str:'尚硅⾕'}
const slogan = '让天下没有难学的技术!'
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武汉','⻄安']
}
// 统⼀导出了:name,slogan,getTel(这里不是对象)
export {name,slogan,getTel}