将NextJs托管到IIS

时间:2019-03-03 02:36:57

标签: node.js iis next.js iisnode

美好的一天!

我的同事有一个网站node.js(next.js),当我们通过控制台构建和启动(npm run build和npm start)时,他的网站运行良好。

我们已将其托管在Azure VM(已安装Windows Server 2016 IIS,iisnode和urlrewrite)中,我们创建了管道,并能够获取构件(运行构建时为“ .next”文件夹)并进行部署到IIS,但是我们仍然需要手动交互才能放置web.config。下面是web.config

  

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

<handlers>
  <add name="iisnode" path="service-worker.js" verb="*" modules="iisnode" />
</handlers>

<!-- use URL rewriting to redirect the entire branch of the URL namespace
to hello.js node.js application; for example, the following URLs will 
all be handled by hello.js:

    http://localhost/node/express/myapp/foo
    http://localhost/node/express/myapp/bar

-->

<rewrite>
  <rules>
    <rule name="AMS" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
  </rules>
</rewrite> 

但是,当我们访问该网站时,它会引发403错误,需要提供默认页面。 (我在这里迷路了,无法通过IIS运行他的网站)

注意:他的其他网站正常工作(因为它具有service-worker.js)。

有没有将Next.JS部署到IIS的经验?预先感谢。

1 个答案:

答案 0 :(得分:0)

在/ public文件夹中,创建以下web.config来接受来自/ a / b / c的请求,并将其重写为/,以保存我们的NextJs代码。

<?xml version="1.0"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="NextJs Routes" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />                            
                    </conditions>
                    <action type="Rewrite" url="/" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

只需执行此操作,您就可以在/ products之类的路由上重新加载页面,但是NextJs会呈现/,即索引页面,因为这是我们的重写规则要求它传递的内容。

因此,我们需要创建一个以NextRouter作为道具的主体组件,然后将窗口的网址与路由器的网址进行比较。如果它们不匹配,则需要使用router.push()更改客户端路由。

我正在使用TypeScript,所以我的body.tsx

import * as React from 'react';
import { NextRouter } from 'next/router';

export default class Body extends React.Component<{router : NextRouter}>
{    
    componentDidMount()
    {        
        if (window.location.pathname == this.props.router.pathname) return;
        
        this.props.router.push(global.window.location.pathname);        
    }

    render = () => this.props.children;                
}

然后在_app.tsx中,我们只需要将主体组件包装在主体组件中即可。

import { useRouter } from 'next/router'
import Head from 'next/head';
import Body from '../src/components/elements/body';

function MyApp({ Component, pageProps }) {

    const router = useRouter();        
        
    return (
        <>
            <Head>                
                <title>NextJs on IIS</title>
            </Head>

            <Body router={router}>                                
                <Component {...pageProps} />                                
            </Body>
        </>
    )
}

export default MyApp

运行npm run build,然后将/ out文件夹复制到IIS服务器。