整理下英文的方案吧.. 问题大致解决, 但没有详细测试过每种方案.
关于在 Popup 页面使用 RequireJS
我们在线上使用 RequireJS 时通过后端代码选择性对 标签进行渲染,
在 popup 页面无法用类似方案达成, 我暂时拟定方案是不进行代码合并,
转而使用 Uglify 的 Grunt 对每个文件单独进行混淆, 然后 zip 压缩..
在 Popup 里 HTML 当中不允许内嵌 JS 代码, 因此放在单独文件,
另外 Handlebars 因为没有编译, 会用到 eval
代码, 而扩展里是屏蔽的.
暂定在 content_security_policy
配置 unsafe-eval
允许模版执行..
实际上压缩还是有遇到问题的,RequireJS 依赖的 require exports modules
被替换了
解决方案就是在 [Uglify 里设定保留的标识符], 在插件里是 except 的配置:
options:
mangle:
except: [
'require'
'exports'
'module'
]
Content Script 里遇到的问题
RequireJS 兼容简化的 CommonJS 语法, 代码执行前会主动分析依赖,
然后取模块的名称添加对应的 标签来对代码进行加载.
这里的问题是, 出现在 Content Script 时, 这个路径是对应当前页面的路径,
而正常运行代码需要是在 chrome-extension://
路径下的代码.
网上的解决方案
搜到一个扩展中使用 RequireJS 的幻灯片, 中间提到了这个用法
代码在 GitHub 上可以查看, 内容是:
(function() {
var global = this;
require.load = function (context, moduleName, url) {
var xhr;
xhr = new XMLHttpRequest();
xhr.open("GET", chrome.extension.getURL(url) + '?r=' + new Date().getTime(), true);
xhr.onreadystatechange = function (e) {
if (xhr.readyState === 4 && xhr.status === 200) {
eval.call(global, xhr.responseText + '\n//@ sourceURL=' + url);
context.completeLoad(moduleName)
}
};
xhr.send(null);
};
})();
主要就是覆盖了原生加载方式, 获取了扩展的 url, 然后加载代码.
测试可用..
RequireJS 插件的问题
后来也注意到 RequireJS 的插件, 比如 json, text 的插件, 都没有搞定这事情.
打断点看了下, 发现是插件里的 load
方法存在问题,
按照文档.. 插件也是覆写几个方法的事情.., 于是开始手改了.
if (chrome && chrome.extension) {
if (config.baseUrl[config.baseUrl.length - 1] == '/') {
name = chrome.extension.getURL(config.baseUrl + name)
} else {
name = chrome.extension.getURL(config.baseUrl + '/' + name)
}
}
目前基本运行成功, 没有形似进行测试.
其他
搜到 StackOverflow 和 Google Groups 时有提到个 Cajon 模块,
看介绍和 almond
类似是 RequireJS 的官方定制版本..
Cajon 支持 CMD 语法的加载... 据说可以用在扩展里...
具体没有深入, 有了解的同学麻烦留言告知啦.. :P
https://github.com/requirejs/cajon/
返回博客首页: http://blog.tiye.me