簡體   English   中英

從 nestjs 中的另一個工作區項目編譯代碼 api - 意外的令牌“導出”

[英]Compiling code from another workspace project in a nestjs api - Unexpected token 'export'

我正在嘗試創建一個包含 NestJs API、React 應用程序以及它們之間共享的許多其他較小項目的 monorepo

monorepo 設置了 yarn workspaces

使用 Vite 的 React 應用程序可以完美地導入和編譯常見項目,但 NestJs api 永遠無法編譯,通常會出現SyntaxError: Unexpected token 'export'錯誤。

我用一個基本的 Nest 項目和一個公共文件夾創建了一個最小的存儲庫,以嘗試使用以下結構獲取單個 function 導入:

.
├── common                  # Sample common project
│   ├── tsconfig         
│   ├── src        
│   │   └── test.ts         # The file called from the api
│   └── package.json   
├── api                     # NestJs API
│   ├── tsconfig      
│   ├── src        
│   └── package.json             
└── package.json            # Yarn workspace setup

主要package.json:

{
    "name": "mono",
    "workspaces": [
        "common",
        "api"
    ]
}

普通package.json

{
    "name": "@test/common",
    "version": "1.0.0",
    "main": "index.ts"
}

常見的tsconfig

{
  "compilerOptions": {
    "module": "CommonJS",
    "allowSyntheticDefaultImports": true,
    "baseUrl": ".",
    "esModuleInterop": true,
    "composite": true,
    "sourceMap": true,
    "declaration": true,
    "declarationMap": true
  }
}

及其在 src/test.ts 中的復雜測試 function

export const hi = () => 'Hello there';

這是我稱之為 function 的main.ts文件:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { hi } from '@test/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  console.log('All fine', hi());
}
bootstrap();

api package.json

{
  "name": "api",
  "scripts": {
    "start": "nest start",
    ...other commands
  },
  "dependencies": {
    "@nestjs/common": "^9.0.0",
    "@nestjs/core": "^9.0.0",
    "@nestjs/platform-express": "^9.0.0",
    "@test/common": "*",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.2.0",
    "webpack-node-externals": "^3.0.0"
  },
  "devDependencies": {
    ...nest deps
    "ts-jest": "29.0.3",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.0.0",
    "tsconfig-paths": "4.1.1",
    "typescript": "^4.7.4"
  },
  "jest": {
    ...jest config
  }
}

還有api的tsconfig

{
  "compilerOptions": {
    "module": "CommonJS",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
  },
  "include": [
    "../common",
    "./src/*"
  ],
  "references": [
    {
      "path": "../common"
    }
  ],
  "paths": {
    "@test/common/*": [
      "../common/*"
    ]
  }
}

在 nest 項目上運行yarn run start時,生成的dist文件夾似乎包含正確的文件結構:

分布式結構

但是一次又一次地導致同樣的錯誤

C:\<path>\MonoNest\api>yarn run start
yarn run v1.22.19
$ nest start
C:\<path>\MonoNest\common\index.ts:1
export * from './src/test';
^^^^^^

SyntaxError: Unexpected token 'export'
    at Object.compileFunction (node:vm:360:18)
    at wrapSafe (node:internal/modules/cjs/loader:1088:15)
    at Module._compile (node:internal/modules/cjs/loader:1123:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (C:\<path>\MonoNest\api\src\main.ts:3:1)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

極簡復現項目可以在Github上獲得,如果你想測試的話

為了清楚起見,我正在嘗試制作一個“真正的”monorepo,其中父文件夾僅包含不同項目的路徑。

我對“官方”nestjs monorepo 文檔不感興趣,它使根存儲庫包含我在其他項目中不需要的大多數 nestjs 包和配置

拋出錯誤是因為您將@test/common放在node_modules中,而沒有將ts文件編譯成js

輸入命令yarn run start后,引擎將 typescript 個文件編譯為 javascript,對於node_modules中的包,編譯是之前完成的。 有關發布 ts 模塊的更多信息。

因此,在編譯之后,javascript 發現有一些來自 typescript 的未知語法沒有編譯到 javascript 中。

所以你需要編譯你的 package 然后使用它。

您有一些選項可以解決此問題:

  1. 將主文件中的導入路徑更改為:
// main.ts
import { hi } from '../../common';
  1. 如果您需要 package 作為依賴項的一部分,但它不存在於 npm 中,那么您需要使用Local paths

從版本 2.0.0 開始,您可以提供包含 package 的本地目錄的路徑。

它會是這樣的:

npm install --save ../path/to/mymodule

使用紗線:

// relative path
yarn add file:./../your-project
// absolute path
yarn add file:/dev/your-project

只是為了看看你的項目是如何工作的,你可以手動構建common模塊,將package.json中的鍵main的值更改為"main": "./path/to/index.js"然后將其移動到你的node_modules中。 (不推薦,只是讓你知道。最后一切都必須是 javascript 才能正常工作。)

這是因為您正嘗試在非純 ESM 的項目中使用純 ESM package。 有時會有變通方法,例如使用模塊名稱映射器(在 Jest 中)。 其他時候……沒有。 您可以嘗試制作您的 package Pure ESM,這會起作用……但我對該過程不夠熟悉,無法提供任何幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM