ES6导入中断Gatsby Build:WebpackError:ReferenceError:未定义元素

时间:2019-05-03 13:40:27

标签: javascript reactjs gatsby

我想在组件中包含以下npm软件包:tiny-slider-react。

但是,尽管在Gatsby Develop中可以正常使用,但Gatsby Build失败并显示以下消息:

error Building static HTML failed

See our docs page on debugging HTML builds for help https://gatsby.dev/debug-html

  3 |   "use strict";
  4 | 
> 5 |   if(!("remove" in Element.prototype)){
    | ^
  6 |     Element.prototype.remove = function(){
  7 |       if(this.parentNode) {
  8 |         this.parentNode.removeChild(this);


  WebpackError: ReferenceError: Element is not defined

  - childNode.remove.js:5 
    [lib]/[ventura-slider]/src/helpers/childNode.remove.js:5:1

  - childNode.remove.js:12 Object../node_modules/ventura-slider/src/helpers/childNode.remove.js
    [lib]/[ventura-slider]/src/helpers/childNode.remove.js:12:2

  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1

  - tiny-slider.module.js:1 Module../node_modules/ventura-slider/src/tiny-slider.module.js
    [lib]/[ventura-slider]/src/tiny-slider.module.js:1:1

  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1

  - Carousel.js:19 Object../node_modules/tiny-slider-react/build/Carousel.js
    [lib]/[tiny-slider-react]/build/Carousel.js:19:19

  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1

  - index.js:7 Object../node_modules/tiny-slider-react/build/index.js
    [lib]/[tiny-slider-react]/build/index.js:7:17

  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1


  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1


  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1

  - sync-requires.js:12 Object../.cache/sync-requires.js
    lib/.cache/sync-requires.js:12:57

  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1

  - static-entry.js:9 Module../.cache/static-entry.js
    lib/.cache/static-entry.js:9:22

注释此导入及其“ React”组件可解决此问题。

Slideview.js

import React from 'react';
import TinySlider from "tiny-slider-react";

...

class SlideView extends React.Component{
    render(){
        return(
            <TinySlider settings={settings}>
                ...
            </TinySlider>
        );
    }
}

预期:滑块与开发一样在生产中工作。 实际结果:构建中断

2 个答案:

答案 0 :(得分:0)

在开发过程中,React组件仅在浏览器中运行。构建时,Gatsby将这些组件呈现在服务器上-并且在这种情况下Element(以及windowdocument之类的东西未定义。)

对于您的特定用例,我没有解决方案,但是当您要进行与DOM相关的操作时,应该在componentDidMount中完成,该操作只能在浏览器中运行。

我为您解决问题的想法:

  • 仅能在父级componentDidMount中导入和使用组件。这是IMO非常脆弱,不是正确的方法

  • 分叉该软件包并对其进行修补,因此操纵Element原型的代码仅在浏览器上运行。最终成为公关

编辑:

我做了一些搜索,发现了类似(类似)的问题和解决方案:https://github.com/gatsbyjs/gatsby/issues/309#issuecomment-373359887

// index.js
import React from "react";
import Link from "gatsby-link";

// import "uikit/dist/js/uikit";
// Third party JS access `window` without
// `typeof window !== "undefined"` check

class Template extends React.Component {
  componentDidMount() {
    import("uikit/dist/js/uikit")
      .then((uikit) => {
        this.uikit = uikit;
      })
      .catch((error) => console.error(error));
  }
  render() {
    // ...
  }
}

// ...

本质上,您要做的是将组件导入componentDidMount生命周期挂钩中,将其绑定到this.<MyComponent>,然后在render函数中使用它:

render() {
   const MyComponent = this.MyComponent;
   return <MyComponent />;
}

请注意,我自己还没有尝试过,但是我看不出它应该如何工作。做自己的测试;)

答案 1 :(得分:0)

结果是我必须在gatsby-node.js中添加以下几行

gatsby-node.js

// /**
//  * Implement Gatsby's Node APIs in this file.
//  *
//  * See: https://www.gatsbyjs.org/docs/node-apis/
//  */

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

它在此文档页面的底部。 https://www.gatsbyjs.org/docs/debugging-html-builds/

感谢菲利普(Phillip)的帮助