如何从开发工具控制台使用 ES6 模块

问题描述 投票:0回答:9

据我了解,如果我创建一个 ES6 模块,我只能从本身就是一个模块的代码中导入它。这意味着非模块代码,即内联 Javascript,或 Chrome 开发工具控制台永远无法访问模块中的代码。

这是真的吗?有什么办法可以解决这个问题,因为这似乎是一个相当极端的限制。

javascript es6-modules
9个回答
93
投票

您可以在 Chrome 控制台中使用 动态导入

import('path/to/module.js').then(m => module = m)

// [doSomething] is an exported function from [module.js].
module.doSomething()

27
投票

您可以使用类似

window.myFunction = myFunction
window.myVariable = myVariable
的行在全局命名空间中注册函数或变量。您可以在声明
myFunction
myVariable
的模块中执行此操作,也可以在导入它们的单独模块中执行此操作。

完成此操作后,您将能够从 Chrome DevTools 控制台使用

myFunction
myVariable

例如:

import myModule from '/path/to/module.js';
window.myModule = myModule;

// in the console:
myModule.foo();

(感谢 @Evert 在评论中提供了这个解决方案,尽管是以一种相当迂回的方式,我花了一段时间才弄清楚。)


21
投票

您可以在 Chrome 控制台中 await 动态导入

const Module = await import('./path/to/module.js')
Module.doSomething()

动态导入大致相当于:

import * as Module from './path/to/module.js';
Module.doSomething()

3
投票

有一种方法可以将 Chrome 开发工具与 ES6 模块结合使用,如果您使用 VSCode适用于 Chrome 的 Javascript 调试器。我在让它工作时遇到了一些麻烦,但这是值得的。 https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome

VSCode 调试器启动一个新的 chrome 窗口,该窗口连接到 VSCode 调试器。您还可以像往常一样在此窗口中使用 Chrome 开发工具 (F12)。它与 ES6 模块配合使用,您可以设置断点、使用控制台、检查变量等...


如果您在设置调试器时遇到困难,这对我来说是这样的:

  • 转到 VSCode 调试窗口 (
    CTRL+SHIFT+D
    ) -> 从下拉列表中选择
    Add Configuration
    -> 选择
    Chrome Launch
    Chrome Launch Legacy
    更改“launch.json”

我的launch.json:

{
  "name": "Launch Chrome Legacy",
  "type": "chrome",
  "request": "launch",
  "url": "http://localhost:5000/auth/login",
  "webRoot": "${workspaceFolder}",
  "sourceMaps": true
},
{
  "name": "Launch Chrome",
  "request": "launch",
  "type": "pwa-chrome",
  "url": "http://localhost:5000/auth/login",
  "webRoot": "${workspaceFolder}",
  "sourceMaps": true
},

关键是使用

"sourceMaps": true
"url": "http://localhost:5000/auth/login"
而不是
http://localhost:5000/blog"
,这是我真正想要调试的页面。但是,当调试器打开新的 chrome 窗口时,我的页面被重定向到
/auth/login
,所以我必须使用这个 url。

  • 您可以尝试禁用新调试器的预览版本并使用
    Legacy
    版本: 在 VSCode 设置中关闭
    Debug › JavaScript: Use Preview
  • 然后从 VSCode 中的调试窗口运行
    Launch Chrome Legacy
  • 要在 VSCode 中设置断点,请从
    Loaded Scripts
  • 打开 javascript 模块

3
投票

一些稍微更符合人体工程学的版本,与不同类型的进口之间的对应关系:

// import { namedExport1, namedExport2 } from 'https://example.com/lib.js'
const { namedExport1, namedExport2 } = await import('https://example.com/lib.js')

// import defaultExport from 'https://example.com/lib.js'
const { default: defaultExport } = await import('https://example.com/lib.js')

// import * as mod from 'https://example.com/lib.js'
const mod = await import('https://example.com/lib.js')

编辑:这里有一个自动进行转换的小实用程序:

function convertImports(imports, { verbose } = {}) {
    return imports
        .split(/\n(?=\s*import)/)
        .map((statement) => {
            const m = statement.match(/^\s*import\s*(?:(?<def>[$\p{L}\p{N}\p{M}]+)|\*\s+as\s+(?<wildcard>[$\p{L}\p{N}\p{M}]+)|(?<named>\{[^}]+\}))\s+from\s+(?<from>(?<quot>['"])[^'"]+\k<quot>)(?:\s+assert\s+(?<assertion>\{[^}]+\}))?[\s;]*$/u)
            if (!m) return statement

            const { groups: { def, wildcard, named, from, assertion } } = m

            const vars = named
                ? named.replaceAll(/\s+as\s+/g, ': ')
                : (wildcard ?? `{ default: ${def} }`)

            return `${verbose ? statement.split('\n').map((x) => `// ${x}\n`).join('') : ''}const ${vars} = await import(${from}${assertion ? `, { assert: ${assertion} }` : ''})`
        })
        .join(verbose ? '\n\n' : '\n')
}

// usage

const imports = `
import { namedExport1, namedExport2 } from 'https://example.com/lib.js'
import {
    namedExport3 as three,
    namedExport4 as four,
} from 'https://example.com/lib.js'
import defaultExport from 'https://example.com/lib.js'
import * as mod from 'https://example.com/lib.js'
import $ from 'https://example.com/jquery.js'
import data from 'https://example.com/data.json' assert { type: 'json' }
`.trim()

console.log(convertImports(imports, { verbose: true }))


1
投票

您可以使用 import 从 Chrome 开发者控制台调用 Javascript 模块中包含的函数,如@Kin 的回答所示。

如果收到错误“TypeError: 无法解析模块说明符”,请尝试使用模块文件的完整 URL。例如,在本地运行 IIS 的 Windows 10 和 Chrome 87 上,这对我有用:

// Call doSomething(), an exported function in module file mymodule.js
import('http://localhost/mysite/myfolder/mymodule.js').then((m) => { m.doSomething(); });

0
投票

您只能从其他模块导入模块,因为

import
是模块功能。

在 ES6 模块之前你是如何“导入”的?你没有,因为它不存在。您实际上可以与 E6 模块进行交互,就像在两个独立的非模块脚本之间进行交互一样。


0
投票

按住模块文件并将其拖到 chrome 开发控制台中。
请务必将其拖到控制台的输入行部分(

>
之后)。

(这适用于 Windows 10 下的 Chrome 78。)


0
投票

卡尔的回答对于我让模块在控制台中工作非常有帮助。但是,由于有充分的理由不在生产代码的模块中使用 window.*,所以我开始做的是:

  1. 在要导入的模块内放置断点。
  2. 当断点被击中时,在控制台中执行
    window.myModule = myModule;
  3. 删除断点并恢复。现在您可以随时在控制台中引用该模块。
© www.soinside.com 2019 - 2024. All rights reserved.