securingsincity / react-ace

React Ace Component
http://securingsincity.github.io/react-ace/
MIT License
4.06k stars 604 forks source link

ReferenceError: window is not defined #1044

Open ccheung0926 opened 3 years ago

ccheung0926 commented 3 years ago

Problem

While I was following this tutorial to build a cloned code-pen apps using npm instead of yarn, I received ReferenceError: window is not defined I looked up some similar issue that was raised in the past, and people suggested to use brace, but the latest react-ace currently stops supporting brace and suggesting us to use Ace-build which I did, but it fails with the same error.

node: v12.8.0 npm: 6.14.8

Sample code to reproduce your issue

import React from "react";
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/mode-html";
import "ace-builds/src-noconflict/mode-css";
import "ace-builds/src-noconflict/theme-monokai";

import styles from "./editors.module.css";

export const JavascriptEditor = () => {
  return <Editor mode="javascript" title={"JS"}  />;
};

export const HtmlEditor = () => {
  return <Editor mode="html" title={"HTML"} />;
};

export const CssEditor = () => {
  return <Editor mode="css" title={"CSS"}  />;
};

const Editor = ({ mode, title }) => {
  return  (
    <div className={styles.editorContainer}>
      <div className={styles.editorTitle}>{title}</div>
      {<AceEditor
        mode={mode}
        theme="monokai"
        name={title}
        fontSize={18}
        width={"100%"}
        showPrintMargin={true}
        showGutter={true}
        tabSize={2}
        setOptions={{ useWorker: false }}    
      />}
    </div>
  );
};

References

Progress on: #

ccheung0926 commented 3 years ago

I just resolved it. Basically, it was due to these 3 arrow functions (JavascriptEditor, HtmlEditor, CssEditor) , i declared those 3 components function using function declaration instead of arrow function. One interesting finding is that it doesn't seem to have to window is not defined error if I used yarn instead of npm


actually, for a moment, it seems like it fixes the issue, but as I keep developing my apps, the issue kicks back.

coderlfm commented 3 years ago

I've had the same problem.Have you found the solution now

syvlabs commented 3 years ago

Same issue came up, it was because I was using react-ace with next.js. By default next.js renders pages server-side, hence the window object isn't available.

The fix was to dynamically import (see docs here) the module containing the AceEditor:

import dynamic from 'next/dynamic'

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

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home
foderking commented 2 years ago

This works in development mode. but when I try to build, I still get the error

foderking commented 2 years ago

UPDATE: I tried the workaround mentioned here Basically, Two dynamic imports. A dynamic import of the component into it's parent and a dynamic import of the react ace modules inside the component itself

tudormunteanu commented 2 years ago

If you're in a React + MUI + Next.js setup like me, you could also avoid the SSR (server-side rendering) like so:

Page:

import dynamic from 'next/dynamic'
import React from "react";
import Box from '@mui/material/Box';

const Ace = dynamic(
  () => import("./components/editor"),
  { ssr: false }
)

const Editor = () => {
    return (
      <Box>
        <Ace />        
      </Box>
    );
}

export default Editor;

Component:

import React from "react";
import { render } from "react-dom";
import AceEditor from "react-ace";
import Box from '@mui/material/Box';

import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/theme-dracula";
import "ace-builds/src-noconflict/ext-language_tools";

function onChange(newValue) {
  console.log("change", newValue);
}

const Editor = (props) => {
  return (
    <Box>
      <Box id="example"></Box>
      <AceEditor
        mode="python"
        theme="dracula"
        onChange={onChange}
        name="example"
        editorProps={{ $blockScrolling: true }}
      />
    </Box>
)
};

export default Editor;

based on the example from @syvlabs

jamond-x commented 1 year ago

If you're in a React + MUI + Next.js setup like me, you could also avoid the SSR (server-side rendering) like so:

Page:

import dynamic from 'next/dynamic'
import Box from '@mui/material/Box';

const Ace = dynamic(
  () => import("./components/editor"),
  { ssr: false }
)

export default Editor;

It's work! Thanks!