如何在 windows server 2016 / IIS 上部署伺服器端渲染 (SSR) 反應應用程序(由 webpack 捆綁)
提醒一下:這是我第一次嘗試在自定義建構的 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>