[英]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.