我维护一个greasemonkey脚本,用于监控当前播放的曲目以及Soundcloud的进度。以前,我可以require("lib/audiomanager")
来访问一个允许我查看整个页面状态的对象,例如播放曲目信息。
问题是,Soundcloud已经开始使用webpack作为他们的客户端Javascript。根据我的理解,这会将所有这些类存储为包中的特定数字。它们存储的数量似乎在每次更新客户端JS时都会更改 并重新编译。
访问webpack中存储的对象的唯一方法似乎是通过全局webpackJsonp,如下所示。包的数量只需要是唯一的。
webpackJsonp([6060], {
0: function (e, t, n) {
window.aman = n(726);
e.exports = function (abc) {
console.log("Exports called");
};
}
});
该代码将执行并允许我访问webpack中该编号的对象。客户端webpack&JS中定义的对象是:
726: function (e, t, n) {
(function (t) {
function i(e) {
var n = t(e.getContainerElement()),
i = e.getState() === r.States.ERROR;
n.toggleClass('blocked', i)
}
var r,
s = n(53),
o = n(14),
a = 1000 / 60;
e.exports = r = new s({
flashAudioPath: n(2181),
flashObjectID: 'flashAudioObject',
updateInterval: a,
debug: !1
}),
r.Errors = s.Errors,
r.States = s.States,
r.UPDATE_INTERVAL = a,
o.once('audio:flash_block audio:flash_unblock', i)
})
.call(t, n(1))
},
所以,我能想到的解决方案:
后者看起来很乱,第一个似乎不可能。有什么想法吗?
我尝试的事情:
答案 0 :(得分:3)
我们也在客户端脚本中使用SoundCloud API,因此我们最终得到了一些“清洁”code。这是它的主要部分(请注意,它不包含try-catch块,因为所有模块都存在):
var playManager, libAudio, eventBus;
webpackJsonp([], {0: function(a, b, require)
{
var modules = require.c;
for (var moduleid in modules)
{
var el = require(moduleid);
if (typeof el["playCurrent"] == "function")
{
playManager = el;
}
else if (typeof el["getSettings"] == "function")
{
libAudio = el;
}
else if (typeof el["trigger"] == "function"
&& typeof el["bind"] == "function"
&& typeof el["listenToOnce"] == "function" &&
typeof el["$"] != "function" &&
typeof el["broadcast"] == "function")
{
eventBus = el;
}
}
答案 1 :(得分:1)
Afaik您只能从其他包中访问包。 Soundcloud不使用ProvidePlugin,因此全局空间中没有可用的库和模块。
更新:
我知道这是一个丑陋的黑客,但它有效:
webpackJsonp([6060], {
0: function (e, t, n) {
var i = 0,
found = false,
lib;
while (i < 2000 && !found) {
try {
lib = n(i);
}
catch (err) {
lib = null;
}
if (lib && typeof lib._mute !== 'undefined') {
found = true;
console.log('found', lib, i);
}
console.log(i, lib);
i++;
}
window.aman = lib;
}
});