WebpackError: TypeError: p5__WEBPACK_IMPORTED_MODULE_4___default.a не является конструктором

Этот сервер работает нормально в режиме разработки, но выдает ошибку во время сборки

Я использую Gatsby.js Framework, и в настоящее время мои коды развернуты на сервере netlify.

Вот мой файл конфигурации gatsby-node.js:

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

**Вывод ошибки: ** вывод

Вот коды в файле Experiments.js

import React from "react"
import MetaData from "../components/MetaData"
import ml5 from "ml5"
import "../components/styles.css"
import p5 from "p5"

export default function Experiments() {
  let label = ""
  let probability = ""
  let classifier
  let video

  const gotResult = (err, result) => {
    if (err) {
      console.error(err)
    } else {
      label = result[0].label.toUpperCase()

      probability = (result[0].confidence * 100).toFixed(2)
      classifier.classify(gotResult)
    }
  }

  const modelOnLoaded = () => {
    console.log("Model is Successfully Loaded!")
  }

  const videoReady = () => {
    classifier.classify(gotResult)
  }

  function sketch(p) {
    p.setup = () => {
      p.createCanvas(640, 480)

      video.hide()
      p.background(0)
    }
    p.draw = () => {
      p.background(0)
      p.image(video, 0, 0)
      p.fill(0)
      p.textSize(32)
      p.text(label, 10, p.height - 100)
      p.text(probability, 10, p.height - 30)
    }
    p.preload = () => {
      video = p.createCapture(p.VIDEO, videoReady)

      classifier = ml5.imageClassifier("MobileNet", video, modelOnLoaded)
    }
  }

  new p5(sketch)

  return (
    <div>
      <MetaData />
      <h1 className="display-1">Image Classifier</h1>

      <div></div>
    </div>
  )
}

Спецификация машины:

System:
    OS: Linux 5.4 Ubuntu 20.04.1 LTS (Focal Fossa)
    CPU: (4) x64 Intel(R) Core(TM) i3-4005U CPU @ 1.70GHz
    Shell: 5.8 - /usr/bin/zsh
  Binaries:
    Node: 12.20.0 - /usr/bin/node
    Yarn: 1.22.10 - /usr/bin/yarn
    npm: 6.14.10 - /usr/bin/npm
  Browsers:
    Chrome: 87.0.4280.88
  npmPackages:
    gatsby: ^2.26.1 => 2.26.1
    gatsby-plugin-load-script: ^1.1.0 => 1.1.0
    gatsby-plugin-manifest: ^2.9.0 => 2.9.0
    gatsby-plugin-react-helmet: ^3.7.0 => 3.7.0
    gatsby-source-github-api: ^0.2.1 => 0.2.1
    gatsby-source-graphql: ^2.11.0 => 2.11.0
  npmGlobalPackages:
    gatsby-cli: 2.16.2

person Debajit    schedule 29.12.2020    source источник
comment
Если вы удалите эти null загрузчики, вас это window беспокоит, не так ли?   -  person Ferran Buireu    schedule 29.12.2020
comment
Ага!, тогда выдаст ошибку о том, что window недоступен   -  person Debajit    schedule 29.12.2020


Ответы (1)


Иногда модуль-нарушитель не является самой зависимостью (в данном случае p5 и ml5), а является одной из dev-зависимостей этих библиотек. Например, в моем проекте я показываю карту, и библиотека карт выводит то же самое, что и ваша проблема, мне пришлось добавить загрузчик null в /canvg/ в моем случае, библиотеку, которая использует мою карту для ее печати. .

Еще одно решение из документов Gatsby, может подойти для вас, использует loadable-components, в основном, вместо добавления null загрузчика в во время сборки он загружает зависимость на стороне клиента (а не на стороне сервера). В твоем случае:

import loadable from '@loadable/component'

const YourFunctionToUseMl5 = loadable(() => import ml5 from "ml5")
const YourFunctionToUseP5 = loadable(() => import p5 from "p5")


function MyComponent() {
 useEffect(()=>{
   // use safely ml5 and p5
 }, [])

  return (
    <div>
     Hello loadable
    </div>
  )
}

Используйте его осторожно, потому что, несмотря на то, что это зависимость небольшого размера, вы используете не собственный подход (как null загрузчик), и это может увеличить размер пакета приложения.

person Ferran Buireu    schedule 30.12.2020
comment
Я сделал то же самое, но все равно показывает ошибку: TypeError: p5 не является конструктором - person Debajit; 30.12.2020
comment
Вы уверены, что p5 является реагирующей импортируемой библиотекой? Я так не думаю, и я не нашел информации об этом, поэтому я предполагаю, что это нативная библиотека JavaScript, а не React. - person Ferran Buireu; 30.12.2020
comment
Да, ты прав. Вы не можете напрямую импортировать p5 в приложение реакции, вместо этого я использую react-p5-wrapper и это работает! - person Debajit; 01.01.2021