对于CoCo webpack打包的一些研究
简述
本文通过注入webpack loader的方式,对coco的一些特殊loader进行分析,以供给第三方改造项目。
本文基于coco版本:v1.21.7
main.js hash: 8a4a5649
0.js hash: c6105fac
1、webpack loader的注入
在控制台运行以下代码
当然,也可以以油猴脚本方式插入
const hookedCode = document .getElementById("root") .nextSibling.innerText.replace("function u(t)", "var u=(...arg)=>(console.log('loader',...arg),window.loader(...arg));window.loader=function(t)") .replace("u.e=function(e)",";u.e=function(e)");
eval(hookedCode);原理是修改loader所在的代码,把loader(u)函数赋值到全局
2、loader特殊值查找教程
如我们想找获取coco中变量等配置的获取方法
通过字符串查找,我们很容易找到以下位置的代码
/*https://creation.codemao.cn/coconut/web/1.22.0-0/static/js/main.8a4a5649.chunk.js:2,585776*/ var r = n(1) , o = n.n(r) , i = n(10) , a = n(6) , s = n(25) , c = n(7) , l = n(31) , u = n(38) , d = n(9) , p = n(26) , f = n(5) , h = n(98) , m = n(374); /*...省略...*/ var n, r, i, a, s, c, m, g, _, b, y, C, T, S, I, A, j, N, R; /*...省略...*/ return r = u.d.getState(), i = r.project, a = i.title, s = i.globalVariableList, c = i.globalArrayList, m = i.globalWidgetIds, g = i.globalObjectList, _ = i.version, b = i.projectSource, y = null === (n = r.common.userInfo) || void 0 === n ? void 0 : n.id, C = w(r.project.screens), T = r.project.screens.map((function(e) { return e.id } )).toJSON(), /*...省略...*/通过上面的代码,我们可以发现globalVariableList等数据可以通过r这个变量获取,而r这个变量是u.d.getState()
从它上面的代码,我们可以看到,u这个变量通过n(38)获取,此处的n就是loader函数
于是,globalVariableList等价于loader(38).d.getState().project.globalVariableList
事实亦如此,通过控制台验证可以得到
3、一些特殊的loader值
loader(0)
这个是coco的入口,是个React render函数
loader(38).d
通过这个可以获取到coco内部的Redux store
project中可以获取大量完整的项目信息
loader(35).Db(控件type)
返回控件的经过coco处理的type(内有控件实体,但是没有原始的type)
如loader(35).Db("TEXT_WIDGET")这样使用
对于来自商城拓展控件,只有添加到舞台后才能使用
对于自定义控件,可以直接获取
其获取到的结构如图
loader(35).K()
返回所有控件的经过coco处理的type
loader(42)
g
当前屏幕下(也可能是作品)的所有控件的Map
格式为 控件id:控件data
f
渲染控件的函数,需要传入渲染的参数(详细看代码)
loader(98)
一个关于自定义、拓展控件的Map
d
返回当前作品中所有的拓展(商城)控件的id、type和cdnUrl
e
返回当前作品中所有的自定义(商城)控件的type和code
f
传入type,根据type查询详细信息,可以找寻到控件的原始types
4、一些注意点
- 上文中给的那段例子的代码很有用,可以根据他找到很多loader值
- 如果coco更新的话,loader值可能失效
- 失效的话没关系,根据以前的关键词重新找就是了,也可以保存以前的
document.getElementById("root").nextSibling.innerText替换掉新的 - 多试验,这个文档过于简略了
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
























