标签:效率 支付宝 script 推出 前端架构 私有属性 dev init 好的
掌握模块化基本概念以及使用模块化带来的好处
当你的网站开发越来越复杂的时候,会经常遇到什么问题?
历史上,JavaScript一直没有模块(module)体系, 无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。 其他语言都有这项功能,比如Ruby的 require
、Python的 import
, 甚至就连CSS都有 @import
, 但是JavaScript任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。
如何解决不通过 script 标签就能加载 JavaScript 文件代码。
什么是模块化
使用模块化开发的方式带来的好处
眼见他起高楼,眼见他宴宾客,眼见他楼塌了。
体验刀耕火种的模块化解决方式
以后如果不使用第三方规范的情况下, 如果写模块可以采用下面这种方式
```js ; (function (形参模块名, 依赖项, 依赖项) { // 通过 形参模块名 修改模块
window.模块名 = 形参模块名 })(window.模块名 || {}, 依赖项, 依赖项) ```
下面是一个关于模块化的面试题,一起观察和分析这段代码的作用:
js var UTIL = (function (parent, $) { // 动态的给一个不存在的对象挂载一个子对象 var my = parent.ajax = parent.ajax || {} my.get = function (url, params, callback) { return $.getJSON(url, params, callback) } return parent }(UTIL || {}, jQuery))
自然界生态系统、计算机操作系统、软件办公系统,还有教育系统、金融系统、网络系统、 理论系统等等。究竟什么是系统呢?
维基百科:系统泛指由一群有关连的个体组成,根据预先编排好的规则工作, 能完成个别元件不能单独完成的工作的群体。 系统分为自然系统与人为系统两大类。
简单来说,系统有两个基本特性:
系统之间的个体可以成为系统成员,要构建一个系统,最基本的层面需要做两件事:
Sea.js 是一个适用于 Web 浏览器端的模块加载器。 在 Sea.js 里,一切皆是模块,所有模块协同构建成模块系统。 Sea.js 首要要解决的是模块系统的基本问题:
在前端开发领域,一个模块,可以是JS 模块,也可以是 CSS 模块,或是 Template 等模块。 而 Sea.js 则专注于 JS 文件模块:
把上面两点中提及的基本书写格式和基本交互规则描述清楚,就能构建出一个模块系统。 对书写格式和交互规则的详细描述,就是模块定义规范(Module Definition Specification)。
比如 CommonJS 社区的 Modules 1.1.1
规范, 以及 NodeJS 的 Modules
规范, 还有 RequireJS 提出的 AMD
规范等等。
Sea.js 遵循的是 CMD 规范。
CMD、AMD、CommonJS 都是社区制定出来的模块规范, 他们的目的都是为了解决 JavaScript 没有模块化系统的问题。 他们都有如何定模块成员,以及模块成员之间如何进行通信交互的规则。
AngularJS Module 也是 ng 框架本身提供的一个模块系统解决方案。 ng定义模块需要起名,即便你去加载或者依赖一个模块的时候, 这个被依赖的模块也需要通过 script 标签引入到 html 页面中。
2015 年 9 月份,ECMAScript 官方推出了 ECMAScript 6 语言标准。 在最新的 ES6 语言规范标准中,已经制定了 JavaScript 模块化规范。
export import
前端界的风气:都喜欢追赶新技术,甚至把没有推出来的标准直接干到了生产环境。
这个社区太浮躁了。
A Module Loader for the Web, Enjoy the fun of programming.
关于 SeaJS
为什么学习和使用 SeaJS ?
谁在用?
SeaJS 适用场景
bower install seajs
npm install seajs
define
函数定义模块require
函数加载模块module.exports
对外暴露接口对象seajs.use
函数启动模块系统seajs.use
加载模块,启动模块系统。
seajs.use(‘id‘)
seajs.use(‘id‘, callback)
加载多个模块,加载完成时,执行回调 seajs.use([‘id1‘,‘id2‘,...],callback)
注意:
DOM ready
事件没有任何关系。如果某些操作要确保在 DOM ready
后执行,需要使用 jquery 等类库来保证define
中的模块代码里define(factory)
define
是一个全局函数,用来定义模块。
define
接受 factory
参数,factory
可以是一个函数,也可以是一个对象或字符串。
factory
为对象、字符串时,表示模块的接口就是该对象、字符串。
factory 是一个对象时
define({})
factory 是一个字符串时
define(‘hello‘)
factory 是一个函数时
define(function(require, exports, module){})
require
require 用来加载一个 js 文件模块, require 用来获取指定模块的接口对象 module.exports
。
require 在加载和执行的时候,js 会按照同步的方式和执行。
使用注意:
必须
命名为 requireTips: 把 require
看做是语法关键字就好啦
模块标识是一个字符串,用来标识模块。
模块标识可以不包含文件后缀名,比如 .js
模块标识可以是 相对 或 顶级 标识
相对标识
相对标识以 .
开头,永远相对于当前模块所处的路径来解析。
顶级标识不以 .
或 /
开始,会相对模块系统的基础路径(base路径,默认是 sea.js 文件所属的路径)。 可以手动配置 base 路径。
js seajs.config({ base: ‘./js‘ })
除了相对和顶级标识之外的标识都是普通路径。 普通路径的解析规则,会相对当前页面解析。
```js // 假设当前页面是 http://example.com/path/to/page/index.html
// 绝对路径是普通路径: require.resolve(‘http://cdn.com/js/a‘); // => http://cdn.com/js/a.js
// 根路径是普通路径: require.resolve(‘/js/b‘); // => http://example.com/js/b.js
// use 中的相对路径始终是普通路径: seajs.use(‘./c‘); // => 加载的是 http://example.com/path/to/page/c.js
seajs.use(‘../d‘); // => 加载的是 http://example.com/path/to/d.js ```
Tips:
base
基础路径解析。
seajs.config({ base: ‘基础路径‘ })
来配置基础路径seajs.use
中的相对路径始终相对当前页面来解析。module 是一个对象,上面存储了与当前模块相关联的一些属性和方法。
module.id
define
方法的第一个参数来指定,默认为该模块文件的绝对路径module.uri
module.dependencies
module.exports
return module.exports
exports 仅仅是 module.exports 的一个引用。 也就是说修改了 exports 就相当于修改了 module.exports。
但是一旦在 factory 内部给 exports 重新赋值,并不会改变 module.exports 的值。 因此给 exports 赋值是无效的。
module.exports
module.exports
或给它赋值改变模块接口对象exports
是 module.exports
的一个引用,就好比在每一个模块定义最开始的地方写了这么一句代码:var exports = module.exports
关于这俩哥们儿的区别请分析一下代码:
```js var module = { exports: {} }
function changeExports (exports, module) { // var exports = module.exports exports.foo = ‘bar‘
// 这里赋值拿不到,不要使用使用 // exports = function () {} return module.exports }
changeExports(module.exports, module) ```
那为啥要有 exports
?
为了开发体验,API更友好,使用 exports 的时候,可以少写一个点儿。
如果你实在分不清楚 exports
和 module.exports
之间的区别,就只记得 module.exports
就可以了。
标签:效率 支付宝 script 推出 前端架构 私有属性 dev init 好的
原文地址:http://www.cnblogs.com/lsy0403/p/5988124.html