我正在使用 React、Next JS 和样式组件。现在我已遵循文档并具有以下文件结构。我只想让全局 CSS 在静态 HTML 页面上工作。我预计 Next JS 的 SSG 能够正常工作。请不要告诉我使用服务器。我知道这很容易解决。我想在从文件资源管理器打开的本地静态页面上实现此功能。
pages/
_app.tsx
_document.tsx
index.tsx
styles/core.css
我非常简单地在我的 _app.tsx 中导入 core.css
import { AppProps } from 'next/app';
import '../styles/core.css';
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
export default MyApp;
现在,当我通过 SSG 生成页面(我不想使用服务器)时,生成的 HTML 文件中有这两行
<link rel="preload" href="/_next/static/css/4da684a704d068a3.css" as="style" crossorigin=""/>
<link rel="stylesheet" href="/_next/static/css/4da684a704d068a3.css" crossorigin="" data-n-g=""/>
当我打开index.html时,控制台显示此错误
Access to CSS stylesheet at 'file:///C:/_next/static/css/4da684a704d068a3.css' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome-untrusted, https, edge.
如何解决这个问题?将 HTML 行更改为
<link rel="stylesheet" href="_next/static/css/4da684a704d068a3.css">
让它发挥作用。请帮忙,我在网上找不到任何东西。
这是我的 _document.tsx 如果有帮助的话
import Document, { Head, Html, Main, NextScript, DocumentContext, DocumentInitialProps } from 'next/document'
import { ServerStyleSheet } from 'styled-components'
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () => originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}
}
这是我的配置
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: 'export',
compiler: {
styledComponents: true,
},
}
module.exports = nextConfig
我希望有更好的解决方案。如果其他人遇到同样的利基问题,这就是我最终要做的事情。
const fs = require('fs');
const cheerio = require('cheerio');
// Read the generated HTML file
const html = fs.readFileSync('./out/target.html', 'utf8');
// Load the HTML into cheerio
const $ = cheerio.load(html);
// Find all <link> tags with crossorigin attribute and remove it
$('link[crossorigin]').removeAttr('crossorigin');
$('script[crossorigin]').removeAttr('crossorigin');
// Write the modified HTML back to the file
fs.writeFileSync('./out/target.html', $.html(), 'utf8');
每当构建时我都会运行这个 JS 文件。
next build && node ./scripts/modify_html.js