资讯专栏INFORMATION COLUMN

requirejs的插件介绍与制作

shinezejian / 1824人阅读

摘要:一句化即它是插件的插件,作者事后才发现有这么一个插件绕了不少弯路。这里的主要是为了保存这段内容用于打包使用。免费领取验证码内容安全短信发送直播点播体验包及云服务器等套餐更多网易技术产品运营经验分享请访问网易云社区。文章来源网易云社区

本文由作者郑海波授权网易云社区发布。

前言
我这里就不介绍requirejs了, 简而言之: requirejs是支持AMD规范的模块加载器, 事实上它也是AMD的最直接推动者。

现在可供挑选的开源模块解决方案很多,比如component、cjs+browserify、umd等等,但是无疑类似requirejs这类加载系统是现在最成熟和可靠的解决方案,所以regularjs第一步就是提供对requirejs的插件支持。

requirejs的插件体系
requirejs的源码内部预留了hook,使得你可以创建插件来增强这个模块系统,并且这个插件可以做到影响到你的OPTIMIZER阶段,一些资源可以被处理为标准的AMD模块。

插件普遍被用来

预编译

加载非js文本

lint 或 test 后置或前置的操作 等等

example 比如它本身是不支持加载文本信息的,但是你可以通过text!插件来加载。

require(["text!foo.html", "jquery"], function(foo, $){

$("#anchor").html(foo);

})
需要注意的是由于文本无法用script标签进行加载,所以text内部是通过XHR来载入的,即它会受到同源策略的影响。

优化OPTIMIZER

由于requirejs同时提供工具(npm:requirejs)可以静态打包优化AMD,刚才的那个text!foo.html会同时被text插件转换为类似下面的AMD模块结构

define("text!foo.html",[],function () {

return "

早上好

";

});
requirejs的插件其实是一个实现的特定接口的标准AMD模块,它在定义时与其它业务模块并无区别。

例如官方text插件的源文件

define(["module"], function (module) { "use strict"; var text = {

    load: function(){}
    ....
}    return text

})
其中load等接口是插件必须实现的,

对于各个接口描述我就不细究了,大家可以参考官网

顺便列举一些有用的requirejs插件

text插件(最常用插件) 如果你的文本内容无需在打包优化阶段做处理,几乎都可以使用这个插件来完成加载

json插件 比楼上多做了一步JSON.parse.

amd-loader(好东西): 注意不要requirejs本身弄混了,因为requirejs本身不是基于xhr的,这个插件主要是提供完善的xhr支持来加载文本内容。一句化即它是[插件的loader插件],作者事后才发现有这么一个插件...绕了不少弯路。具体例子可以查看es6

handlebars 用来加载handlebar的插件

其实由于amd等模块系统占据了开发中的模块入口这一环,其实在开发中可以有无限的可能性,这也是常规大公司都会自造一个轮子来最优配置的缘由之一,事实上requirejs目前的插件系统已经有足够的灵活性来定制自己的策略。

实现requirejs-regular的过程
背景

首先我们先理清我们的需求, 与常规的的模板预编译类似,我们的插件主要为了实现两个功能。

在开发阶段,我们希望能加载js文件一样,加载我们的模板文件,这带来的几个好处

这使得我们不必将模板零散的填充到页面的script 或 textarea标签中

依赖系统唯一化, 模板依赖集成进了模块依赖中

在优化阶段(即requirejs提供的OPTIMIZER的上线打包功能),我们的模板字符串可以被预处理为序列化的AST对象,这样就不会发生浏览器端的解析,效率更高。

实现

一个插件模块会同时跑在浏览器端(开发环境)和node端(为线上或测试环境的打包优化工具),所以你的插件模块必须可以同时跑在浏览器端和node端,这个几乎是整个开发环境最麻烦的一部分

regular.js的单文件虽然是umd模块可以支持amd环境,但是由于依赖的dom。所以首先要将parser部分(不依赖dom)打成一个AMD模块,由于regularjs本身就是基于commonjs的模块构建,将其中一部分打成AMD模块是分分钟的事情,这里我们使用webpack来打包成regular-parser.js,简单起见我们随regularjs模块一同发布到bower上

我们还要解决模板的加载问题,插件内部的加载问题也要手动解决,即你至少要实现loader接口和get接口。这里我们完全可以偷个懒,直接使用!text插件。

即插件会依赖这两个模块

define(["text", "regular-parser"], function(text, parser){ //blalalalala...

return{
    load: load,
    write: write
}

})
然后我们只需要实现两个接口:

load

var buildMap = {};function load(name, req, onLoad, config){

text.load(name, req, function(data,r){
    onLoad(
      (buildMap[name] = parser.parse(data, false))
    );
}, config);

}
这里直接使用了text插件的纯文本加载,需要注意的是这个onLoad接口,传入参数相当于模块的内容,我们这里预parse了这段文本内容。即你通过rgl!template.html最终会获得解析后的AST数据。

其实对于regularjs来讲在浏览器端有无进行模块系统层面的预解析并无意义,关键是在打包优化阶段。这里的buildMap主要是为了保存这段内容用于打包使用。

write 实现write接口主要是为了在打包优化阶段改写相关模块

