Masashi Ishikawa's portfolio

Gatsbyビルドエラー「window is not defined」への対処法

2020/05/23
Gatsby

なにこれ

react-cytoscapeのようなwindowオブジェクトを前提としたライブラリをGatsbyで使おうとすると、gatsby developのときは正常動作するにもかかわらず、ビルド時にだけwindow is not definedエラーがでます。今回はその対処法を備忘録として残しておきます。

原因と対処法

Gatsbyビルド時は、windowdocumentといったブラウザのグローバルオブジェクトを参照しているとエラーになります。 この場合、それらがundefinedかチェックが必要です。

// (Before) 以下でビルド時にエラーが出る場合は...
const module = require("module") 

// (After 1) このようにwindowオブジェクトの存在チェックをすることでエラーを免れます
if (typeof window !== `undefined`) {
  const module = require("module")
}

// (After 2) このような形でもOKです
const module = typeof window !== `undefined` ? require("module") : null

またwebpackの設定で、ビルドエラーになるライブラリをダミーに置き換えることで、エラーを免れます。

exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === 'build-html') {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /react-cytoscapejs/,
            use: loaders.null(),
          },
        ],
      },
    })
  }
}

さらに、そのライブラリを使った処理をReactコンポーネントに記述している場合は、componentDidMountuseEffectに移しましょう。そうすることで、その処理がブラウザでのみ実行されるようになるのでビルド時のエラーを免れます。

import CytoscapeComponent from 'react-cytoscapejs'

class PostRelationSection extends React.Component {

  /*--中略--*/

  componentDidMount() {
    const { posts, allImage } = this.props
    const nodes = createPostNode({ posts, allImage })
    nodes.push(CYTOSCAPE_ZOOM_UP_ELEMENT)
    nodes.push(CYTOSCAPE_ZOOM_DOWN_ELEMENT)

    const edges = createPostEdges({posts})

    const cytoscapeElements = CytoscapeComponent.normalizeElements({ nodes, edges })
    this.setState({ cytoscapeElements })
  }

  /*--中略--*/
}

参考

  • なにこれ
  • 原因と対処法
  • 参考
  • このエントリーをはてなブックマークに追加

←前の記事

thumbnail

関連記事

thumbnail
thumbnail
thumbnail
thumbnail
thumbnail

最近の記事

thumbnail
thumbnail
thumbnail
thumbnail
thumbnail
記事一覧