【问题标题】:NODEJS - Error using 'import' with IISnodeNODEJS - 在 IISnode 中使用“导入”时出错
【发布时间】:2022-07-30 02:45:24
【问题描述】:

我在 nodeJs 中有一个应用程序,我正在尝试使用 ISSnode 通过 ISS 创建一个服务器。 通常使用 'require' 来创建 express 服务器,但有些库需要使用 'import'。

import express from "express";
var app = express();
const port = process.env.PORT
app.get('/', function (req, res) {
res.send('Express is working on IISNode!');
});
app.listen(port);

我在 package.json 中使用了“type”:“module”,并且还使用 .mjs 扩展名进行了测试,但是,每当我通过 IIS 启动服务器时,都会出现此消息:

应用程序抛出未捕获的异常并终止: 错误 [ERR_REQUIRE_ESM]:不支持来自 C:\Program Files\iisnode\interceptor.js 的 ES 模块 C:\Integrations\integrationTelegram\src\index.js 的 require()。 而是将 C:\Program Files\iisnode\interceptor.js 中 index.js 的 require 更改为在所有 CommonJS 模块中都可用的动态 import()。 在对象。 (C:\Program Files\iisnode\interceptor.js:210:1)

(function () {

    // refactor process.argv to determine the app entry point and remove the interceptor parameter

    var appFile;
    var newArgs = [];
    process.argv.forEach(function (item, index) {
        if (index === 2)
            appFile = item;
        if (index !== 1)
            newArgs.push(item);
    });

    process.argv = newArgs;

    // determine if logging is enabled

    if (process.env.IISNODE_LOGGINGENABLED != 1) {
        return;
    }

    var path = require('path')
        , fs = require('fs');

    // configuration

    var maxLogSize = (process.env.IISNODE_MAXLOGFILESIZEINKB || 128) * 1024;
    var maxTotalLogSize = (process.env.IISNODE_MAXTOTALLOGFILESIZEINKB || 1024) * 1024;
    var maxLogFiles = (+process.env.IISNODE_MAXLOGFILES) || 20;
    var relativeLogDirectory = process.env.IISNODE_logDirECTORY || 'iisnode';

    // polyfill node v0.7 fs.existsSync with node v0.6 path.existsSync

    var existsSync = fs.existsSync || path.existsSync;

    // determine the the abosolute log file directory

    var wwwroot = path.dirname(appFile);
    var logDir = path.resolve(wwwroot, relativeLogDirectory);

    // ensure the log directory structure exists

    var ensureDir = function (dir) {
        if (!existsSync(dir)) {

            ensureDir(path.dirname(dir));

            try {
                fs.mkdirSync(dir);
            }
            catch (e) {

                // check if directory was created in the meantime (by another process)

                if (!existsSync(dir))
                    throw e;
            }
        }
    };

    ensureDir(logDir);

    // generate index.html file

    var htmlTemplate = fs.readFileSync(path.resolve(__dirname, 'logs.template.html'), 'utf8');
    var indexFile = path.resolve(logDir, 'index.html');

    var updateIndexHtml = function () {
        var files = fs.readdirSync(logDir);
        var logFiles = [];

        files.forEach(function (file) {
            var match = file.match(/(.+)-(\d+)-(stderr|stdout)-(\d+)\.txt$/);
            if (match) {
                logFiles.push({
                    file: file,
                    computername: match[1],
                    pid: +match[2],
                    type: match[3],
                    created: +match[4]
                });
            }
        });

        var html = htmlTemplate.replace('[]; //##LOGFILES##', JSON.stringify(logFiles)).replace('0; //##LASTUPDATED##', new Date().getTime());

        try {
            fs.writeFileSync(indexFile, html);
        }
        catch (e) {
            // empty - might be a collistion with concurrent update of index.html from another process
        }
    };

    // make best effort to purge old logs if total size or file count exceeds quota

    var purgeOldLogs = function () {
        var files = fs.readdirSync(logDir);
        var stats = [];
        var totalsize = 0;

        files.forEach(function (file) {
            if (file !== 'index.html') {
                try {
                    var stat = fs.statSync(path.resolve(logDir, file));
                    if (stat.isFile()) {
                        stats.push(stat);
                        stat.file = file;
                        totalsize += stat.size;
                    }
                }
                catch (e) {
                    // empty - file might have been deleted by other process
                }
            }
        });

        if (totalsize > maxTotalLogSize || stats.length > maxLogFiles) {

            // keep deleting files from the least recently modified to the most recently modified until
            // the total size and number of log files gets within the respective quotas

            stats.sort(function (a, b) {
                return a.mtime.getTime() - b.mtime.getTime();
            });

            var totalCount = stats.length;

            stats.some(function (stat) {
                try {
                    fs.unlinkSync(path.resolve(logDir, stat.file));
                    totalsize -= stat.size;
                    totalCount--;
                }
                catch (e) {
                    // likely indicates the file is still in use; leave it alone
                }

                return totalsize <= maxTotalLogSize && totalCount <= maxLogFiles;
            });
        }
    };

    // intercept a stream

    var intercept = function (stream, type) {

        var currentLog;
        var currentSize;
        var currentLogCreated;

        var rolloverLog = function () {
            var now = new Date().getTime();
            var filename = process.env.COMPUTERNAME + '-' + process.pid + '-' + type + '-' + now + '.txt';
            currentLog = path.resolve(logDir, filename);
            currentSize = 0;
            currentLogCreated = false;
            purgeOldLogs();
        };

        rolloverLog(); // create a new log file

        var ensureBuffer = function (data, encoding) {
            if (Buffer.isBuffer(data)) {
                return data;
            }
            else {
                data = data.toString().replace(/\n/g, '\r\n');
                return new Buffer(data, typeof encoding === 'string' ? encoding : 'utf8');
            }
        };

        stream.write = stream.end = function (data, encoding) {
            var buffer = ensureBuffer(data, encoding);
            if (currentSize > maxLogSize) {
                rolloverLog();
            }

            if (!currentLogCreated) {
                fs.writeFileSync(currentLog, '', 'utf8');
                updateIndexHtml();
                currentLogCreated = true;
            }

            var f = fs.openSync(currentLog, 'a');
            currentSize += fs.writeSync(f, buffer, 0, buffer.length, currentSize);
            fs.closeSync(f);
        };
    };

    // intercept stdout and stderr

    intercept(process.stdout, 'stdout');
    intercept(process.stderr, 'stderr');

    // install uncaughtException handler such that we can trace the unhandled exception to stderr

    process.on('uncaughtException', function (e) {
        // only act on the uncaught exception if the app has not registered another handler
        if (1 === process.listeners('uncaughtException').length) {
            console.error('Application has thrown an uncaught exception and is terminated:\n' + (e.stack || (new Error(e).stack)));
            process.exit(1);
        }
    });

})();

