quando in ambiente di sviluppo, la mia app funziona perfettamente. Quando nell'ambiente di produzione si blocca con l'errore:
Uncaught TypeError: (0 , _react.useEffect) is not a function
Succede in un file che ho creato dove importare React e useEffect in questo modo:
import React, { useEffect } from 'react'
const X = () => {
useEffect(() => { ... })
...
}
l'aggiunta di un console.log proprio sotto questa riga conferma che useEffect è effettivamente indefinito quando in produzione e la funzione prevista in dev.
Ho controllato il mio package.json, yarn.lock e node_modules per qualsiasi versione di reazione o di reazione che potesse essere inferiore a 16.8.0 in cui è stato introdotto useEffect. Ma tutto è 16.13.1 e sono la dipendenza principale e ho provato a pulire la cache del mio filato, eliminare node_modules & yarn.lock e reinstallare.
Ho provato ad aggiungerlo e rimuoverlo peerDependencies
senza successo.
Ho messo un segno di spunta per assicurarmi che non ci siano 2 versioni separate di React in esecuzione, ma il salvataggio window.React1 = React
all'interno della libreria e window.React2 = React
all'interno della mia applicazione e il controllo
window.React1 === window.React2
era vero, quindi neanche quello.
Infine, ho anche provato ad alias React a quello specifico in node_modules, ma senza fortuna.
L'unica soluzione che ho trovato che funziona è se lo importa in questo modo:
import React from 'react';
const X = () => {
React.useEffect(() => { ... })
...
}
Ma questo dovrebbe essere esattamente lo stesso che usare un'importazione destrutturata? Se uso esplicitamente React.useEffect, mi costringe anche a cambiare tutti gli altri miei usi useState e useEffect in React.useSate
eReact.useEffect
L'errore successivo diventa: TypeError: (0 , _react.useState) is not a function
in un altro file in cui utilizzo gli hook di React.
Voglio risolvere il problema non implementare una soluzione alternativa.
Uso microbundle
per raggruppare la mia libreria usando React. Uso parcel-bundler
per importare il componente React e renderlo in un ambiente di sviluppo (direttamente da SRC) o prod (la libreria in bundle)
La versione in bundle che uso è in bundle con .mjs
Ho controllato anche l'output del bundle .mjs minimizzato e all'interno di React viene importato in questo modo:
import ue,{useEffect as pe,useState as fe}from"react";
Il che mi sembra perfetto.
Quello che davvero non capisco è come un'importazione ristrutturata la spezzerebbe, ma solo facendo React.useEffect funzionerebbe bene?
Ecco il mio package.json
{
"name": "xxx",
"version": "1.1.4",
"repository": "git@github.com:xxx/xxx.git",
"author": "xxx",
"license": "MIT",
"source": "src/index.ts",
"main": "dist/bundle.js",
"umd:main": "dist/bundle.umd.js",
"module": "dist/bundle.mjs",
"publishConfig": {
"registry": "https://npm.pkg.github.com/@xxx"
},
"scripts": {
"build": "microbundle",
"dev": "parcel ./test-app/dev/index.html --port 3000",
"start": "parcel ./test-app/serve/index.html --port 3000",
"storybook": "start-storybook -s ./public -c .storybook --ci",
"prepublishOnly": "yarn build"
},
"dependencies": {
"@api-platform/admin": "2.1.0",
"@api-platform/api-doc-parser": "0.8.2",
"@fortawesome/fontawesome-svg-core": "^1.2.28",
"@fortawesome/free-solid-svg-icons": "^5.13.0",
"@fortawesome/react-fontawesome": "^0.1.9",
"@material-ui/core": "^4.9.10",
"@material-ui/icons": "^4.9.1",
"@react-keycloak/web": "^2.1.1",
"@types/pluralize": "^0.0.29",
"google-geocoder": "0.2.1",
"history": "^4.10.1",
"keycloak-js": "^9.0.3",
"lodash.debounce": "^4.0.8",
"lodash.omit": "^4.5.0",
"lodash.set": "4.3.2",
"notistack": "0.9.9",
"papaparse": "^5.2.0",
"parcel-bundler": "1.12.4",
"polished": "^3.5.2",
"react": "16.13.1",
"react-admin": "3.4.1",
"react-dom": "16.13.1",
"react-is": "16.13.1",
"react-redux": "^7.2.0",
"recompose": "^0.30.0",
"redux": "4.0.5",
"styled-components": "5.1.0"
},
"devDependencies": {
"@babel/core": "7.9.0",
"@babel/plugin-syntax-export-default-from": "7.8.3",
"@babel/preset-env": "7.9.5",
"@babel/preset-react": "7.9.4",
"@storybook/addon-a11y": "5.3.18",
"@storybook/addon-actions": "5.3.18",
"@storybook/addon-info": "5.3.18",
"@storybook/addon-knobs": "5.3.18",
"@storybook/addon-links": "5.3.18",
"@storybook/addon-storyshots": "5.3.18",
"@storybook/addon-storysource": "5.3.18",
"@storybook/addon-viewport": "5.3.18",
"@storybook/react": "5.3.18",
"@testing-library/react": "^10.0.3",
"@types/jsonld": "1.5.1",
"@types/lodash": "4.14.149",
"@types/node": "13.11.1",
"@types/papaparse": "5.0.3",
"@types/react-redux": "7.1.7",
"@types/recompose": "^0.30.7",
"@types/styled-components": "5.1.0",
"@welldone-software/why-did-you-render": "4.0.7",
"awesome-typescript-loader": "5.2.1",
"babel-loader": "^8.1.0",
"babel-plugin-module-resolver": "4.0.0",
"babel-plugin-styled-components": "1.10.7",
"lodash.get": "4.4.2",
"lodash.uniq": "4.5.0",
"microbundle": "0.11.0",
"openapi-types": "1.3.5",
"parcel-plugin-static-files-copy": "2.3.1",
"pluralize": "^8.0.0"
},
"alias": {
"jsonld": "./node_modules/jsonld/dist/jsonld.js"
},
"staticFiles": {
"staticPath": "public",
"watcherGlob": "**"
}
}
Vale anche la pena notare che è solo React con questo problema. Tutte le altre mie importazioni ristrutturate funzionano bene.
global
flag --globals react=React
e aggiungere React come dipendenze tra pari <- Anche se potrebbe non essere una soluzione corretta. Guarda questo numero: github.com/developit/microbundle/issues/537 sembra provenire dayarn
microbundler
invece che react-scripts
per la build di produzione, o qualcosa che ha alterato le configurazioni del bundler in modo negativo. Voglio attirare la tua attenzione. I nomi degli hook di reazione dovrebbero iniziare con use
e potrebbero essere in questa riga import ue,{useEffect as pe,useState as fe}from"react";
che usano Effetti importati quando pe
qualcosa è andato storto con reagire. Quindi, hai provato a costruire con create-react-app
e react-scripts
?