打字稿:SyntaxError:意外的令牌“导出”

Posted

技术标签:

【中文标题】打字稿:SyntaxError:意外的令牌“导出”【英文标题】:Typescript : SyntaxError: Unexpected token 'export' 【发布时间】:2020-09-14 23:18:27 【问题描述】:

在我的 React 项目中,我需要在 3 个打字稿项目之间共享模型(在我的例子中是打字稿接口)。所以我选择了 bit.env 并将我所有的模型导入到https://bit.dev/model/index/~code 并且一切都很好。

然后我需要验证模型中的字段,因此我将实用程序功能添加到 https://bit.dev/model/index/~code#util.ts 并将其部署到 bit.env

当我尝试在我的项目 #2(我保留 firebase 云函数的地方)中使用此辅助函数时,我开始遇到以下错误。

/Users/vinoth.gopu/Documents/mine/oss/Cloud/functions/node_modules/@bit/model.index/dist/index.js:1
export * from './admin';
^^^^^^

SyntaxError: Unexpected token 'export'
    at wrapSafe (internal/modules/cjs/loader.js:1101:16)
    at Module._compile (internal/modules/cjs/loader.js:1149:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1205:10)

我在项目 #2 中的代码

export const placeOrder = functions
    .runWith(
        memory:'256MB'
    )
    .region(cloudConfig.firebase.region)
    .firestore
    .document('Orders/OrderId')
    .onCreate((snap, context) => 
        const orderDetails = snap.data() as UserOrders;

        try 
            //check if all fields of interface implemented
            if(isOrder(orderDetails))  // PROBLEM HERE
                 //do something
            

正如上面代码中所指出的,我可以使用该模型项目中的所有接口,但辅助函数会抛出错误消息。

我参考了这些文章和链接

    Getting Unexpected Token Export https://medium.com/the-node-js-collection/an-update-on-es6-modules-in-node-js-42c958b890c

但它们似乎都不起作用(我也有点困惑哪个项目需要转译共享模型或项目#2 在我的情况下?)。我可以理解这是节点无法识别 ES6 模块并需要某种中间转译的问题。但我想知道所有具有类似export 语句的接口如何工作得很好。我想了解我在这里缺少什么。

【问题讨论】:

您使用的是什么版本的打字稿?如果有,请提供项目的本地版本,否则请提供全球版本? 3.9.3 在两个项目中 【参考方案1】:

NodeJS 默认使用 CommonJS 加载包的方式。使用较新版本的 NodeJS,您确实可以使用 .mjs 文件或告诉引擎项目是 a module-based project 来获得 javascript 的模块功能。

我不知道 FireBase 是否使用最新的 Node 版本,但这至少应该可以解释您看到该错误的原因。在 NodeJS 已经开始在 CommonJS 中包装东西之后很久,JS 就获得了对 Export 的支持,这就是实现它的原因。旧版支持几乎总是很痛苦。

您可以通过更改为 CommonJS 或按照链接的 NodeJS ESM 页面中概述的步骤来解决此问题。

至于为什么导出函数需要这个,而导出接口不需要,这是因为从 TS 编译成 JS 的接口是......什么都没有。字面上没什么。 JS 没有打字系统,所以当 TS 被编译时,任何不需要的东西都会被排除在编译到 JS 目标之外。

【讨论】:

是的,应该没问题。这应该告诉它编译为 CommonJS,然后它应该可以与 NodeJS 一起工作。 firebase.google.com/docs/functions/typescript 这可能会有所帮助 对于函数,我使用完全相同的格式。我尝试了上面提到的(添加 tsconfig 并设置 commonJS),但结果相同。我想知道的是,为什么相同的“导出”样式适用于接口,但不适用于简单的 const/function?谢谢罗伯特 接口是TS,编译时往往不包括在内,因为JS不需要它们。 更新的答案包括为什么接口没有被编译成 JS【参考方案2】:

似乎答案在 bit.dev 中

"bit": 
    "env": 
      "compiler": 
        "bit.envs/compilers/react-typescript@3.1.52": 
          "rawConfig": 
            "tsconfig": 
              "compilerOptions": 
                "target": "ES5",
                "module": "CommonJS"
              
            
          
        
      
    ,
    "componentsDefaultDirectory": "src/name",
    "packageManager": "npm"
  ,

通过处理转译解决了我的问题。

【讨论】:

以上是关于打字稿:SyntaxError:意外的令牌“导出”的主要内容,如果未能解决你的问题,请参考以下文章

意外的令牌 <Container> ,reactjs,打字稿

如何解决语法错误、意外令牌、导出类型?

“无法重新声明块范围的变量”和“SyntaxError:意外的令牌'导出'”[关闭]

开玩笑设置“SyntaxError:意外的令牌导出”

未捕获的 SyntaxError:意外的令牌导出 (Redux)

SyntaxError: 尝试使用 @babel/register 时意外的令牌导出