// run the original application entry point

require(process.argv[1]);

我有什么遗漏吗?

我的 web.config:

<configuration>
    <system.webServer>

        <!-- indicates that the server.js file is a node.js application
        to be handled by the iisnode module -->

        <handlers>
            <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
        </handlers>

        <rewrite>
            <rules>
                <rule name="sendToNode">
                    <match url="/*" />
                    <action type="Rewrite" url="server.js" />
                </rule>
            </rules>
        </rewrite>

    </system.webServer>
</configuration>

【问题讨论】:

    标签: node.js iis iisnode


    【解决方案1】:

    您可以参考this这个问题的可能原因。

    node-fetch 的当前版本仅兼容 ESM 导入(使用 import),不兼容使用 require() 的 CommonJS 模块。

    您有以下选择需要解决:

    1. 将您的项目切换到 ESM 模块并使用 import fetch from 'node-fetch'; 加载它。

    2. 在最新版本的 nodejs 中,您可以使用 let fetch = await import('node-fetch') 将 ESM 模块动态导入 CommonJS 模块。

    3. 使用node-fetch 的v2 版本,它仍然支持加载require(),如文档中的here 所述。

    希望对你有帮助!

    【讨论】:

    • 亲爱的JennyDai,您好,非常感谢您的回复!但在这种情况下,我没有使用 node-fetch,我计划使用 Axios。事实上,我使用 ISSnode 通过 ISS 启动了一个快速服务器,一旦我访问 Root 路由,它就会返回此消息。
    • 您是否尝试过使用Axios,您得到了什么结果?错误是否仍然存在?
    • 我真的很想帮助你。请确保 IISnode 已正确安装,然后尝试重新发布您的应用程序,这里是安装 iisnode 的参考:harveywilliams.net/blog/installing-iisnode
    • 我还没有使用它,因为 IIS 服务器不接受 IMPORT。我做了IIS节点的安装,但还是一样。我不得不将整个项目更改为使用 require,这是我真的不想要的。但在那之后,我设法运行了服务器。不过还是谢谢
    【解决方案2】:

    这是 iisnode 中的一个错误,因为它似乎在模块成为规范之前就被放弃了。如果你进入 IIS 节点目录,你会看到 intercept.js 和

        require(process.argv[1]);
    

    如果你把它替换为

        require('child_process').spawn(process.arv[0], process.argv.slice(1));
    

    它会起作用的。这不是官方修复,因此可能会有其他副作用,但它解决了我的问题。太糟糕了,似乎没有人维护 iisnode。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-04
      • 2023-01-04
      • 2017-08-27
      • 1970-01-01
      • 1970-01-01
      • 2023-01-09
      • 2020-04-13
      • 2014-05-29
      相关资源
      最近更新 更多