SeaJS在AIFISH前端框架中的使用详解

二叶草 2020年3月9日21:34:30前端框架评论阅读模式
在软件开发过程中,模块化设计编程思想早已见怪不怪了,模块化设计程序编写不仅给开发设计精英团队产生高效率层面上的益处,还可以让开发设计的新项目或是商品维护保养成本费大幅度降低。那麼,在WEB开发设计全过程中JS开发语言早已必不可少了,通过JS脚本语言能够带来更加舒适的人机交互和用户体验。但是,JS脚本的使用过程中也会有出现引用依赖的混乱,那么JS脚本语言的模块化思想势必会得到大家广泛的认可,在这样的一个背景下,AIFISH框架采用了由现蚂蚁金服前端工程师玉伯带来的成熟的模块化加载js框架——seajs。

SeaJS简介

Seajs,一个Web模块加载框架,追求简单、自然的代码书写和组织方式,Sea.js 遵循 CMD 规范,模块化JS代码。依赖的自动加载、配置的简洁清晰,可以让程序员更多地专注编码。

优点:

1. 提高可维护性。

2.模块化编程。

3.动态加载,前端性能优化

这里不得不提一下AMD和CMD规范:

异步模块定义(AMD)是AsynchronousModule Definition的缩写,是 RequireJS 在推广过程中对模块定义的规范化产出。

通用模块定义(CMD)是Common ModuleDefinition的缩写,是SeaJS 在推广过程中对模块定义的规范化产出。

RequireJS和 SeaJS 都是模块化框架的代表,AMD和CMD,是他们各自定义模块化的方式,大同小异,主要是代码风格和API不同。

SeaJS使用

SeaJS环境中的javascript的写法—模块化

模块化?何为模块化?在seaJS中的所有javascript都必须要依据模块化的书写格式。这又是什么意思?其实,seaJS在管理文件的过程中是根据javascript(这里我们先讨论seaJS对javascript的管理)的文件名进行管理的,这个文件名就相当于我们平时所说的命名空间。在调用文件的时候我们可以直接写文件名而不需要写它的后缀。但是也是有特殊情况的:

a.加载css的时候一定要加后缀的

b.路径中有”?“的时候javascript文件的后缀不能省略

c.路径中是以"#"号结尾的文件也不可以省去后缀

到底如何模块化一个javascript?这个时候就要用到我们seaJS提供的几个接口了,模块化使用define函数,如下:

define(id,deps,factory)

id:模块id,可以自己赋值,如果不赋值默认就是该函数的相对路径,各位可以调试看看;

deps:当前模块所依赖的模块,这里关键就是按需加载了,将你需要的js文件引入;

factory:模块工厂函数,这个函数是重点,主要是模块的逻辑实现。

模块化案例

在前端开发领域,一个模块,可以是JS 模块,也可以是 CSS 模块,或是 Template 等模块。在 Sea.js 里,我们专注于 JS 模块(其他类型的模块可以转换为 JS 模块):

1.模块是一段 JavaScript 代码,具有统一的基本书写格式。

2.模块之间通过基本交互规则,能彼此引用,协同工作。

在AIFISH前端框架中每个js文件都是一个模块,在文件开头有如下定义:

SeaJS在AIFISH前端框架中的使用详解

factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:require、exports 和 module。

SeaJS在AIFISH前端框架中的使用详解

当前模块对外提供的接口。传给 factory 构造方法的 exports 参数是 module.exports 对象的一个引用。只通过 exports 参数来提供接口,有时无法满足开发者的所有需求。 比如当模块的接口是某个类的实例时,需要通过 module.exports来实现。

SeaJS在AIFISH前端框架中的使用详解

require 是一个方法,接受模块标识作为唯一参数,用来获取其他模块提供的接口。之后就可以在当前js模块引用utils模块的方法了。

SeaJS踩坑全记录

seajs的模块定义方式非常simple,主要的难点在于不同项目有不同的部署要求,因此因为模块标识理解不够在AIFISH前端开发框架选型初期造成各种坑。下面详细分析下模块标识和加载机制!

模块标识
  • 模块标识命名规则

1、一个模块标识由斜线(/)分隔的多项组成。

