Next.js 加载 <script> 标签但不执行它们
Next.js Loads <script> tags but it doesn't execute them
我正在将现有的 React 应用程序集成到 Next.js 中,主要用于 SEO 功能。
我将 css 文件链接粘贴到 Next.js
中的 <Header>
标签内,它们似乎工作正常。当我尝试使用 <script>
标记对 javascript 文件执行相同操作时,它不会执行这些脚本中的代码。但我可以在 chrome 开发工具中看到它们加载了 http 200
。
我尝试使用 npm
中名为 Loadjs
的库来加载 componentDidMount
中的脚本,但我得到的结果与使用 <script>
标签完全相同。
在 Next.js
中是否有正确的方法来做我不知道的这种简单的事情?
这是 pages/index.js
文件中包含的代码。
import React from "react"
import Head from 'next/head'
import MyAwesomeComponent from "../components/mycomponent.js"
export default () => (
<div>
<Head>
<link type="text/css" rel="stylesheet" href="static/css/chatwidget.css" />
<link type="text/css" rel="stylesheet" href="static/css/download.css" />
<script type="text/javascript" src="static/libs/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/malihu-custom-scrollbar-plugin@3.1.5/jquery.mCustomScrollbar.concat.min.js"></script>
<script type="text/javascript" src="static/libs/bootstrap.min.js"></script>
<script type="text/javascript" src="static/libs/owl.carousel.min.js"></script>
<script type="text/javascript" src="static/scripts/chatHead.js"></script>
<script type="text/javascript" src="static/libs/jquery.magnific-popup.js"></script>
</Head>
<MyAwesomeComponent /> {/* a simple React component that returns : <p>Hello World </p>*/}
</div>
)
抱歉回答晚了。
事实证明,我链接的所有 scripts
都错过了一个实际上会 运行 每个动作的 functions
的脚本。
这对我有用:
为您的静态文件创建一个文件夹:
<root>/static/hello.js
在你的 index.js
<root>/pages/index.js
import Head from 'next/head';
import MyAwesomeComponent from '../components/mycomponent';
export default () => (
<div>
<Head>
<script type="text/javascript" src="/static/hello.js"></script>
</Head>
<MyAwesomeComponent />
</div>
)
希望对您有所帮助,
此致
希望对你有帮助
将静态文件夹移动到根目录中的 public 文件夹中
export default () => (
<div>
<Head>
<link type="text/css" rel="stylesheet" href="/static/css/chatwidget.css" />
<link type="text/css" rel="stylesheet" href="/static/css/download.css" />
<script type="text/javascript" src="/static/libs/jquery.min.js"></script>
...
</Head>
<MyAwesomeComponent />
</div>
)
您也可以运行 js 编码这个
<script
dangerouslySetInnerHTML={{
__html: `
let a = 1;
functionCall();
`,
}}
></script>
使用以下方法,您可以轻松地将脚本文件的 原始脚本文本 放入生成的 Next.js HTML 页面的 <head>
中,而无需搞砸围绕着字符转义、格式化和一般假装我们实际上并不是最终构建一个 HTML 页面。
在许多用例中,您可能需要脚本 运行 而无需联网。例如:第 3 方脚本、监控/分析脚本预计在 <head>
中,没有单独的网络负载。其中许多都被缩小、损坏、随心所欲,应该只是复制、粘贴,继续生活。
Next.js 很难假装 Web 开发的一切现在都是神奇的 React 和 Webpack(我希望对吗?)
我发现的最佳开发人员体验方式是这样做:
_document.js
...
<Head>
<script type="text/javascript" dangerouslySetInnerHTML={{ __html: process.env.rawJsFromFile }}></script>
</Head>
...
next.config.js
https://github.com/vercel/next.js/blob/canary/packages/next/next-server/server/config.ts#L33
module.exports = {
env: {
rawJsFromFile: fs.readFileSync('./rawJsFromFile.js').toString()
}
}
rawJsFromFile.js
alert('Freedom!!!!!!!!!!!!!!!');
// and other 3rd party script junk, heck even minified JS is fine too if you need
希望这可以让一些人免于我忍受了数小时的挫折...
这是我尝试过的并且对我有用。
我使用了两个文件 entry-script.js
和 main-script.js
。我把这些像这样
<root>/static/entry-script.js
和 <root>/static/main-script.js
entry-script.js
的内容如下
(function (d, t) {
t = d.createElement("script");
t.setAttribute("src", "/static/main-script.js");
d.getElementsByTagName("head")[0].appendChild(t);
})(document);
主要逻辑在文件main-script.js
中。
在 NextJS 的文件 _doucment.js
中,我将我的文件 entry-script.js
包含在正文中,如下所示
class MyDocument extends Document {
render() {
return (
<Html>
<Head>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<script
type="text/javascript"
src="/static/entry-script.js"
></script>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement(),
],
};
};
使用 Next.js v11,您可以使用 Next 组件 Script
https://nextjs.org/blog/next-11#script-optimization
<Script
src="..."
strategy="beforeInteractive"
/>
我写了一篇文章阐述这个问题,希望它能派上用场:
https://www.devtwins.com/blog/how-to-add-a-third-party-script-to-a-nextjs-website
我正在将现有的 React 应用程序集成到 Next.js 中,主要用于 SEO 功能。
我将 css 文件链接粘贴到 Next.js
中的 <Header>
标签内,它们似乎工作正常。当我尝试使用 <script>
标记对 javascript 文件执行相同操作时,它不会执行这些脚本中的代码。但我可以在 chrome 开发工具中看到它们加载了 http 200
。
我尝试使用 npm
中名为 Loadjs
的库来加载 componentDidMount
中的脚本,但我得到的结果与使用 <script>
标签完全相同。
在 Next.js
中是否有正确的方法来做我不知道的这种简单的事情?
这是 pages/index.js
文件中包含的代码。
import React from "react"
import Head from 'next/head'
import MyAwesomeComponent from "../components/mycomponent.js"
export default () => (
<div>
<Head>
<link type="text/css" rel="stylesheet" href="static/css/chatwidget.css" />
<link type="text/css" rel="stylesheet" href="static/css/download.css" />
<script type="text/javascript" src="static/libs/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/malihu-custom-scrollbar-plugin@3.1.5/jquery.mCustomScrollbar.concat.min.js"></script>
<script type="text/javascript" src="static/libs/bootstrap.min.js"></script>
<script type="text/javascript" src="static/libs/owl.carousel.min.js"></script>
<script type="text/javascript" src="static/scripts/chatHead.js"></script>
<script type="text/javascript" src="static/libs/jquery.magnific-popup.js"></script>
</Head>
<MyAwesomeComponent /> {/* a simple React component that returns : <p>Hello World </p>*/}
</div>
)
抱歉回答晚了。
事实证明,我链接的所有 scripts
都错过了一个实际上会 运行 每个动作的 functions
的脚本。
这对我有用:
为您的静态文件创建一个文件夹:
<root>/static/hello.js
在你的 index.js
<root>/pages/index.js
import Head from 'next/head';
import MyAwesomeComponent from '../components/mycomponent';
export default () => (
<div>
<Head>
<script type="text/javascript" src="/static/hello.js"></script>
</Head>
<MyAwesomeComponent />
</div>
)
希望对您有所帮助,
此致
希望对你有帮助
将静态文件夹移动到根目录中的 public 文件夹中
export default () => (
<div>
<Head>
<link type="text/css" rel="stylesheet" href="/static/css/chatwidget.css" />
<link type="text/css" rel="stylesheet" href="/static/css/download.css" />
<script type="text/javascript" src="/static/libs/jquery.min.js"></script>
...
</Head>
<MyAwesomeComponent />
</div>
)
您也可以运行 js 编码这个
<script
dangerouslySetInnerHTML={{
__html: `
let a = 1;
functionCall();
`,
}}
></script>
使用以下方法,您可以轻松地将脚本文件的 原始脚本文本 放入生成的 Next.js HTML 页面的 <head>
中,而无需搞砸围绕着字符转义、格式化和一般假装我们实际上并不是最终构建一个 HTML 页面。
在许多用例中,您可能需要脚本 运行 而无需联网。例如:第 3 方脚本、监控/分析脚本预计在 <head>
中,没有单独的网络负载。其中许多都被缩小、损坏、随心所欲,应该只是复制、粘贴,继续生活。
Next.js 很难假装 Web 开发的一切现在都是神奇的 React 和 Webpack(我希望对吗?)
我发现的最佳开发人员体验方式是这样做:
_document.js
...
<Head>
<script type="text/javascript" dangerouslySetInnerHTML={{ __html: process.env.rawJsFromFile }}></script>
</Head>
...
next.config.js
https://github.com/vercel/next.js/blob/canary/packages/next/next-server/server/config.ts#L33
module.exports = {
env: {
rawJsFromFile: fs.readFileSync('./rawJsFromFile.js').toString()
}
}
rawJsFromFile.js
alert('Freedom!!!!!!!!!!!!!!!');
// and other 3rd party script junk, heck even minified JS is fine too if you need
希望这可以让一些人免于我忍受了数小时的挫折...
这是我尝试过的并且对我有用。
我使用了两个文件 entry-script.js
和 main-script.js
。我把这些像这样
<root>/static/entry-script.js
和 <root>/static/main-script.js
entry-script.js
的内容如下
(function (d, t) {
t = d.createElement("script");
t.setAttribute("src", "/static/main-script.js");
d.getElementsByTagName("head")[0].appendChild(t);
})(document);
主要逻辑在文件main-script.js
中。
在 NextJS 的文件 _doucment.js
中,我将我的文件 entry-script.js
包含在正文中,如下所示
class MyDocument extends Document {
render() {
return (
<Html>
<Head>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<script
type="text/javascript"
src="/static/entry-script.js"
></script>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement(),
],
};
};
使用 Next.js v11,您可以使用 Next 组件 Script
https://nextjs.org/blog/next-11#script-optimization
<Script
src="..."
strategy="beforeInteractive"
/>
我写了一篇文章阐述这个问题,希望它能派上用场:
https://www.devtwins.com/blog/how-to-add-a-third-party-script-to-a-nextjs-website