【问题标题】:Get Default Export in JavaScriptCore在 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 函数?

【问题讨论】:

    标签: javascript c jslint javascriptcore


    【解决方案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 的回答没有给你想要的,另一个接近你以前状态的选择是......

      1. 注释掉两行导出代码that starts on this line
      2. 引用小写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 中,这令人困惑;我认为它曾经?无论如何,这应该可以解决您的问题。

      【讨论】:

        猜你喜欢
        • 2017-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-07
        • 2020-04-30
        • 1970-01-01
        相关资源
        最近更新 更多