1

我设置了一个使用Carbon Components的 Svelte 和 Electron 。我大部分时间都在工作,但我一直在调试。

这是我用于测试的示例组件:

<script lang="ts">
    import { Tile } from 'carbon-components-svelte'
    let name = 'John Doe'

    function test() {
        console.log('You clicked me!')
    }
</script>

<div>
    <Tile>
        <h2>{name}</h2>
        <button on:click={test}>Click me</button>
    </Tile>
</div>

当我将组件加载到开发环境中时,我无法在 Chrome 的开发工具中设置断点:

在此处输入图像描述

但是,如果我打开我svelte.config.js的 ,最初看起来:

import sveltePreprocess from 'svelte-preprocess'
import { optimizeImports } from "carbon-preprocess-svelte";

export default {
  preprocess: [ sveltePreprocess(), optimizeImports() ]
}

并删除optimizeImports()调用,然后断点正常工作。

有谁知道为什么会这样?显然这与carbon-preprocess-svelte图书馆有关。我创建了一个重现该问题的基本项目:https ://github.com/troncoso/carbon-svelte-bug

4

2 回答 2

1

TL;DR:内联源映射有点损坏,这是carbon-preprocess-svelte.


当你使用:时,默认的模块解析将从一个大的伞形文件中import { Tile } from 'carbon-components-svelte'导入命名的导出,这是一个大的缩小代码包。显然这不是最优的。Tilecarbon-components-svelte/lib/index.js

optimizeImportsfromcarbon-preprocess-svelte是一个预处理器,它试图通过读取您的导入代码然后将其重写为import Tile from "carbon-components-svelte/src/Tile/Tile.svelte".

显然,这个预处理器中存在某种错误,会产生损坏的源映射。准确地说,它会生成一个丢失了一些映射位置的源映射。Chrome devtool 依赖这些映射位置来设置断点。当它丢失时,它不能设置一个。

当您手动重写导入时,您会跳过此预处理器,从而避免错误行为。这与您目前的发现一致。

我们可以在这里搁置我们的案例并得出结论,您optimizeImports现在应该避免使用,只需将错误报告给碳团队。下面将深入探讨更多细节。


这是坏情况的内联源图:

//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FDQSxJQUFBLE1BQUEsK0NBQUE7Ozs7Ozs7Ozs7Ozs7O2FBUThCLFVBQ2xCO3VCQUFDLEdBQUs7Ozs7O0dBRGhCLFVBRVE7Ozs7O3dEQUZVLEdBQVM7Ozs7O3VEQUNoQixHQUFLOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQVJsQixLQUFBLEdBQUEsQ0FBQTs7T0FDQSxTQUFBO2tCQUNBLEtBQUEsSUFBQSxDQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7IiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIkNvdW50ZXIuc3ZlbHRlIl0sInNvdXJjZXNDb250ZW50IjpbIjxzY3JpcHQgbGFuZz1cInRzXCI+XG4gIGltcG9ydCBUaWxlIGZyb20gJ2NhcmJvbi1jb21wb25lbnRzLXN2ZWx0ZS9zcmMvVGlsZS9UaWxlLnN2ZWx0ZSdcbiAgbGV0IGNvdW50OiBudW1iZXIgPSAwXG4gIGNvbnN0IGluY3JlbWVudCA9ICgpID0+IHtcbiAgICBjb3VudCArPSAxXG4gIH1cbjwvc2NyaXB0PlxuXG48VGlsZT5cbiAgPGJ1dHRvbiBvbjpjbGljaz17aW5jcmVtZW50fT5cbiAgICBDbGlja3M6IHtjb3VudH1cbiAgPC9idXR0b24+XG48L1RpbGU+XG5cbjxzdHlsZT5cbiAgYnV0dG9uIHtcbiAgICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgICBmb250LXNpemU6IGluaGVyaXQ7XG4gICAgcGFkZGluZzogMWVtIDJlbTtcbiAgICBjb2xvcjogI2ZmM2UwMDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjIsIDAsIDAuMSk7XG4gICAgYm9yZGVyLXJhZGl1czogMmVtO1xuICAgIGJvcmRlcjogMnB4IHNvbGlkIHJnYmEoMjU1LCA2MiwgMCwgMCk7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgICB3aWR0aDogMjAwcHg7XG4gICAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gIH1cblxuICBidXR0b246Zm9jdXMge1xuICAgIGJvcmRlcjogMnB4IHNvbGlkICNmZjNlMDA7XG4gIH1cblxuICBidXR0b246YWN0aXZlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjIsIDAsIDAuMik7XG4gIH1cbjwvc3R5bGU+XG4iXX0=

这是一个很好的案例

