【问题标题】:Debugging with webpack, ES6 and Babel使用 webpack、ES6 和 Babel 进行调试
【发布时间】:2015-08-25 18:40:46
【问题描述】:

这看起来应该比较容易实现,但是唉。

我有 ES6 课程:

'use strict';

export class BaseModel {  
    constructor(options) {
        console.log(options);
    }
};

以及使用它的根模块:

'use strict';

import {BaseModel} from './base/model.js';

export let init = function init() {
    console.log('In Bundle');
    new BaseModel({a: 30});    
};

我的目标是:

  1. 通过 Babel 传递以上内容,得到 ES5 代码
  2. 用 webpack 打包模块
  3. 能够调试结果

经过一些试验,这是我拥有的 webpack 配置:

{
    entry: {
        app: PATH.resolve(__dirname, 'src/bundle.js'),
    },
    output: {
        path: PATH.resolve(__dirname, 'public/js'),
        filename: 'bundle.js'
    },        
    devtool: 'inline-source-map',
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel'
            }
        ]        
    }
}

这在一定程度上似乎奏效了。

所以,我可以这样做:

我可以按F11并输入代码,但我无法评估BaseModel

这有点违背调试的目的(或目的之一)。

我尝试过以各种顺序添加source-map-loaderbabel-loader

{
    test: /\.js$/,
    loader: "source-map-loader"
}

无济于事。

旁注 1:如果我放弃 webpack,只是通过 Babel 将带有源映射的模块编译成 System.js:

babel src/ --out-dir public/js/ --debug --source-maps inline --modules system
  • 一切正常。

旁注 2:这个 ?sourceMaps=true 似乎根本没有做任何事情,因为如果我从 webpack 中删除源映射配置 - 根本不会保留/生成任何源映射。人们会期望最初的、由 Babel 生成的源映射保存在结果文件中。没有。

任何建议将不胜感激

【问题讨论】:

    标签: javascript debugging ecmascript-6 webpack babeljs


    【解决方案1】:

    这是 Javascript 源映射的问题,don't currently support mapping symbol names 和 babel 在从 ES2105 模块语法编译为 CommonJS 时会更改 import-ed 模块的名称。

    Babel 这样做是为了完全支持 ES2015 模块 export bindings 的事实,方法是在代码中使用时解析对导入的所有引用,而不是在导入时。

    如果您不编写依赖于导出绑定的模块(很可能,因为您实际上无法使用 CommonJS 执行此操作),那么您可能更愿意在转译 ES2015 时保留变量名称。我为 Babel 6 创建了一个替代原生 babel commonjs 模块转换的替代方法,它保留了变量名:babel-plugin-transform-es2015-modules-commonjs-simple。这是原生 babel 变换 babel-plugin-transform-es2015-modules-commonjs 的直接替代品。

    您可以将它与 webpack 或 node.js 一起使用。一个典型的配置可能是:

    npm install --save-dev babel-preset-es2015-webpack
    npm install --save-dev babel-plugin-transform-es2015-modules-commonjs-simple
    

    模块babel-preset-es2015-webpack 是标准 es2015 预设的一个分支,它包含模块转换,因为您想使用替代版本。这也适用于节点。这些模块在.babelrc中使用:

    {
        "presets": [
            "es2015-webpack"
        ],
        "plugins": [
            "transform-runtime",
            ["transform-es2015-modules-commonjs-simple", {
                "noMangle": true
            }]
        ]
    }
    

    transform-runtime 通常是包含在任何实质性项目中的好主意,以避免生成代码的额外重复。 webpack.config.js中的典型模块配置:

    module: {
        loaders: [
            {
                loader: "babel-loader",
                include: [path.resolve(__dirname, "src")]                
            }
        ]
    },
    devtool: '#inline-source-map'
    

    生成的代码不会更改导入的名称,因此使用源映射进行调试将为您提供对符号的访问。

    【讨论】:

    • 非常好!将不得不尝试这个.. 调试 webpack 捆绑和转译的代码似乎有点痛苦 =( 绝对让我想念旧的 gulp / es5 JS 路线
    • 谢谢.. 对我们非常有帮助,尤其是在让开发人员购买完全转译的工作流程方面。 Babel 很容易原生地支持这一点(因为我的代码只是对原生模块的微小改动),但是 babel 团队选择了纯粹/完整与实用性的路线。就个人而言,如果没有良好的调试经验,我就活不下去,但我可以不编写具有动态绑定的模块。我希望源地图中的符号规范能够迅速出现,让所有这些都变得不必要,但这个过程似乎是在爬行。
    • @JamieTreworgy 你,我的朋友,是个英雄。我最近开始研究这个,因为它开始困扰我。谢谢。
    • 对此问题感兴趣的人请密切注意铬错误bugs.chromium.org/p/chromium/issues/detail?id=327092 - 有迹象表明源地图规范正在发生一些事情!
    • 有趣 - 所以当使用 tree-shaking Webpack 在 babel 编译步骤之后处理 ES6 模块转换时,所以不,这不起作用。我不知道 Webpack 最终使用什么过程来转换 ES6 模块语法,可能只是在摇树之后通过transform-es2015-modules-commonjs 推动它?我不敢相信他们会重新发明它。无论如何,我打赌它是可以解决的,但由于符号映射已经在 Canary 中获得了实验性支持(截至几天前),我不确定它是否值得弄清楚。
    【解决方案2】:

    您需要使用已编译的变量名称,而不是原始名称。 Source maps 只允许浏览器显示编译后的代码对应的源代码;他们不能让浏览器从编译后的代码中解析原始变量名。

    要查看已编译的变量名称,请切换到已编译的源代码,或查看右侧的“作用域变量”窗格,该窗格将显示(如锡上所说)当前作用域中存在哪些变量。

    IIRC Babel 倾向于在模块名称前加上 _,因此您的 BaseModel 变量可能称为 _baseModel 或类似名称。

    【讨论】:

    • 我明白了。不代表无法解决。最后 - 源地图就是这样,一个地图。从理论上讲,webpack 可以链接回 Babel 生成的原始源映射。他们甚至声称,AFAIU,source-map-loader,这似乎是可能的。
    • 另外,它不在作用域变量中,而是在闭包中。
    • Webpack 正在正确处理 Babel 源映射——如果不是这样,原始源将不会显示在 Chrome 中。但是源映射,无论它们是如何生成的,都不会影响 JavaScript 控制台的行为。 JavaScript 控制台(REPL,与 Source 窗格不同)将始终反映已编译源的变量名称等 - 即浏览器实际执行的源代码——不是原始源代码。
    • 一定误解了你在说什么。当我使用 System.js + babel 并使用源映射转换文件时 - 我可以绝对看到源代码和开发。工具指的是原始属性名称等。请参阅 旁注 1 的编辑以获取使用的截图和命令。 (当然控制台会打印出一个“真实的”toString,但这不是问题。
    • 啊。我懂了。我不知何故忘记了 Webpack 在其编译过程中重写 requires 的事实。改变这些变量名的是 Webpack,而不是 Babel。(续)
    【解决方案3】:

    我通过添加语句取得了一些成功

    调试器;

    在您的 javascript/typescript 文件中,甚至在 angular 或 vue2 的框架文件中,例如 *.vue

    因此,即使文件被转换、更改或重命名,或者您到 URL 的路径映射不起作用,调试器仍然会执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 2016-10-28
      • 2015-08-17
      • 2018-08-17
      • 2016-11-11
      相关资源
      最近更新 更多