目标:了解一下前端模块化的知识
内容:用于记录一些心得。(前端模块化)
正文:
一、JavaScript原始功能
在网页开发的早期,JS作为一种脚本语言,做一些简单的表单验证或者动画实现,那个时候代码还是很少的,一般是直接写在<script>标签中。
二、存在问题
随着AJAX异步请求的出现,慢慢形成了前后端的分离。客户端需要完成的事情越来越多,代码量也是与日俱增。为了应对代码量的剧增,我们通常会将代码组织在多个JS文件中,进行维护。但是这种维护方式,依然不能避免一些灾难性的问题。比如说全局变量同名问题(因为一个大的项目是多人完成的,需要导入每个人写的代码汇总);另外,这种代码的编写方式对JS文件的依赖顺序几乎是强制性的,也无法避免全局变量同名问题。
三、模块化雏形(早期的模块化)
之前解决上述的问题的方法有匿名函数,类似于(function () {} )()的格式。但是代码的复用性又不得不降低了,甚至不可复用。所以在ES5中可以通过把需要可复用的代码添加到一个对象,通过匿名函数的返回这个对象(使用模块作为出口,暴露到外面的属性和方法,不需要暴露的直接定义),并用某个变量去接收这个返回对象,这个变量就是模块。然后在别的文件导入这个模块,就可以使用这个模块的代码了。
幸运的是,前端模块化开发以及有了很多既有的规范,以及对应的实现方案。
常见的模块化规范有:CommonJS(通过node实现),AMD,CMD,也有ES6的Modules。(tips:模块化包括导出和导入)
四、CommonJS(webpack也使用这个,因为也是依赖node环境)
CommonJS的导出:(注意是要在node环境下,要用node底层解析module.exports)
1 module.exports = { 2 flag: ture, 3 test(a, b) { 4 return a + b 5 }, 6 demo(a, b) { 7 return a - b 8 } 9 }
CommonJS的导入:(moduleA是刚刚导出文件的文件名(可加路径))
1 //CommonJS模块 2 let {test, demo, flag} = require('moduleA') 3 //等同于 4 let _mA = require('moduleA'); 5 let test = _mA.test; 6 let demo = _mA.demo; 7 let flag = _mA.flag;
五、ES6的Modules
export(导出)/import(导入)
当我们在引入别人JS文件时,用<script src="xxx.js'>,当我们在script标签下使用type=‘module’时,这意味着我们是按照模块化使用这个xxx.js文件。相当于这个文件是在一个模块内,有着自己独立的作用域。
export(导出了模块对外提供的接口)。可以导出变量,函数,类(ES6提供了class类)。或者是导出一个默认的东西,让导入者自己来命名(export default),这样的好处就是导入者可以不必知道要导入的模块代码的名字。
1 //info.js 2 export let name = 'coco' 3 export let age = 18 4 //另一种写法 5 // let name = 'coco' 6 // let age = 18 7 // export {name, age} 8 export function logInfo (value){ 9 return console.log(value) 10 } 11 export class Person { 12 constructor(name, age){ 13 this.name = name; 14 this.age = age; 15 } 16 run(){ 17 console.log('I am a class') 18 } 19 } 20 // export logInfo, Person} 21 //默认导出只能有一个 22 const address = 'abc'; 23 export default address
import(导入,加载对应模块)。导入之后就可以对应使用了。
1 //func.js 2 import {name, age} from 'info.js' 3 import{logInfo, Person} from 'info.js' 4 //默认导出adress并命名为add 5 import add from 'info.js'