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.jsmain-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