【问题标题】:ReferenceError: document is not defined when refresh nextjs pageReferenceError:刷新nextjs页面时未定义文档
【发布时间】:2020-09-30 23:12:42
【问题描述】:

我正在尝试使用 React for Nextjs 9.4 创建一个简单的 UI 库,这就是我在做什么

// input.js in React UI Lib

import React from "react";
import styled from "./input.module.scss";

const Input = React.forwardRef((props, ref) => (
  <>
    {props.label && <label className={styled.label}>{props.label}</label>}
    <input className={styled.input} {...props} ref={ref} />
  </>
));

export default Input;

并为简单起见制作了导出所有模块的索引

// app.js the index file for the lib

import PrimaryButton from "./components/button/primaryButton";
import TextInput from "./components/input/input";
import PasswordInput from "./components/passwordInput/password";
import CheckBox from "./components/checkbox/checkbox";

export {
  PrimaryButton,
  TextInput,
  PasswordInput,
  CheckBox
};

这也是我为 SSR Next 构建的 webpack 配置

const path = require("path");
const autoprefixer = require("autoprefixer");
const nodeExternals = require("webpack-node-externals");

const CSSLoader = {
  loader: "css-loader",
  options: {
    modules: "global",
    importLoaders: 2,
    sourceMap: false,
  },
};

const CSSModlueLoader = {
  loader: "css-loader",
  options: {
    modules: true,
    importLoaders: 2,
    sourceMap: false,
  },
};

const PostCSSLoader = {
  loader: "postcss-loader",
  options: {
    ident: "postcss",
    sourceMap: false,
    plugins: () => [autoprefixer()],
  },
};

const SassLoader = {
  loader: "sass-loader",
  options: {
    // Prefer `dart-sass`
    implementation: require("sass"),
  },
};

module.exports = {
  target: "node",
  entry: "./src/app.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
    chunkFilename: "[id].js",
    publicPath: "",
    library: "",
    libraryTarget: "commonjs",
  },
  externals: [nodeExternals()],
  resolve: {
    extensions: [".js", ".jsx"],
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        loader: "babel-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.(sa|sc|c)ss$/i,
        exclude: [/node_modules/, /\.module\.(sa|sc|c)ss$/i],
        use: ["style-loader", CSSLoader, PostCSSLoader, SassLoader],
      },
      {
        test: /\.module\.(sa|sc|c)ss$/i,
        exclude: /node_modules/,
        use: ["style-loader", CSSModlueLoader, PostCSSLoader, SassLoader],
      },
      {
        test: /\.(png|jpe?g|gif)$/,
        loader: "url-loader?limit=10000&name=img/[name].[ext]",
      },
    ],
  },
};

1-i 构建

2-在 npm 上发布

3-在 Nextjs 中导入

然后一切正常,但问题是当我在开发过程中尝试刷新 (F5) 页面时出现错误

Unhandled Runtime Error
ReferenceError: document is not defined

我该如何解决?

【问题讨论】:

  • 你没有访问窗口|| SSR 期间的文档,因此请尽量防止在此期间进行渲染,例如 typeof window !=== 'undefined' ? &lt;Component /&gt; : null
  • @Mashiro 我已将组件更改为typeof window !== 'undefined' ? &lt;&gt; {props.label &amp;&amp; &lt;label className={styled.label}&gt;{props.label}&lt;/label&gt;} &lt;input className={styled.input} {...props} ref={ref} /&gt; &lt;/&gt; : null,仍然是同样的错误
  • 你能提供你捆绑文件的链接吗
  • 我知道为什么会发生检查答案

标签: reactjs webpack next.js server-side-rendering


【解决方案1】:

尝试检查客户端渲染中的组件:

const isBrowser = typeof window !== 'undefined';
isBrowser ? <Component/> : null;

另一种选择是尝试使用 ssr false 进行渲染:

const DynamicComponentWithNoSSR = dynamic(
() => import('../components/hello3'),
{ ssr: false }
)

谢谢..

【讨论】:

    【解决方案2】:

    您可能并不总是希望在服务器端包含模块。例如,当模块包含仅在浏览器中工作的库时。

    看看下面的例子:

    import dynamic from 'next/dynamic'
    
    const DynamicComponentWithNoSSR = dynamic(
    () => import('../components/hello3'),
    { ssr: false }
    )
    
    function Home() {
    return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
     )
    }
    
    export default Home
    

    【讨论】:

      【解决方案3】:
      const Example = dynamic( () => import('example'), { ssr: false } )
      

      https://github.com/elrumordelaluz/reactour/issues/130

      【讨论】:

        【解决方案4】:
        1. 尝试仅在您可以使用的客户端呈现组件:

          typeof window !== 'undefined' ? &lt;Component /&gt; : null

        2. 你在 webpack 配置中使用style-loader,它将使用document.createElement 进入头部,这在 SSR 中不可用,你可以选择其他选项,例如 mini-css-extract-plugin

          李>

        【讨论】:

        • typeof window !== 'undefined' &amp;&amp; &lt;Component /&gt; 也可以
        猜你喜欢
        • 2023-02-07
        • 2022-01-11
        • 2022-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-30
        • 2020-09-18
        相关资源
        最近更新 更多