//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FDQSxJQUFBLE1BQUEsK0NBQUE7Ozs7Ozs7Ozs7Ozs7O2FBUThCLFVBQ2xCO3VCQUFDLEdBQUs7Ozs7O0dBRGhCLFVBRVE7Ozs7O3dEQUZVLEdBQVM7Ozs7O3VEQUNoQixHQUFLOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQVJsQixLQUFBLEdBQUEsQ0FBQTs7T0FDQSxTQUFBO2tCQUNBLEtBQUEsSUFBQSxDQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7IiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIkNvdW50ZXIuc3ZlbHRlIl0sInNvdXJjZXNDb250ZW50IjpbIjxzY3JpcHQgbGFuZz1cInRzXCI+XG4gIGltcG9ydCBUaWxlIGZyb20gJ2NhcmJvbi1jb21wb25lbnRzLXN2ZWx0ZS9zcmMvVGlsZS9UaWxlLnN2ZWx0ZSdcbiAgbGV0IGNvdW50OiBudW1iZXIgPSAwXG4gIGNvbnN0IGluY3JlbWVudCA9ICgpID0+IHtcbiAgICBjb3VudCArPSAxXG4gIH1cbjwvc2NyaXB0PlxuXG48VGlsZT5cbiAgPGJ1dHRvbiBvbjpjbGljaz17aW5jcmVtZW50fT5cbiAgICBDbGlja3M6IHtjb3VudH1cbiAgPC9idXR0b24+XG48L1RpbGU+XG5cbjxzdHlsZT5cbiAgYnV0dG9uIHtcbiAgICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgICBmb250LXNpemU6IGluaGVyaXQ7XG4gICAgcGFkZGluZzogMWVtIDJlbTtcbiAgICBjb2xvcjogI2ZmM2UwMDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjIsIDAsIDAuMSk7XG4gICAgYm9yZGVyLXJhZGl1czogMmVtO1xuICAgIGJvcmRlcjogMnB4IHNvbGlkIHJnYmEoMjU1LCA2MiwgMCwgMCk7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgICB3aWR0aDogMjAwcHg7XG4gICAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gIH1cblxuICBidXR0b246Zm9jdXMge1xuICAgIGJvcmRlcjogMnB4IHNvbGlkICNmZjNlMDA7XG4gIH1cblxuICBidXR0b246YWN0aXZlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjIsIDAsIDAuMik7XG4gIH1cbjwvc3R5bGU+XG4iXX0=

它们是 base64 编码的 json,如果我们解码它们,我们会得到:

坏情况

{
  "version": 3,
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;OAAiB,IAAA,MAAA,+CAAA;;;;;;;;;;;;;;aASa,UAClB;uBAAC,GAAK;;;;;GADhB,UAEQ;;;;;wDAFU,GAAS;;;;;uDAChB,GAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;",
  "names": [],
  "sources": ["Counter.svelte"],
  "sourcesContent": [
    "<script lang=\"ts\">\n  import { Tile } from 'carbon-components-svelte'\n  let count: number = 0\n  const increment = () => {\n    count += 1\n  }\n</script>\n\n<Tile>\n  <button on:click={increment}>\n    Clicks: {count}\n  </button>\n</Tile>\n\n<style>\n  button {\n    font-family: inherit;\n    font-size: inherit;\n    padding: 1em 2em;\n    color: #ff3e00;\n    background-color: rgba(255, 62, 0, 0.1);\n    border-radius: 2em;\n    border: 2px solid rgba(255, 62, 0, 0);\n    outline: none;\n    width: 200px;\n    font-variant-numeric: tabular-nums;\n    cursor: pointer;\n  }\n\n  button:focus {\n    border: 2px solid #ff3e00;\n  }\n\n  button:active {\n    background-color: rgba(255, 62, 0, 0.2);\n  }\n</style>\n"
  ]
}

好案例

{
  "version": 3,
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;OACA,IAAA,MAAA,+CAAA;;;;;;;;;;;;;;aAQ8B,UAClB;uBAAC,GAAK;;;;;GADhB,UAEQ;;;;;wDAFU,GAAS;;;;;uDAChB,GAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KARlB,KAAA,GAAA,CAAA;;OACA,SAAA;kBACA,KAAA,IAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;",
  "names": [],
  "sources": ["Counter.svelte"],
  "sourcesContent": [
    "<script lang=\"ts\">\n  import Tile from 'carbon-components-svelte/src/Tile/Tile.svelte'\n  let count: number = 0\n  const increment = () => {\n    count += 1\n  }\n</script>\n\n<Tile>\n  <button on:click={increment}>\n    Clicks: {count}\n  </button>\n</Tile>\n\n<style>\n  button {\n    font-family: inherit;\n    font-size: inherit;\n    padding: 1em 2em;\n    color: #ff3e00;\n    background-color: rgba(255, 62, 0, 0.1);\n    border-radius: 2em;\n    border: 2px solid rgba(255, 62, 0, 0);\n    outline: none;\n    width: 200px;\n    font-variant-numeric: tabular-nums;\n    cursor: pointer;\n  }\n\n  button:focus {\n    border: 2px solid #ff3e00;\n  }\n\n  button:active {\n    background-color: rgba(255, 62, 0, 0.2);\n  }\n</style>\n"
  ]
}

