Azure部署Node.js应用时ERR_REQUIRE_ESM错误求助
Node.js ES模块部署Azure App Service(Windows)报错:ERR_REQUIRE_ESM
应用抛出未捕获异常并终止:Error [ERR_REQUIRE_ESM]: 不支持从C:\Program Files (x86)\iisnode\interceptor.js中使用require()加载ES模块C:\home\site\wwwroot\app.js。请将C:\Program Files (x86)\iisnode\interceptor.js中对app.js的require改为所有CommonJS模块均支持的动态import()。位于Object. (C:\Program Files (x86)\iisnode\interceptor.js:459:1)
已完成package.json添加"type": "module"、将require改为import的操作,但找不到iisnode文件夹及interceptor.js文件。部署遵循官方Node.js快速入门指南(Windows环境)。
相关配置文件
package.json
{ "name": "my-express-app", "version": "0.0.0", "private": true, "scripts": { "start": "node app.js" }, "type": "module", "description": "my-express-app", "author": { "name": "" }, "dependencies": { "@azure/msal-node": "^1.16.0", "axios": "^1.3.4", "body-parser": "^1.15.0", "cookie-parser": "^1.4.0", "cors": "^2.8.5", "dotenv": "^16.0.3", "express": "^4.14.0", "morgan": "^1.7.0", "nodemon": "^2.0.20", "pug": "^3.0.2", "serve-favicon": "^2.3.0", "tedious": "^15.1.2", "tedious-connection-pool": "^1.0.5" } }
app.js
import express from "express"; import logger from "morgan"; import cookieParser from "cookie-parser"; import bodyParser from "body-parser"; import * as checkResource from "./middleware/checkResource.js"; import { setError } from "./middleware/error.js"; import cors from "cors"; import { router as routes_Admin } from "./controllers/admin.js"; import { resolve } from "path"; export var app = express(); // middlewares app.use(checkResource.check); app.use(setError); app.use("/static", express.static("public")); app.use(express.json()); app.use(cors()); //controllers; app.use(routes_Admin); app.use(logger("dev")); app.use(bodyParser.json()); app.use(cookieParser()); app.set("port", process.env.PORT || 3000); app.get("/", (req, res) => { console.log("Hello World!"); res.send("Hello world!"); }); app.listen(app.get("port"), () => {});
web.config
<?xml version="1.0" encoding="utf-8"?> <!-- This configuration file is required if iisnode is used to run node processes behind IIS or IIS Express. For more information, visit: https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config --> <configuration> <system.webServer> <!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support --> <webSocket enabled="false" /> <handlers> <!-- Indicates that the app.js file is a node.js site to be handled by the iisnode module --> <add name="iisnode" path="app.js" verb="*" modules="iisnode"/> </handlers> <rewrite> <rules> <!-- Do not interfere with requests for node-inspector debugging --> <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true"> <match url="^app.js\/debug[\/]?" /> </rule> <!-- First we consider whether the incoming URL matches a physical file in the /public folder --> <rule name="StaticContent"> <action type="Rewrite" url="{REQUEST_URI}"/> </rule> <!-- All other URLs are mapped to the node.js site entry point --> <rule name="DynamicContent"> <conditions> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/> </conditions> <action type="Rewrite" url="app.js"/> </rule> </rules> </rewrite> <!-- 'bin' directory has no special meaning in node.js and apps can be placed in it --> <security> <requestFiltering> <hiddenSegments> <remove segment="bin"/> </hiddenSegments> </requestFiltering> </security> <!-- Make sure error responses are left untouched --> <httpErrors existingResponse="PassThrough" /> <!-- You can control how Node is hosted within IIS using the following options: * watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server * node_env: will be propagated to node as NODE_ENV environment variable * debuggingEnabled - controls whether the built-in debugger is enabled See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options --> <!--<iisnode watchedFiles="web.config;*.js"/>--> </system.webServer> </configuration>
解决方案
- 改用Azure App Service Linux环境:Windows环境依赖的iisnode模块不支持ES模块的
import语法,Linux环境直接通过Node.js进程启动应用,规避iisnode的限制。部署时选择Linux操作系统的App Service计划,重新部署即可。 - 修改web.config,绕过iisnode直接启动Node进程:如果必须使用Windows环境,修改web.config中的handler配置,替换iisnode模块为直接调用node.exe:
注意:需要确保Azure App Service的Windows环境已安装对应版本的Node.js,并且<handlers> <add name="nodejs" path="app.js" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" /> </handlers> <httpPlatform processPath="%programfiles%\nodejs\node.exe" arguments=".\app.js" stdoutLogEnabled="true" stdoutLogFile=".\node.log" startupTimeLimit="30" />processPath指向正确的node.exe路径。 - 降级为CommonJS模块:如果上述方案不可行,将
package.json中的"type": "module"移除,把所有import改回require语法,适配iisnode的CommonJS加载方式。
内容的提问来源于stack exchange,提问作者Gello
相关产品推荐
相关产品推荐