2、每一项必须是小驼峰字符串、 . 或 .. 。

3、模块标识可以不包含文件后缀名,比如 .js 。

4、模块标识可以是 相对 或 顶级 标识。如果第一项是 . 或 ..,则该模块标识是相对标识。

解释一下其中的几种概念:

1、相对路径,以. 或 ..开头。

2、顶级路径,不以.或 ..及斜线(/)开头。

3、普通路径,除相对和顶级路径外的,比如/(根路径)开头的,"http://"、"https://"、    "file:///" 等协议标识开头的。

4.模块命名空间是seajs所在文件的根路径即所谓的base路径,去除了seajs/x.y.z 字串,   也可以指定seajs.config({base:});

SeaJS在AIFISH前端框架中的使用详解

  • 模块依赖提取过程如何解析

1、只提取相对标识。

2、相对标识相对 require 所在模块的标识来解析。

  • 上线后模块标识解析规则

1、顶级标识始终相对 base 基础路径解析。(顶级标识由字符串开头)。

2、绝对路径和根路径,即普通路径,始终相对当前页面解析,跟我们平时用的其他js和css路径一样,比如当前页面是www.simple.com/user/index.html ,路径为/js/hello.js,它解析后的地址为www.simple.com/js/hello.js。

3、模块定义中require 和 require.async 的相对路径相对当前模块路径来解析。

如果我们能理解其模块标识解析设计的出发点,那么就可以轻易的理解这些而不用记忆这么多:

1、关注度分离。书写模块的时候我们是不用指定模块id的,require的模块时候只要填入依赖模块的相对路径,于是我们只要关注代码的书写而不是依赖,打包后工具会自动帮我们处理好模块id。

2、尽量与浏览器的解析规则一致。上线后在浏览器中的代码,模块路径的解析规则应该于平时用的css、js这些加载路径规则一样,普通路径和相对路径的都是相对当前页面的。

模块记载机制

千万别天真的以为你在模块里面这样:

SeaJS在AIFISH前端框架中的使用详解

就天真地以为,这个模块会加载完a模块之后再加载b模块。真相其实是这样的:
在一个模块里面,require语句的优先级是最高的,无论你将它放在模块的任意位置会优先执行require。 注意,优先执行require不代表你可以这么写:

SeaJS在AIFISH前端框架中的使用详解

除非a.js是个三方插件或者a模块不对外提供任何方法和属性,仅仅是用于给页面来点特效啦,加载一些数据啦等,和代码的下文没有什么关系的事情,你大可以把require(“a”)放在任何地方,也就没必要将其赋值给某个变量了。

比如:

a.js的内容如下:

SeaJS在AIFISH前端框架中的使用详解

一个依赖a模块的模块内容如下:

SeaJS在AIFISH前端框架中的使用详解

执行结果你会发现弹窗内容果然先是”a”,后是”t”;
值得注意的是seajs还有一种模块加载方法是use,它的加载时机就得看你把它写在什么地方了。
接上文的那个依赖a模块的模块内容如果是这么写:

SeaJS在AIFISH前端框架中的使用详解

这次的执行结果就是先”t”后”a”了。

言归正传,a和b到底谁先加载,我可以肯定地告诉你,确实是a先加载,但是!恩,但是来了。但是a和b谁先加载完就得看各自的造化了,或是因为网络原因,或是因为文件大小,意思就是说你require的模块它们之间一定不要有啥耦合关系,否则很有可能会因为加载的先后顺序导致一些异常,不过话又说回来,如果你严格按照seajs的规范来设计模块的话这种事问题肯定不会出现的,各个模块内部都有独立的作用域和其明确的依赖链。

总 结

AIFISH中使用SeaJS可以提高JavaScript代码的可读性和清晰度,解决目前JavaScript编程中普遍存在的依赖关系混乱和代码纠缠等问题,方便代码的编写和维护。
SeaJS本身遵循KISS(Keep It Simple, Stupid)理念进行开发,其本身仅有个位数的API,因此学习起来毫无压力。在学习SeaJS的过程中,处处能感受到KISS原则的精髓——仅做一件事,做好一件事。

本文来源于:SeaJS在AIFISH前端框架中的使用详解-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
二叶草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" )...

发表评论