var tpl = function(str, data){ return str.replace(/{{(w+)}}/g, function(all, name){ return data[name] || ""

})

}var template ="define("{{pn}}!{{mn}}",function(){ return {{ast}} });n";function write(pn, mn, writeModule){ if(buildMap[mn]){

   writeModule(
       tpl(template,{
           pn: pn,
           mn: mn,
           ast: parser.parse(buildMap[mn])
       })
   )

}
}
此时这个插件必须依赖于两个模块,即必须同时保证text和regular-parser模块同时存在,类似的方案可以查看hogan,它必须保证环境中有hogan和text才可以运行. 熟悉requirejs打包过程的同学也知道,除了loader端的配置,我们在build的打包文件也需要一并将这些依赖模块剔除,因为上线时是不需要这些插件的。所以这将大大增加配置成本,其实解决方案也很简单,就是使用[webpack]再将其打包成一个standlone的AMD模块即可,具体可以参考这里的gulpfile。

大功告成

使用就非常简单了,和你使用requirejs-text差不多,

1.首先下载rgl.js,最简单的就是bower安装

bower install regularjs-regular --save
save参数是安装后并写入到bower.json中,这个和npm一致

2.配置

require.config({ paths : { "rgl": "../../bower_components/regularjs-regular/rgl",

   // 同时载入我们的regularjs来使用这些模板       "regularjs": "../../bower_components/regularjs/dist/regular"

}
});
3.使用

require(["rgl!./foo.html", "regularjs"], function( tpl, Regular){ var Foo = Regular.extend({

  template: tpl
})    new Foo({}).$inject("#app")

});
4.打包

模板文件

{{message}}

经过插件处理后会打包成

define("rgl!foo.html",function(){return [{"type":"element","tag":"h2","attrs":[],"children":[{"type":"expression","body":"_c_._sg_("message", _d_["message"])","constant":false,"setbody":"_c_._ss_("message",_p_,_d_, "=")"}]}] });
即上线后就不会有parse了,比如PO主目前正在开发的项目在初期就有几十个模板文件,build成单文件后的运行时开销还是应该尽量避免.

tip:build.js记得通过stubModules配置项目删除掉这个插件模块,具体看demo的build.js。

对于NEJ的使用者
NEJ的新模块系统支持上述类似的regular模板加载了

网易杭州的同事,事实上你已经可以在NEJ的新模块系统中(完全兼容老版本)通过regular!path/to/template.html的方式来加载你的regular模板了,打包之后模板将会被预解析,同时新版NEJ也支持text!加载纯文本内容, 详询@飞锅。新版本的加载系统,支持类似AMD的注入写法,并且兼容老版本的模块写法,亲测好用哈。

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请访问网易云社区。

文章来源: 网易云社区

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25374.html

相关文章

  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0
  • 一张脑图看懂BUI Webapp移动快速开发框架【上】--框架工具、资源

    摘要:后续我们还会增加一些实战类的移动开发案例,欢迎关注专栏。进入官网新版预览在线预览需要使用开启设备模拟,效果更佳。 前言 之前写过一篇 2018开发最快的Webapp框架--BUI交互框架 ,如果你还没看过,可以简单看一下,主要介绍了BUI的基本功能,有多少控件,以及实现的思路,BUI 1.5版本以后变化很大,统一新的风格,新的规范750,新增基于Dom的数据驱动,完善了页面的生命周期等...

    wuyumin 评论0 收藏0
  • RequireJS按需加载样式文件

    摘要:这个需求我们经常遇到,比如我们使用时,在加载其脚本模块时,在页面我们也会添加上标签引入其相关的样式文件。 样式模块化的好处 RequireJS被设计用来加载JavaScript模块的,可是大家有没有联想到其实样式文件可以进行模块化处理,那么问题来了,RequireJS能不能像加载脚本文件一样来加载样式文件呢? 虽然RequireJS本身没有实现这个功能,但官网推荐了一些常用的插件供...

    googollee 评论0 收藏0
  • 前端开发应知网站

    摘要:作为一名前端开发者所有程序员最起码遇到就算不会解决也应该会搜解决问题的答案跟大家分享一下我个人积累的网站开发者文档菜鸟教程教程网一行代码搞定监控阿里巴巴图标库颜色布料在线制作,有很多在线开发工具渐进式应用程序核对表在线存放图片的地址 作为一名前端开发者(所有程序员)最起码遇到bug就算不会解决也应该会搜解决问题的答案 跟大家分享一下我个人积累的网站: MDN开发者文档:https:/...

    netScorpion 评论0 收藏0
  • 前端开发应知网站

    摘要:作为一名前端开发者所有程序员最起码遇到就算不会解决也应该会搜解决问题的答案跟大家分享一下我个人积累的网站开发者文档菜鸟教程教程网一行代码搞定监控阿里巴巴图标库颜色布料在线制作,有很多在线开发工具渐进式应用程序核对表在线存放图片的地址 作为一名前端开发者(所有程序员)最起码遇到bug就算不会解决也应该会搜解决问题的答案 跟大家分享一下我个人积累的网站: MDN开发者文档:https:/...

    harryhappy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<