曾经倍受好评的上古免费插件迎来史诗级更新!

SeekPro这款插件诞生于五年前。它简陋,粗糙甚至还会卡顿。那时最新的Creator版本才来到3.3。而编写插件的资料更是无从寻起。所以它的实现可以说是非常奇葩。但就是这么一款插件,它确实解决了开发过程中的一些小毛刺,因此下载量也达到了400多。

在过去的五年里,我曾经碰到过不止一个人提起过这个插件,虽然他不出名。但是这个插件能被人使用并且记得它的好,也是让我感到惊喜。而在AI的加持下,今天这个插件终于更新到了3.0版本。引来重磅的史诗级功能更新。

改进或者新增了如下功能:

插件地址如下(依旧免费)
https://store.cocos.com/app/detail/3468

如果你在使用过程中遇到任何bug或者有优化的建议,欢迎你通过插件介绍里的联系方式联系作者。这个插件的迭代离不开你们的优质建议。 :laughing:

4赞

我还想要一个功能.
就是一个bundle,除了那几个主包,还会不会引用其它包的资源.
这个功能有点类似 点击bundle,导出资源包,这样就能看出依赖了哪些东西了.那几个主包,可以忽略.但如果有其它包,就有点问题了.

楼主好人一生平安 先mark

有的啊。bundle分析里有三个大分类

主包依赖当前bundle的资源
当前bundle依赖其他bundle的资源
其他bundle依赖当前bundle的资源

这个需求不能满足你的要求吗?

嗯,看到了.
发现一个问题,脚本循环依赖的时候,卡死了…

:sweat_smile: 控制台有无输出啥子的。多提供点信息。可能是你脚本数量太大了之类的。

又看了一下,进度100%就没有了.
log也没有.

说明没有脚本循环依赖?

有的有的.

不行,你把工程(只保留脚本)发给我。我自己测试一下算了。 :rofl:


// 用 Tarjan SCC 求真实循环依赖,对比插件算法
const fs = require(‘fs’);
const path = require(‘path’);
const ROOT = ‘/Users/dhf/Documents/git/cocos/blast/assets’;
const EXTS = [’.ts’, ‘.tsx’, ‘.js’, ‘.jsx’];

function* walkFiles(dir) {
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
const p = path.join(dir, e.name);
if (e.isDirectory()) { if (e.name === ‘node_modules’ || e.name.startsWith(’.’)) continue; yield* walkFiles§; }
else if (EXTS.includes(path.extname(e.name).toLowerCase())) yield p;
}
}
const files = […walkFiles(ROOT)];
const fileSet = new Set(files.map(f => path.resolve(f)));
const importRe = /(?:import|export)[^’"]from\s’"[’"]|import\s*’"[’"]/g;
function resolveImport(fromFile, spec) {
if (!spec.startsWith(’.’)) return null;
const base = path.resolve(path.dirname(fromFile), spec);
for (const ext of EXTS) if (fileSet.has(base + ext)) return base + ext;
for (const ext of EXTS) if (fileSet.has(path.join(base, ‘index’ + ext))) return path.join(base, ‘index’ + ext);
return null;
}
const graph = new Map();
for (const f of files) {
const rf = path.resolve(f);
let src; try { src = fs.readFileSync(f, ‘utf8’); } catch { continue; }
let m; importRe.lastIndex = 0;
while ((m = importRe.exec(src))) {
const t = resolveImport(rf, m[1] || m[2]);
if (t && t !== rf) { if (!graph.has(rf)) graph.set(rf, new Set()); graph.get(rf).add(t); }
}
}

// Tarjan SCC (迭代版,避免栈溢出)
const t0 = Date.now();
const index = new Map(), low = new Map(), onStack = new Set(), stack = [];
let idx = 0;
const sccs = [];
for (const start of graph.keys()) {
if (index.has(start)) continue;
const callStack = [[start, 0]];
while (callStack.length) {
const frame = callStack[callStack.length - 1];
const v = frame[0];
if (frame[1] === 0) { index.set(v, idx); low.set(v, idx); idx++; stack.push(v); onStack.add(v); }
let recurse = false;
const targets = graph.get(v) ? […graph.get(v)] : [];
for (let i = frame[1]; i < targets.length; i++) {
const w = targets[i];
if (!index.has(w)) { frame[1] = i + 1; callStack.push([w, 0]); recurse = true; break; }
else if (onStack.has(w)) low.set(v, Math.min(low.get(v), index.get(w)));
}
if (recurse) continue;
if (low.get(v) === index.get(v)) {
const scc = [];
let w;
do { w = stack.pop(); onStack.delete(w); scc.push(w); } while (w !== v);
if (scc.length > 1) sccs.push(scc);
}
callStack.pop();
if (callStack.length) { const p = callStack[callStack.length - 1][0]; low.set(p, Math.min(low.get§, low.get(v))); }
}
}
console.log(‘Tarjan SCC 耗时(ms):’, Date.now() - t0);
console.log(‘真实循环依赖组数(强连通分量>1):’, sccs.length);
sccs.slice(0, 10).forEach((scc, i) => {
console.log(\n环 #${i + 1} (${scc.length} 个文件):);
scc.slice(0, 6).forEach(f => console.log(’ ‘, path.relative(ROOT, f)));
if (scc.length > 6) console.log(’ … 等’, scc.length, ‘个’);
});

哈哈哈,这就是免费的插件的意义。请论友帮我找bug,然后修复。这个回答我会喂给AI的,让他修复一下。哈哈哈


扫描完文件报错了。 :sweat_smile:

进QQ群反馈吧。我现场抽AI去修

初看时,这啥插件,看完后,哦哦,它啊

有人反馈垃圾,所以不看了 :dog: