【问题标题】:NextJS React - WebpackError: window is not definedNextJS React - WebpackError:未定义窗口
【发布时间】:2020-03-18 11:23:46
【问题描述】:

我正在尝试使用 React。 我按照 NextJs (link) 的“入门”教程,成功创建了新项目。

当我尝试导入第三方插件(如 current-devicessmooth-scrollbar)时,我会收到以下错误:

ReferenceError: window is not defined
(anonymous function)
/c/xampp/htdocs/nextjs/node_modules/smooth-scrollbar/dist/smooth-scrollbar.js:1:262
Module._compile
module.js:652:30
Module._extensions..js
module.js:663:10
Module.load
module.js:565:32
tryModuleLoad
module.js:505:12
Function.Module._load
module.js:497:3
Module.require
module.js:596:17
require
internal/module.js:11:18
smooth-scrollbar
webpack:/external "smooth-scrollbar":1
> 1 | module.exports = require("smooth-scrollbar");
View compiled
__webpack_require__
./webpack/bootstrap:21
  18 | // Execute the module function
  19 | var threw = true;
  20 | try {
> 21 |  modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
     | ^  22 |  threw = false;
  23 | } finally {
  24 |  if(threw) delete installedModules[moduleId];
View compiled
Module../pages/index.js
/_next/development/server/static/development/pages/index.js:221:74
__webpack_require__
./webpack/bootstrap:21
  18 | // Execute the module function
  19 | var threw = true;
  20 | try {
> 21 |  modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
     | ^  22 |  threw = false;
  23 | } finally {
  24 |  if(threw) delete installedModules[moduleId];
View compiled
3
/_next/development/server/static/development/pages/index.js:383:18
__webpack_require__
./webpack/bootstrap:21
  18 | // Execute the module function
  19 | var threw = true;
  20 | try {
> 21 |  modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
     | ^  22 |  threw = false;
  23 | } finally {
  24 |  if(threw) delete installedModules[moduleId];
View compiled
▶ 2 stack frames were collapsed.

我在文件 C:\xampp\htdocs\nextjs\pages\index.js 中所做的导入

只是:

import Scrollbar from 'smooth-scrollbar';
import device from 'current-device'

非常感谢您的帮助!

【问题讨论】:

    标签: javascript reactjs webpack


    【解决方案1】:

    Next.js 有一个服务器端和一个客户端, 窗口未在服务器端定义,“平滑滚动条”和“当前设备”可能都使用窗口, 您可以使用 ssr: false 的 next 动态导入,仅在 clinet 端使用一些包:

    import dynamic from 'next/dynamic'
    
    const DynamicComponentWithNoSSR = dynamic(
      () => import('package'),
      { ssr: false }
    )
    
    // ...
    
    
    // use it in render like:
    <DynamicComponentWithNoSSR />
    

    更多信息请访问docs

    【讨论】:

    • 感谢您的回答!我没有考虑服务端渲染和客户端渲染!
    • 短小精悍,效果不错。无法要求更多,谢谢:)
    • @SamSverko 乐于助人:)
    • 非常感谢,我有时会出现窗口位置错误,我不知道为什么!它既简单又很棒!
    • 太棒了!你的回答也适用于这个错误Next.js SyntaxError "Unexpected token 'export'":stackoverflow.com/q/65936222/3051080
    【解决方案2】:

    就我而言,仅做 Nextjs 动态导入是不够的。

    示例

    动态导入 TVChart.js

    import dynamic from "next/dynamic"
    import * as React from "react"
    
    const TVChartContainer = dynamic(() => import("./TVChart"), { ssr: false })
    
    export default () => {
      return <TVChartContainer />
    }
    
    

    如果您仍然收到 > ReferenceError: window is not defined 错误,即使在使用接受的答案中提到的dynamic imports with no ssr 之后,这可能是由于需要 window 存在并在顶层导入。

    在我的例子中,我正在导入 TradingView Charting Library widget 对象,如下所示:

    TVChart.js - 不工作

    import { widget } from "../public/static/charting_library/charting_library.min" //did not work
    
    class TVChart extends Component {
    
        tvWidget = null
    
        componentDidMount() {
            const widgetOptions = {} //ChartingLibraryWidgetOptions
            this.tvWidget = new widget(widgetOptions)
        }
    
        render() {
            <div id="tv_chart_container" className="TVChartContainer" />
        }
    }
    export default TVChart;
    

    TVChart.js - 工作

    // import { widget } from "../public/static/charting_library/charting_library.min" // <-- Remove this line
    
    class TVChart extends Component {
    
        tvWidget = null
    
        async componentDidMount() {
            const { widget } = await import("../public/static/charting_library/charting_library.min") // <-- Import asynchronously
            const widgetOptions = {} //ChartingLibraryWidgetOptions
            this.tvWidget = new widget(widgetOptions)
        }
    
        render() {
            <div id="tv_chart_container" className="TVChartContainer" />
        }
    
    }
    export default TVChart;
    
    

    希望对你有帮助。

    【讨论】:

    • 这很有帮助!请注意,如果您像我一样导入 npm 包,则可以通过解构它来访问默认导出。您可以将事件别名设置为其他内容:const { default: LibName } = await import('SomeNPMLibrary');
    猜你喜欢
    • 2019-06-03
    • 2019-10-12
    • 2020-11-26
    • 2021-03-30
    • 2019-10-05
    • 2020-06-25
    • 2020-09-18
    • 2022-12-24
    • 2023-02-04
    相关资源
    最近更新 更多