node.js - 将 NextJs 托管到 IIS
问题描述
再会!
我的同事有一个网站 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 的经验?提前致谢。
解决方案
在 /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 作为 prop 的 body 组件,然后将窗口的 url 与路由器的 url 进行比较。如果它们不匹配,我们需要使用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 中,我们只需要将 main Component 包装在 Body Component 中。
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 服务器。
推荐阅读
- c# - 在 linq 中计算组上的行号并仅采用行号为 1 的行号?
- angular - 如何在 Angular 6 Frontend 上显示存储在 laravel .env 配置路径中的图像?
- r - 使用 ncdf4 包将大型数组写入 NetCDF 文件时,R 会话卡住
- powershell - 如何为经过身份验证的用户授予具有 powershell 的文件夹的完全权限
- javascript - 如何使用 ngfor 迭代对象
- java - 如何将目标添加到 captureRequestBuilder 以及如何处理每一帧?
- javascript - Firebase 云功能 - 如何获取模型数据
- google-maps - 无法解析模块“react-native-google-place-picker”
- dax - DAX WeekNum 超过 1 年?
- xamarin.forms - 在默认的空白应用程序中找不到命名空间“应用程序”