Hello I am trying to deploy a web app to Netlify. It uses the COCO SSD model for object recognition in the frontend, which is purposeful. The web app works perfectly fine on localhost but once I deploy to Netlify I get this error:
detector.js:47 TypeError: Cannot call a class as a function
at r (classCallCheck.js:3)
at new t (tensor.ts:266)
at t.value (engine.ts:736)
at i (tensor_ops_util.ts:75)
at i (tensor.ts:55)
at Module.p (io_utils.ts:223)
at t.value (graph_model.ts:139)
at t.<anonymous> (graph_model.ts:119)
at c (runtime.js:63)
at Generator._invoke (runtime.js:293)
I have never had this problem before and find it very odd, this is my code for implementation of the COCO SSD model and the class.
import React from 'react';
import Lottie from 'react-lottie';
import * as cocoSsd from '@tensorflow-models/coco-ssd';
import '@tensorflow/tfjs';
class Detector extends Component {
constructor(props) {
super(props);
this.state = {
count: 0,
list: ['person','laptop','scissors','mouse', 'spoon', 'keyboard',],
isStopped: true,
}
}
videoRef = React.createRef();
componentDidMount() {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
//getting camera permission code removed for readability
const modelPromise = cocoSsd.load();
Promise.all([modelPromise, webCamPromise])
.then(values => {
this.detectFrame(this.videoRef.current, values[0]);
})
.catch(error => {
console.error(error);
});
}
}
detectFrame = (video, model) => {
model.detect(video).then(predictions => {
this.checkPredictions(predictions);
requestAnimationFrame(() => {
this.detectFrame(video, model);
});
});
};
checkPredictions = predictions => {
predictions.forEach(prediction => {
if(prediction.class === this.state.list[0]) {
const tempL = this.state.list;
const tempC = this.state.count + 1;
tempL.shift();
this.setState({list: tempL, count: tempC, isStopped: false});
}
});
};
render() {
return (
<div>
//removed for readability
</div>
);
}
}
export default Detector;
It looks like webpack
has picked the field (the built file) of @tensorflow/tfjs
in case of production mode which ends up the problem.
But we can specify this field manually which describes here https://webpack.js.org/configuration/resolve/#resolvemainfields
In order to do it, you just simply switch to use react-app-rewired
where we can customize webpack
configuration. Here is the steps:
npm i -D react-app-rewired
config-overrides.js
with following content:module.exports = function override(config, env) {
if (process.env.NODE_ENV === 'production')
{
config.resolve.mainFields = ['main'];
}
return config;
}
react-app-rewired
script by replacing the react-scripts
commands:"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
// ...
},
Finally, you can run npm build
and serve your built content to test it. That's it!