Apenas um aviso: esta é a primeira vez que tento implantar um aplicativo react em um servidor Windows personalizado, mas consegui fazê-lo com sucesso no Heroku e no Linux (PM2), então sei que a arquitetura do aplicativo é suposta para funcionar corretamente.
O cenário:
Eu construí um servidor de hospedagem Windows Server 2016/64 bits para hospedar vários sites. Eu usei o VPS Contabo para fazer isso. Eu testei todos os recursos que deveriam funcionar, mesmo com outros aplicativos, como ASP.NET, PHP, certificados SSL e tudo está funcionando bem.
Quanto ao projeto node js específico que estou tentando hospedar neste servidor, ele consiste em 2 partes principais:
- Backend em node junto com um CMS, também desenvolvido em node/javascript.
Criei um espaço de hospedagem em um subdomínio para este e está funcionando perfeitamente, mesmo com o certificado SSL Let's Encrypt. Caso alguém queira acessá-lo, seria em: https://backendnode.fullstackwebdesigner.com/system
- Frontend na renderização do lado do servidor de reação.
É aqui que está ocorrendo o problema. Se alguém quiser acessá-lo, aqui está o link: https://fullstackwebdesigner.com/
Eu usei basicamente a mesma técnica para ambos:
- iisnode;
- Extensão de reescrita de URL;
- módulos de nó iis;
- configuração do arquivo web.config;
O problema:
Eu consegui carregar como um site, assim como fiz com o backend, mas o problema é que parece não carregar os arquivos CSS, imagens e assim por diante. Portanto, o layout não carrega. No console, há uma mensagem de erro:
Uncaught SyntaxError: Unexpected token '<'
O aplicativo react: Como eu disse antes, ele foi feito como um aplicativo de renderização do lado do servidor e empacotado com o webpack. Portanto, ele compila os arquivos agrupados em um diretório chamado “/build”. E neste diretório, há um diretório “/public” onde estão todos os ativos, como arquivos CSS e imagens.
Durante o desenvolvimento, eu executaria a compilação no terminal como: node build/bundle.react.js
E por mais estranho que pareça, quando executo isso no terminal do servidor windows, funciona perfeitamente. Mas só pode ser acessado através de: http://localhost:3001 Carrega tudo o que é suposto carregar.
Aqui está uma representação simplificada da estrutura do arquivo:
- /build/
--bundle.react.js
--/build/public/
---/files-layout/
---/fonts/
---bundle.react.client.js
Aqui está também o arquivo web.config que estou usando no espaço de hospedagem do site para a compilação do react:
<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>
Alguém tem alguma idéia do que pode estar faltando ou acontecendo, já que não houve muitas referências sobre a renderização do lado do servidor de hospedagem no servidor Windows na web? Talvez uma configuração extra no IIS, web.config ou no espaço de hospedagem do site?
Editar:
Um teste interessante que acabei de fazer: no meu computador de desenvolvimento local, quando executo pelo terminal:
node bundle.react.js
de dentro da pasta /build, recebo o mesmo resultado do problema que está acontecendo online (sem layout, estilos, imagens e assim por diante).
Mas quando eu corro pelo terminal:
node build/bundle.react.js
de fora da pasta /build (do diretório base), ele carrega perfeitamente.
Em mais coisa. Os diretórios base são organizados assim:
…(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)
Suponho que haja algum tipo de problema ao referenciar a pasta /node_modules por causa de como escrevi o arquivo web.config, mas não tenho idéia de como fazer referência a ele.
Deu pra funcionar! O link a seguir me ajudou a fazer os ajustes finais, junto com o teste que fiz: https://www.thecodehubs.com/how-to-deploy-ssr-angular-universal-to-iis/
Resumindo, acabei tendo que copiar o pacote do servidor para o diretório raiz. E altere o arquivo web.config para chamar o arquivo raiz. Veja como ficou o arquivo web.config, junto com mais algumas configurações que achei interessantes no link que postei (não testei ainda sem a configuração extra):