簡體   English   中英

無法啟動使用 ES 模塊的 Node.js 應用程序

[英]Unable to start Node.js application that uses ES module

我有一個簡單的 Node.js 16.x應用程序。 它使用 ES 模塊,所以我在package.json中有"type": "module" 每當我使用npm腳本時,一切正常。

Now I'm trying to deploy it using Docker and I don't need the npm scripts anymore, so I'm starting the application directly using the node binary, in the same way I declared it within package.json : node --require dotenv/config main.js ...但這不起作用,它會失敗,並顯示圍繞 ES 模塊的典型錯誤消息,例如:

(node:9) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/opt/application/main.js:1
import { app } from "./application.js";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1031:15)
    at Module._compile (node:internal/modules/cjs/loader:1065:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47

我還嘗試了圍繞此命令的設置組合: node --input-type=module --experimental-modules --require dotenv/config main.js 按照本指南進行操作,但仍然遇到相同的錯誤信息。

我想我在這里遺漏了一些瑣碎的事情,所以我的問題是:如何在不使用package.json情況下啟動此應用程序(因為此時我將不再擁有它)或將.js文件重命名為.mjs ,通過使用只有node二進制?


這是應用程序在文件系統中的樣子(如果有什么不同的話):

/opt/application # ls -ltr 
total 72
-rw-r--r--    1 root     root          2158 Oct 10 13:47 application.js
drwxr-xr-x    2 root     root          4096 Jan 27 14:57 support
-rw-r--r--    1 root     root           318 Jan 27 14:57 main.js
drwxr-xr-x    2 root     root          4096 Jan 27 14:57 handler
drwxr-xr-x    2 root     root          4096 Jan 27 14:57 config
-rw-r--r--    1 root     root          1448 Jan 27 14:58 knexfile.js
drwxr-xr-x    2 root     root          4096 Jan 27 16:57 service
drwxr-xr-x    2 root     root          4096 Jan 27 16:57 model
-rw-r--r--    1 root     root         28672 Jan 27 16:57 production.sqlite3
drwxr-xr-x  228 root     root         12288 Jan 27 16:57 node_modules
/opt/application # cat main.js 
import { app } from "./application.js";
import { logger } from "./config/winston.js";
import { SERVER_PORT } from "./support/constants.js";

const port = process.env.PORT || SERVER_PORT;

app.listen(port, () => {
  logger.debug(`Server running at http://localhost:${port}`);
  logger.info("Press CTRL-C to stop");
});

這是package.json文件的(摘錄):

{
  "name": "node-express",
  "private": true,
  "type": "module",
  "scripts": {
    "develop": "nodemon --require dotenv/config src/server.js",
    "start": "node --require dotenv/config src/server.js",
    "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
  },
  "dependencies": {
    "compression": "1.7.4",
    "dotenv": "10.0.0",
    "errorhandler": "1.5.1",
    "express": "4.17.1",
    "helmet": "4.6.0",
    "http-status-codes": "2.1.4",
    "lusca": "1.7.0",
    "knex": "0.95.11",
    "morgan": "1.10.0",
    "objection": "2.2.16",
    "sqlite3": "5.0.2",
    "uuid": "8.3.2",
    "winston": "3.3.3"
  },
  "devDependencies": {
    "@jest/globals": "27.2.1",
    "cross-env": "7.0.3",
    "eslint-config-prettier": "8.3.0",
    "eslint-config-recommended": "4.1.0",
    "eslint-plugin-jest": "24.4.2",
    "eslint-plugin-prettier": "4.0.0",
    "eslint": "7.32.0",
    "jest": "27.2.1",
    "npm-run-all": "4.1.5",
    "nodemon": "2.0.12",
    "prettier": "2.4.1",
    "supertest": "6.1.6"
  },
  "engines": {
    "node": "16.x"
  },
  "jest": {
    "collectCoverage": true,
    "clearMocks": true,
    "setupFiles": [
      "dotenv/config"
    ],
    "verbose": true
  },
  "nodemonConfig": {
    "ignore": [
      "*.test.js"
    ],
    "watch": [
      "src/*"
    ]
  }
}

不幸的是,您嘗試做的事情是不可能的。 節點文檔

Node.js 在作為初始輸入傳遞給節點時,或者在 ES 模塊代碼中的 import 語句引用時,會將以下內容視為 ES 模塊:

  • .mjs結尾的文件。

  • 當最近的父package.json文件包含值為"module"的頂級"type"字段時,以.js結尾的文件。

  • 字符串作為參數傳遞給--eval ,或通過STDIN管道傳遞到node ,帶有標志--input-type=module

如果可能,您應該只復制package.json中的 package.json - 這就是 Node 所期望的。

否則,如果你的 Docker 圖像中絕對不能有package.json ,那么node --input-type module --require dotenv/config < main.js應該做的技巧

暫無
暫無

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

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