在 JavaScriptCore 中获取默认导出
Posted
技术标签:
【中文标题】在 JavaScriptCore 中获取默认导出【英文标题】:Get Default Export in JavaScriptCore 【发布时间】:2021-05-17 23:40:53 【问题描述】:目标:我正在尝试在 javascriptCore 中运行 JSLint。
旧版本
较早的 JSLint 版本公开了一个名为 JSLINT
的全局函数,如下所示:
var JSLINT = (function ()
...
这很容易在 JavaScriptCore 中检索和执行:
// Assume 'ctx' is a JSGlobalContextRef
// Assume we have already called JSEvaluateScript()
JSStringRef jsFunctionName = JSStringCreateWithUTF8CString("JSLINT");
JSValueRef jsLintFunctionValue = JSObjectGetProperty(ctx, JSContextGetGlobalObject(ctx), jsFunctionName, NULL);
JSStringRelease(jsFunctionName);
JSObjectRef jsLintFunction = JSValueToObject(ctx, jsLintFunctionValue, &exception);
有了这个引用,我就可以使用JSObjectCallAsFunction()
来执行该函数。完美运行。
新版本
现在,JSLint 已移至此:
export default Object.freeze(function jslint(
source = "",
option_object = empty(),
global_array = []
)
...
);
JavaScriptCore 的文档很差。我尝试了很多东西,但显然缺少一些明显的东西。我现在如何检索和执行jslint
函数?
【问题讨论】:
【参考方案1】:将 jslint 作为 es-module 导入的说明是 here。
/*jslint devel*/
import jslint from "./jslint.mjs";
let code = "console.log('hello world');\n";
let result = jslint(code);
result.warnings.forEach(function (
formatted_message
)
console.error(formatted_message);
);
// stderr
// 1 Undeclared 'console'. // line 1, column 1
// console.log('hello world');
// 2 Use double quotes, not single quotes. // line 1, column 13
// console.log('hello world');
【讨论】:
【参考方案2】:快速版
如果@kaizhu 的回答没有给你想要的,另一个接近你以前状态的选择是......
-
注释掉两行导出代码that starts on this line。
引用小写
jslint
这是您需要用今天的 JSLint 版本注释掉的两行代码。
// export default Object.freeze(jslint_export);
// jslint_import_meta_url = import.meta.url;
如果您在项目中包含该现在编辑的文件,则函数 jslint
将在您的全局范围内。
console.log(JSON.stringify(jslint("var a = 5").warnings, null, " "))
结果:
[
"a": ";",
"b": "(end)",
"code": "expected_a_b",
"column": 9,
"line": 1,
"line_source": "var a = 5",
"name": "JSLintError",
"message": "Expected ';' and instead saw '(end)'.",
"formatted_message": " 1. \u001b[31mExpected ';' and instead saw '(end)'.\u001b[39m \u001b[90m// line 1, column 9\u001b[39m\n var a = 5"
]
我认为您对代码所做的唯一更改是将jslint
小写:
JSStringRef jsFunctionName = JSStringCreateWithUTF8CString("jslint");
改进?
请注意,使用jslint_export
可能“更正确”,它是jslint
的冻结副本。
JSStringRef jsFunctionName = JSStringCreateWithUTF8CString("jslint_export");
如果您真的愿意,您可以将 jslint_export
变量替换为 JSLINT
,而根本不更改您的 JavaScriptCore 代码。
// let jslint_export; // The jslint object to be exported.
let JSLINT; // The jslint object to be exported.
// lots of stuff skipped
// jslint_export = Object.freeze(Object.assign(jslint,
JSLINT = Object.freeze(Object.assign(jslint,
cli: Object.freeze(jslint_cli),
edition: jslint_edition,
jslint: Object.freeze(jslint.bind(undefined))
));
我必须仔细检查旧代码以查看其行为是否相同,但请注意实际的 linting 函数将在该构造中的 JSLINT.jslint
上。
但是,我不确定为什么在当前版本的 JSLint 中存在如此多的全局范围污染。为什么这并不都存在于IIFE 中,这令人困惑;我认为它曾经?无论如何,这应该可以解决您的问题。
【讨论】:
以上是关于在 JavaScriptCore 中获取默认导出的主要内容,如果未能解决你的问题,请参考以下文章
使用 JavascriptCore C Api 绑定本机对象
swift 笔记:iOS与JavaScript的交互(二):JavaScriptCore:16。 JSContext相关演示,在委托:webViewDidFinishLoad()中获取上下文