[英]JS infinite loop protection, how to use babel-standalone plugins without node or web-worker with DOM?
有一个浏览器内代码编辑器 (ace),可以为 p5.js 动态编译用户编写的代码。 研究如何防止无限循环并了解到一些这样的编辑器将babel-standalone与loop-protect一起使用。 为了避免定时循环标志(默认 100 毫秒)的问题,repl.it 使用了一个名为transform-prevent-infinite-loops.js的插件,它限制了迭代次数。
两者看起来都很棒并且想要测试它们,但是我无法弄清楚如何将任何一个(两个 CommonJS 模块)与 babel-standalone 一起使用,特别是在不使用捆绑器或 nodejs 时。 我很乐观地认为有一种方法可以直接加载这些插件,因为我不需要解析自己的代码,只需将等待的代码分析为变量字符串。 让内联lolizer插件示例正常工作 - 但上述无限循环保护插件要复杂得多,不幸的是,文档似乎没有提到独立导入外部插件。 是否可以在没有捆绑程序或 nodejs 的情况下使用这些?
基本设置: https://pastebin.com/LEYx8Kr4
以前分享过其他尝试,但按照建议减少到一个问题。
带有网络工作者的基本设置: https://pastebin.com/NgAPZzCX
在 pastebin 上还尝试使用web-worker route ,但似乎它不支持DOM API ,其中引入了 p5.js 函数。 为了解决这个问题,尝试做一些花哨的正则表达式来将代码剥离到循环中,但是你缺少变量,即。 如果循环计数是loopCount
而不是10
。
如果存在无限循环以防止重新编译会覆盖当前正在运行的代码(实时编码环境)的错误代码,最终目标是得到一个危险信号。 web-worker 路由提供了这一点,如果我正确理解 babel,它不会标记它,但实际上会更改正在编译的代码以捕获该无限循环......是否还有另一种技术需要考虑,或者可能是这一切的混合?
我正在为我的库开发一个 repl,并且已经在独立使用 babel。
这个问题对我来说是正确的,因为它帮助我使用来自 react 的链接 babel 插件解决了这个问题。
如果你在某处声明你的插件 function
const preventInfiniteLoops = ({ types: t, template }) => {
const buildGuard = template(`
if (ITERATOR++ > MAX_ITERATIONS) {
throw new RangeError(
'Potential infinite loop: exceeded ' +
MAX_ITERATIONS +
' iterations.'
);
}
`)
return {
visitor: {
'WhileStatement|ForStatement|DoWhileStatement': (path, file) => {
// An iterator that is incremented with each iteration
const iterator = path.scope.parent.generateUidIdentifier('loopIt')
const iteratorInit = t.numericLiteral(0)
path.scope.parent.push({
id: iterator,
init: iteratorInit,
})
// If statement and throw error if it matches our criteria
const guard = buildGuard({
ITERATOR: iterator,
MAX_ITERATIONS: t.numericLiteral(MAX_SOURCE_ITERATIONS),
})
// No block statment e.g. `while (1) 1;`
if (!path.get('body').isBlockStatement()) {
const statement = path.get('body').node
path.get('body').replaceWith(t.blockStatement([guard, statement]))
} else {
path.get('body').unshiftContainer('body', guard)
}
},
},
}
}
然后将其添加到独立的 babel 很简单
更新您的 pastebin 示例:(这是一个猜测,我没有测试过)
Babel.availablePlugins['preventInfiniteLoops'] = preventInfiniteLoops
let output = Babel.transform(codeIn.value, { presets: [], plugins: ['preventInfiniteLoops']}).code;
我正在使用 es6,所以我的代码是这样做的:
import { availablePlugins } from '@babel/standalone'
availablePlugins['preventInfiniteLoops'] = preventInfiniteLoops
这篇文章对我帮助很大,希望我的评论也能帮助其他人
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.