使用 TypeScript 将 JSON(从 Sentry)转换为 HTML

Posted

技术标签:

【中文标题】使用 TypeScript 将 JSON(从 Sentry)转换为 HTML【英文标题】:Convert JSON (from Sentry) to HTML with TypeScript 【发布时间】:2019-03-22 07:44:22 【问题描述】:

我想学习 TypeScript。

我有一个由哨兵方法 event_from_exception() (Python) 返回的 JSON 字典。

我想将它格式化为带有可扩展局部变量和 pre_ 和 post_context 的漂亮 html。结果应大致如下所示:

这是一个示例 json:


  "exception": 
    "values": [
      
        "stacktrace": 
          "frames": [
            
              "function": "main", 
              "abs_path": "/home/modlink_cok_d/src/sentry-json.py", 
              "pre_context": [
                "from sentry_sdk.utils import event_from_exception", 
                "", 
                "def main():", 
                "    local_var = 1", 
                "    try:"
              ], 
              "lineno": 9, 
              "vars": 
                "exc": "ValueError()", 
                "local_var": "1"
              , 
              "context_line": "        raise ValueError()", 
              "post_context": [
                "    except Exception as exc:", 
                "        event, info = event_from_exception(sys.exc_info(), with_locals=True)", 
                "        print(json.dumps(event, indent=2))", 
                "", 
                "main()"
              ], 
              "module": "__main__", 
              "filename": "sentry-json.py"
            
          ]
        , 
        "type": "ValueError", 
        "value": "", 
        "module": "exceptions", 
        "mechanism": null
      
    ]
  , 
  "level": "error"

TypeScript 怎么能做到这一点?

【问题讨论】:

这个问题并没有真正需要什么 - 你应该展示你已经尝试过的东西,等等。'with typescript'没有帮助 - 是否涉及框架?看起来你只是想让别人为你做这项工作。 @David 这是我第一个使用 TypeScript 的“玩具”项目。我以前从未使用过这种语言。这就是为什么我还没有尝试任何东西。到目前为止,还没有涉及其他框架。我不希望别人这样做。我想要一些提示如何解决这个问题。 您知道如何使用 javascript 来实现吗?这肯定会引导您朝着正确的方向使用 TypeScript。 @David 不,我不知道如何在 JS 中执行此操作。我曾经使用 XSLT 将 XML 从一种格式转换为另一种 XML 格式。但这并不好玩。我觉得 XSLT 太复杂了。 我对这个问题的一个方面感到困惑:你想要一个生成 HTML 的 CLI 程序,还是一个接受事件并呈现它的浏览器内 web 应用程序?后者的一个答案可能是 React,前者可能需要不同类型的模板引擎。 【参考方案1】:
    为您的数据创建架构。这将帮助您使用 TypeScript 和 IDE。

你可以使用给你的https://app.quicktype.io。

export interface Welcome 
    exception: Exception;
    level:     string;


export interface Exception 
    values: Value[];


export interface Value 
    stacktrace: Stacktrace;
    type:       string;
    value:      string;
    module:     string;
    mechanism:  null;


export interface Stacktrace 
    frames: Frame[];


export interface Frame 
    function:     string;
    abs_path:     string;
    pre_context:  string[];
    lineno:       number;
    vars:         Vars;
    context_line: string;
    post_context: string[];
    module:       string;
    filename:     string;


export interface Vars 
    exc:       string;
    local_var: string;

    从您的 data 渲染 HTML。

您可以使用template literal 如果您没有首选 Web 框架(React、Vue)。

const data = JSON.parse(json);
const html = `
    <div>$data.exception.values.map(value => `
        <div>$value.stacktrace.frames.map(frame => `
            <div>
                <pre>$frame.abs_path in $frame.function</pre>
                <div style="margin-left:2rem">
                    $frame.pre_context.map((line, i) =>`
                        <pre>$frame.lineno + i - frame.pre_context.length. $line</pre>
                    `).join("")

                    <pre><strong>$frame.lineno. $frame.context_line</strong></pre>
                    $frame.post_context.map((line, i) => `
                        <pre>$frame.lineno + i + 1. $line</pre>
                    `).join("")
                </div>
            </div>
        `).join("")</div>
    `).join("")</div>
`;
document.body.innerHTML = html;

例如:https://codesandbox.io/s/52x8r17zo4

【讨论】:

【参考方案2】:

要在没有框架的情况下自行执行此操作,我将为 json 中的每个元素创建一个类。然后我会在每个类上都有一个 toHTML(domParent) 方法来迭代它的子组件:

class Stacktrace  
  frames: Frame[];
  type: string;
  value: string;
  module: string;
  mechanism: string;

  toHTML(domParent) 
    for (let frame of Frame) 
      frame.toHTML(domParent); 
    
    domParent.addChild(`<div>$type</div>`);
    domParent.addChild(`<div>$value</div>`);
    domParent.addChild(`<div>$module</div>`);
    domParent.addChild(`<div>$mechanism</div>`);
  

这只是伪代码,但应该能让你走上正轨。

【讨论】:

我还建议至少对基本组件使用Bootstrap 之类的东西。如果你最终想要一个框架,你可能会比选择Angular 做得更糟。【参考方案3】:

选项 1. 将文件另存为 .json 并使用浏览器打开(我尝试使用 FireFox)你应该能够以非常好的格式看到它,就像你发布的图片一样。

选项 2. 使用 JavaScript 根据 JSON 动态创建 DOM 对象。参考this和this。

/*

以下是创建脚本的一些提示

解析 JSON 使用递归函数根据您的喜好创建 div 或 p 标签。 还在每个元素上添加点击事件侦听器以展开/折叠子视图。

*/

希望这会有所帮助。

【讨论】:

以上是关于使用 TypeScript 将 JSON(从 Sentry)转换为 HTML的主要内容,如果未能解决你的问题,请参考以下文章

使用 TypeScript 函数返回 JSON 对象

将 JSON 对象映射到 TypeScript 对象

typescript - 将 json 转换为接口

从 Typescript 解析 JSON 恢复数据成员但不恢复类型:无法在结果上调用方法

如何从 Typescript 中的 package.json 获取版本?

从 Typescript POST 到 Web API API,无法传递 JSON 对象