Iis

如何在 windows server 2016 / IIS 上部署伺服器端渲染 (SSR) 反應應用程序(由 webpack 捆綁)

  • October 24, 2021

提醒一下:這是我第一次嘗試在自定義建構的 Windows 伺服器上部署 react 應用程序,但我已經成功地在 Heroku 和 Linux (PM2) 上完成了它,所以我知道應用程序架構是假設的正常工作。

場景:

我已經建構了一個 Windows Server 2016 / 64 位託管伺服器來託管多個網站。我已經使用 VPS Contabo 來做到這一點。我已經測試了所有應該工作的功能,即使是其他應用程序,如 ASP.NET、PHP、SSL 證書,一切都執行良好。

至於我試圖在此伺服器上託管的特定節點 js 項目,它由 2 個主要部分組成:

  • node 中的後端與 CMS 一起使用 node / javascript 開發。

我為此在子域上創建了一個託管空間,它執行良好,即使使用 Let’s Encrypt SSL 證書也是如此。如果有人想訪問它,請訪問: https ://backendnode.fullstackwebdesigner.com/system

  • 反應伺服器端渲染中的前端。

這就是問題發生的地方。如果有人想訪問它,這裡是連結: https ://fullstackwebdesigner.com/

我對它們都使用了基本相同的技術:

  • iis節點;
  • URL重寫擴展;
  • iis節點模組;
  • web.config 文件配置;

問題:

我已經設法讓它作為一個網站載入,就像我對後端所做的那樣,但問題是它似乎沒有載入 CSS 文件、圖像等。所以佈局不會載入。在控制台上,有錯誤消息: Uncaught SyntaxError: Unexpected token '<'

react 應用程序:正如我之前所說,它是作為伺服器端渲染應用程序完成的,並與 webpack 捆綁在一起。因此,它將捆綁的文件建構到名為“/build”的目錄中。在這個目錄中,有一個“/public”目錄,所有資產都在其中,例如 CSS 文件和圖像。

在開發時,我會在終端上執行建構:node build/bundle.react.js

儘管看起來很奇怪,但當我在 Windows 伺服器的終端上執行它時,它執行良好。但只能通過以下方式訪問:http://localhost:3001 它會載入所有應該載入的內容。

這是文件結構的簡化表示:

- /build/
--bundle.react.js
--/build/public/
---/files-layout/
---/fonts/
---bundle.react.client.js

這也是我在網站託管空間上用於反應建構的 web.config 文件:

<configuration>
   <system.webServer>
       <iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" />
       
       <handlers>
           <add name="iisnode" path="/build/bundle.react.js" verb="*" modules="iisnode" />
       </handlers>

       <rewrite>
           <rules>
               <!-- Redirect to HTTPS (alternative). -->
               <rule name="Redirect to HTTPS / SSL" stopProcessing="true">
                   <match url="(.*)" />
                   <conditions>
                       <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                   </conditions>
                   <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
               </rule>

               <!-- Don't interfere with requests for logs. -->
               <rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
                   <match url="^[a-zA-Z0-9_\-]+\.js\.logs\/\d+\.txt$" />
               </rule> 
               <!-- Node. -->
               <rule name="sendToNode">
                   <match url="(.*)" />
                   <conditions>
                       <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                   </conditions>
                   <action type="Rewrite" url="/build/bundle.react.js" />          
               </rule>
           </rules>    
       </rewrite> 
       <defaultDocument>
           <files>
               <clear />
               <add value="/build/bundle.react.js" />
           </files>
       </defaultDocument>
       <security>
           <requestFiltering>
               <hiddenSegments>
                   <add segment="node_modules" />
               </hiddenSegments>
           </requestFiltering>
       </security>
   </system.webServer>
   <system.web>
       <compilation defaultLanguage="js" />
   </system.web>
</configuration>

任何人都知道可能缺少什麼或正在發生什麼,因為在 web 上的 windows 伺服器上託管伺服器端渲染的參考文獻不多?可能是 IIS、web.config 或網站託管空間上的額外配置?

編輯:

我剛剛做了一個有趣的測試:在我的本地開發電腦上,當我通過終端執行時:

node bundle.react.js

從 /build 文件夾中,我得到與線上發生的問題相同的結果(沒有佈局、樣式、圖像等)。

但是當我通過終端執行時:

node build/bundle.react.js

從 /build 文件夾外部(從基本目錄),它可以完美載入。

關於更多的事情。基本目錄的組織方式如下:

…(some folders)
- /build/
--bundle.react.js
--/build/public/
---/files-layout/
---/fonts/
---bundle.react.client.js
-node_modules
…(some root files, like webpack and so on)

我猜由於我如何編寫 web.config 文件,引用 /node_modules 文件夾存在某種問題,但我不知道應該如何引用它。

讓它工作!以下連結幫助我進行了最後的調整,以及我所做的測試: https ://www.thecodehubs.com/how-to-deploy-ssr-angular-universal-to-iis/

總結起來,我不得不將伺服器包複製到根目錄。並更改 web.config 文件以呼叫根文件。以下是 web.config 文件的最終結果,以及我在發布的連結中發現的一些有趣的配置(沒有額外配置尚未測試):

<configuration>
   <system.webServer>
       <iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" />
       
       <handlers>
           <add name="iisnode" path="bundle.react.js" verb="*" modules="iisnode" />
       </handlers>

       <rewrite>
           <rules>
               <!-- Redirect to HTTPS. -->
               <rule name="Redirect to HTTPS / SSL" stopProcessing="true">
                   <match url="(.*)" />
                   <conditions>
                       <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                   </conditions>
                   <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
               </rule>

               <!-- Don't interfere with requests for logs. -->
               <rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
                   <match url="^[a-zA-Z0-9_\-]+\.js\.logs\/\d+\.txt$" />
               </rule>
               
               <!-- Node. -->
               <rule name="sendToNode">
                   <match url="(.*)" />
                   <conditions>
                       <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                   </conditions>
                   <action type="Rewrite" url="bundle.react.js" />
               </rule>
               
               <rule name="StaticContent" stopProcessing="true">
                 <match url="([\S]+[.](jpg|jpeg|gif|css|png|js|ts|cscc|less|ico|html|map|svg))" />
                 <action type="None" />
               </rule>
           </rules>
       </rewrite> 
       
       <staticContent>
           <clientCache cacheControlMode="UseMaxAge" />
           <remove fileExtension=".svg" />
           <remove fileExtension=".eot" />
           <remove fileExtension=".ttf" />
           <remove fileExtension=".woff" />
           <remove fileExtension=".woff2" />
           <remove fileExtension=".otf" />
           <mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
           <mimeMap fileExtension=".svg" mimeType="image/svg+xml"  />
           <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
           <mimeMap fileExtension=".woff" mimeType="application/x-woff" />
           <mimeMap fileExtension=".woff2" mimeType="application/x-woff" />
           <mimeMap fileExtension=".otf" mimeType="application/otf" />
       </staticContent>
       
       
       <defaultDocument>
           <files>
               <clear />
               <add value="bundle.react.js" />
           </files>
       </defaultDocument>

       <security>
         <requestFiltering>
           <hiddenSegments>
             <add segment="node_modules" />
             <!--add segment="iisnode" /-->
           </hiddenSegments>
         </requestFiltering>
       </security>
   </system.webServer>
   <system.web>
       <compilation defaultLanguage="js" />
   </system.web>
</configuration>

引用自:https://serverfault.com/questions/1081546