节点模块导入导致意外的令牌错误

时间:2019-12-04 13:27:52

标签: javascript node.js azure azure-web-app-service azure-webapps

我有一个使用WebSocket库(ws)的节点应用程序,并且能够在本地计算机上运行此应用程序。

但是,当我将其发布到Azure App Service时,对于相同的代码会出现以下错误。

我检查了两个节点都在运行相同版本的节点12.13.0,我已经完成了npm install,并且这些软件包看起来是相同的(无论如何,它们也都包含在内)。而且下面的错误实际上是在抱怨ws模块中的文件。

触发此错误的代码行是:var WebSocket = require('ws');

Wed Dec 04 2019 13:03:04 GMT+0000 (Coordinated Universal Time): Application has thrown an uncaught exception and is terminated:
SyntaxError: Unexpected token {
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (D:\home\site\wwwroot\node_modules\ws\index.js:3:19)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
Application has thrown an uncaught exception and is terminated:
SyntaxError: Unexpected token {
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (D:\home\site\wwwroot\node_modules\ws\index.js:3:19)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)

1 个答案:

答案 0 :(得分:0)

作为参考,我试图使GitHub存储库examples/server-stats/的示例websockets/ws适用于本地和Azure应用服务。

首先,我将所有源代码下载到本地计算机上,并在本地目录(如下图所示)中运行npm installnpm install ws

图1.示例server-stats的本地文件结构。

enter image description here

第二,我尝试使用命令node index.js直接运行它并遇到问题Error: Cannot find module '../..',然后我将文件index.js更改为以下代码。

const WebSocket = require('ws'); // The original content is `require('../..')`

然后,我运行node index.js并打开浏览器以查看结果,效果很好。

图2。server-stats在本地运行正常

enter image description here

众所周知,Azure App Service要求节点应用程序绑定代码process.env.PORT中的端口值并以web.config文件启动,因此我更改了index.js文件,并创建了一个web.config文件,其内容来自Kudu Wiki页面Using a custom web.config for Node apps,并使用index.js代替server.js,其代码如下。

  • index.js

    const port =  8080;
    
    server.listen(port, function() {
      console.log('Listening on http://localhost:'+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 server.js file is a node.js site to be handled by the iisnode module -->
          <add name="iisnode" path="index.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="^index.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="public{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="index.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 WebApp,如下图所示,在其Kudu控制台中查看。

图3.通过Kudu Console在Azure WebApp上的示例文件结构

enter image description here

在我为WEBSITE_NODE_DEFAULT_VERSION添加新的重新编码12.13.0Application settings后,

图4.通过WEBSITE_NODE_DEFAULT_VERSION中的Application settings设置节点运行时版本

enter image description here

我在浏览器中打开了它,它确实起作用了。

图5.对于具有默认设置的websocket功能,它不起作用

enter image description here

上面的结果有两个问题。

  1. 对于使用websocket的Web应用程序,需要在Web sockets中启用功能General settings

    图6.要在Web sockets中启用General settings

    enter image description here

  2. 默认情况下,Azure启用了SSL来进行HTTP访问,因此,对于wss文件中的Websocket URL,必须使用ws而不是public/index.html

    图7.使用wss代替ws中的public/index.html来在Azure App Service上启用SSL。

    enter image description here

最后,它可以在Azure App Service上运行。

enter image description here