背景
由于公司要做前后端分离,我在搭建单页面应用的前端路由框架时引入了RequireJS,但由于RequireJS本身基于AMD规范实现时只提供了针对JS模块的加载和移除API,其他资源(Resource)是通过插件的方式扩展的,由于我这里需要在组件切换时加载对应组件的CSS模块并移除上一个组件的CSS模块,所以必须要引入对应的CSS插件,但进一步发现的问题是,由于AMD规范并没有在插件中提出移除相关的规范,以至于RequireJS在实现时,并未要求插件要实现对应的移除API,所以原本官方在设计CSS插件上只有加载插件的load方法和标准化方法normalize的实现,若要移除CSS模块那么必须修改对应CSS插件和RequireJS的源码。
经过几天对AMD规范进一步的考察以及RequireJS和CSS插件源码的理解,具体源码修改方案如下。
解决方案
CSS插件源码修改
在原本CSS插件要求实现的load方法上新添加参数:
//other code
cssAPI.load = function (cssId, req, load, config,id) {
(useImportLoad ? importLoad : linkLoad)(req.toUrl(cssId + '.css'), load,id);
};
//other code
添加的id
最终是代表模块module
的ID,后面会详细说明。上述CSS插件考虑到浏览器兼容性,会根据用户当前浏览器判断使用哪种方式加载,第一个importLoad
方法是针对IE <9以及Firefox < 18版本,第二个linkLoad
是针对其他版本浏览器,由于我这里面向的用户群体的浏览器版本在IE10+和其他主流浏览器,所以我这里只修改对应内部的linkLoad
方法,对应linkLoad方法修改如下:
// other code
var linkLoad = function linkLoad(url, callback,id) {
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
if (useOnload) link.onload = function () {
link.onload = function () {
};
// for style dimensions queries, a short delay can still be necessary
setTimeout(callback