github地址: https://github.com/duwenbin0316/Requirejs-demo.git ,如果对你有帮助,请点个star,谢谢!
requirejs的使用我就一笔带过,主要是讲如何搭建项目结构。
项目基本目录结构如下:
在index.html中引入requirejs本身以及主js文件:
index.js定义了模块的名称和路径,以及模块所需的依赖,并调用了main模块的start方法:
main.js为应用主模块,调用main.start()执行应用初始化,所有的dom创建都在模块内部处理,index.html中只有一个div#main的dom元素。main.js内容如下:
同时在main.js中调用了header模块的start方法。
项目结构按照该思路一层一层构建,简单明了,当然也可以根据个人习惯提取出一些通用的组件,本文就不再赘述。
所以:只需要将需要暴露给外部的变量或者方法 设置为exports的属性 就行,
可以把exports看做一个全局对象,把所有暴露出来的函数和变量都存放在里面
1.先写个6.js文件
CommonJS规范规定,每个模块内部,module变量代表当前模板,这个变量是一个对象,他的 exports 属性(相当于 module.exports )是对外的接口。 这里详情请看我的另一篇文章: module、exports 和 require的关系
加载某个模块,其实是加载该模块的module.exports属性。require方法用于加载模块
ES6模块化的使用方法:(注!因为CommonJS类库众多,以及 CommonJS 和 ES6 之间的差异,所以无法直接兼容es6。)
直接/按需导出:可使用多个 用变量/常量的方式
导入:需要用按需导入 {解构} 的方式获取
默认导出:只能使用一个 (default属性只有es6才有)可以用引入对象定义多个属性,但这样在引入后调用的时候,更麻烦。
导入:优点:可以直接使用文件做接收参数且不用结构。
重命名export和import
如果导入的多个文件中,变量名字相同,即会产生命名冲突的问题,为了解决该问题,ES6为提供了重命名的方法,当你在导入名称时可以这样做:
如果想看CommonJS与ES6模块化的原理 可以去看我另一篇文章
[秦圆圆]大佬写的 require和import的区别
[大孩子气]大佬写的 require/exports、import/export 的区别
[七分sunshine!]大佬写的# 前端模块化工具 requireJs的使用
首先我们要明白一个前提,CommonJS模块规范和ES6模块规范完全是两种不同的概念。
我们知道在浏览器环境中,使用var声明一个全局变量会把该变量挂载到window对象上去,所以我们才可以访问到window.a
那如果是在node环境中呢?
如果我们在一个js文件中直接打印window是找不到这个顶层对象的,因为node环境下的顶层对象是global,
那我们声明的全局变量会不会像window对象一样挂载到global对象上呢?下面我们来试一下。
我们要想把变量a挂载到global对象上就必须要这样做
但是为什么会是undefined呢?
这就涉及到了模块化,在node环境中会存CommonJS模块化,它会把当前的文件当成模块的方式加载,那怎么理解以模块的方式加载呢?
我们可以简单的认为,每一个模块就是一个函数,模块中的内容就相当于是函数中的内容。
我们再想另一个问题,既然模块是一个函数,函数里的this指向是什么呢?
我们知道函数中的this是指向调用它的对象的,然而每个模块又是一个函数,node环境中的this又不能指向window,那会是指向谁呢?经过试验,发现node环境下的this指向的是一个空对象,这是因为node环境下的this指向的其实就是该模块导出的对象,默认是一个空对象
那我们如何让this指向全局对象global呢?很简单,把内容放到一个自执行函数里面就可以了,因为自执行函数里面的this永远指向全局对象
函数都会有arguments参数列表,而模块作为一个函数它的arguments又是什么呢?
module 和 exports 是Node.js给每个js文件内置的两个对象
在 a.js 中用 exports 或 module.exports 导出的对象,可以再另一个文件中通过该 require() 引用。
实际上,这两个对象指向同一块内存,也就是说他们两个是等价的(不去改变他们指向的内存地址)
require 引入的对象本质上是 module.exports .当 module.exports 和 exports 指向的不是同一块内存, exports 导出的内容就会失效。