【问题标题】:ES6 import error handlingES6 导入错误处理
【发布时间】:2016-08-14 20:03:57
【问题描述】:

我目前正在使用 Babel。

我之前使用require 做过以下操作:

try {  
    var myModule = require('my-module');
} catch (err) {
    // send error to log file
}

但是,当尝试使用 import 执行此操作时:

try {  
    import myModule from 'my-module';
} catch (err) {
    // send error to log file
}

我得到错误:

'import' 和 'export' 只能出现在顶层

现在我知道importrequire 不同。从阅读Are ES6 module imports hoisted?import提升,这意味着导入在代码执行之前加载。

我之前所做的是,如果任何要求失败,则会创建一个日志,该日志会通过电子邮件提醒我(将日志发送到 logstash 等)。所以我的问题归结为以下几点。

如何在 nodejs 中以一种良好的实践方式处理导入错误?这样的事情存在吗?

【问题讨论】:

  • 你用过 Babel 吗?
  • @Tugrul 啊,是的,我应该提到这一点。
  • 我现在没有问题了:)
  • 我认为如果你需要有条件地加载模块(或者需要在加载时捕获错误),你必须坚持使用require()。另请参阅this question and its answers
  • 尝试查看System.import,虽然它没有在 babel 中实现

标签: node.js


【解决方案1】:

您无法捕获 静态导入 错误(参见 Boris 的回答)

不过,您可以为此使用动态 import()

现在是 supported by all evergreen browsers & Node,是标准 since ES2020 的一部分。

class ImportError extends Error {}

const loadModule = async (modulePath) => {
  try {
    return await import(modulePath)
  } catch (e) {
    throw new ImportError(`Unable to import module ${modulePath}`)
  }
}

【讨论】:

  • 动态 import() 返回一个 Promise,因此您也可以使用 Promise 样式处理错误:import(modulePath).catch(e => Promise.reject("Module " + modulePath + " not found.")).then(module => { /* use module here */ console.log(module); })。另见stackoverflow.com/a/47755315/341201
【解决方案2】:

[2021 年编辑]查看Caveman answer 以获得允许进行动态导入

的最新答案

这个谈话放弃它:https://github.com/ModuleLoader/es-module-loader/issues/280 并同意你所说的。

import 仅适用于基础级别。它们是静态的并且总是加载 在模块运行之前。

所以你不能做代码检查。

但是,好消息是,由于它是静态的,因此可以进行分析,像 webpack 这样的工具会在构建时抛出错误。

【讨论】:

  • 请注意,此答案不再完全正确:您不能对静态导入执行此操作,但您可以dynamic imports 执行此操作,这会返回您可以执行的承诺.catch() 在 Promise 链中,或者 try await/catch 如果你在异步函数中。
【解决方案3】:

补充dynamic import.

class ImportError extends Error {}

const loadModule = async (modulePath) => {
  try {
    return await import(modulePath)
  } catch (e) {
    throw new ImportError(`Unable to import module ${modulePath}`)
  }
}

async function main() {
  // import myDefault, {foo, bar} from '/modules/my-module.js'
  const { default: myDefault, foo, bar } = await loadModule('/modules/my-module.js')
}

chained_promises

import("/modules/my-module.js").then(module=>{
  module.foo()
  module.bar()
}).catch(err=>
  console.log(err.message)
)

Destructuring assignment

import("/modules/my-module.js").then(({foo, bar})=>{
  foo()
  bar()
}).catch(err=>
  console.log(err.message)
)

【讨论】:

    【解决方案4】:

    由于云服务正在成为常态,现在对此的一个非常现代的答案是让导入失败并记录到 stderr,因为云服务从 stderr 到其日志记录服务的日志。所以基本上你不需要做任何事情。

    【讨论】:

      猜你喜欢
      • 2019-01-05
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 2017-06-29
      • 2015-02-25
      • 2011-03-09
      • 1970-01-01
      • 2017-12-30
      相关资源
      最近更新 更多