问题出在mappings现场。您可以使用源映射解码器了解这两个文件,然后通过单击转储按钮进行比较。您会看到坏案例文件中缺少一些映射信息。

这篇文章源码图剖析,如果你感兴趣的话,将引导你了解js源码图格式的技术细节(理解神秘的;;OAAiB,IAAA,MAAA,+CAAA;;部分)。

但是现在让我们简单地阅读人性化的转储:

Counter.svelte,137,27,5,0,null

translates to:

position 137:27 from compiled file `Counter.js`
maps to 
position 5:0 from original source file `Counter.svelte`

这是两个文件的转储。

坏情况映射转储

Counter.svelte,24,7,1,17,null
Counter.svelte,24,11,1,17,null
Counter.svelte,24,17,1,17,null
Counter.svelte,24,64,1,17,null
Counter.svelte,38,13,10,30,null
Counter.svelte,38,23,11,12,null
Counter.svelte,39,23,11,13,null
Counter.svelte,39,26,11,18,null
Counter.svelte,44,3,10,2,null
Counter.svelte,44,13,12,10,null
Counter.svelte,49,56,10,20,null
Counter.svelte,49,59,10,29,null
Counter.svelte,54,55,11,13,null
Counter.svelte,54,58,11,18,null

好案例映射转储

Counter.svelte,24,7,2,0,null
Counter.svelte,24,11,2,0,null
Counter.svelte,24,17,2,0,null
Counter.svelte,24,64,2,0,null
Counter.svelte,38,13,10,30,null
Counter.svelte,38,23,11,12,null
Counter.svelte,39,23,11,13,null
Counter.svelte,39,26,11,18,null
Counter.svelte,44,3,10,2,null
Counter.svelte,44,13,12,10,null
Counter.svelte,49,56,10,20,null
Counter.svelte,49,59,10,29,null
Counter.svelte,54,55,11,13,null
Counter.svelte,54,58,11,18,null
Counter.svelte,134,5,3,0,null
Counter.svelte,134,10,3,0,null
Counter.svelte,134,13,3,0,null
Counter.svelte,134,14,3,0,null
Counter.svelte,136,7,4,0,null
Counter.svelte,136,16,4,0,null
Counter.svelte,137,18,5,0,null
Counter.svelte,137,23,5,0,null
Counter.svelte,137,27,5,0,null
Counter.svelte,137,28,5,0,null
于 2021-10-13T06:08:15.570 回答
0

有关详细信息,请阅读@hackape 的答案。但最终它似乎是一个错误carbon-preprocess-svelte,特别是optimizeImports()插件。我在该项目上创建了一个问题:https ://github.com/carbon-design-system/carbon-preprocess-svelte/issues/18

与此同时,我想出了一个解决方案,确保源地图正常工作,但我仍然会摇晃树。我创建了一个carbon.ts文件:

import { Button } from 'carbon-components-svelte/src/Button'
import { Tile, ClickableTile } from 'carbon-components-svelte/src/Tile'
import { StructuredList, StructuredListHead, StructuredListBody, StructuredListRow,
    StructuredListCell } from 'carbon-components-svelte/src/StructuredList'
import { Header, HeaderGlobalAction, HeaderUtilities, Content }
    from 'carbon-components-svelte/src/UIShell'
import { Theme } from 'carbon-components-svelte/src/Theme'
import { TooltipDefinition } from 'carbon-components-svelte/src/TooltipDefinition'

export  {
    Button,
    Tile,
    ClickableTile,
    StructuredList,
    StructuredListBody,
    StructuredListCell,
    StructuredListHead,
    StructuredListRow,
    Header,
    HeaderGlobalAction,
    HeaderUtilities,
    Theme,
    TooltipDefinition,
    Content
}

当我需要一个组件时,我只需将它添加到这个文件中。然后我像这样导入组件:

<script lang="ts">
    import { Button } from '@/components/carbon'
</script>

我知道我可以自己在 svelte 文件中完成导入,但是这样当错误修复后,我可以更轻松地找到并替换所有导入。只需搜索“@/components/carbon”并将其替换为“carbon-components-svelte”。

于 2021-10-13T12:30:41.787 回答