dans l'environnement de développement, mon application fonctionne très bien. Dans l'environnement de production, il se bloque avec l'erreur:
Uncaught TypeError: (0 , _react.useEffect) is not a function
Cela se produit dans un fichier que j'ai créé où j'importe React et useEffect comme ceci:
import React, { useEffect } from 'react'
const X = () => {
useEffect(() => { ... })
...
}
l'ajout d'un console.log juste en dessous de cette ligne confirme que useEffect est en effet indéfini en production et la fonction attendue en développement.
J'ai vérifié mes packages.json, yarn.lock et node_modules pour toute version de react ou react-dom qui pourrait être inférieure à 16.8.0 où useEffect a été introduit. Mais tout est 16.13.1 et ils sont la principale dépendance et j'ai essayé de nettoyer mon cache de fils, de supprimer node_modules & yarn.lock et de réinstaller.
J'ai essayé de l'ajouter et de le supprimer peerDependencies
sans succès.
Je mets un chèque pour m'assurer qu'il n'y a pas 2 versions distinctes de React en cours d'exécution, mais l'enregistrement window.React1 = React
à l'intérieur de la bibliothèque et à l' window.React2 = React
intérieur de mon application et la vérification
window.React1 === window.React2
c'était vrai, donc ce n'est pas ça non plus.
Enfin, j'ai également essayé d'alias React à celui spécifique dans node_modules, mais sans aucune chance.
La seule solution que j'ai trouvée qui fonctionne est si je l'importe comme ceci:
import React from 'react';
const X = () => {
React.useEffect(() => { ... })
...
}
Mais cela devrait être exactement la même chose que d'utiliser une importation déstructurée? Si j'utilise explicitement React.useEffect, cela m'oblige également à changer tous mes autres crochets useState et useEffect en React.useSate
etReact.useEffect
L'erreur suivante devient simplement: TypeError: (0 , _react.useState) is not a function
dans un autre fichier où j'utilise des crochets React.
Je veux résoudre le problème sans implémenter une solution de contournement.
J'utilise microbundle
pour regrouper ma bibliothèque à l'aide de React. J'utilise parcel-bundler
pour importer le composant React et le rendre dans un environnement de développement (directement depuis src) ou prod (la bibliothèque fournie)
La version groupée que j'utilise est livrée avec .mjs
J'ai également vérifié la sortie du bundle .mjs minifié et à l'intérieur de React est importé comme ceci:
import ue,{useEffect as pe,useState as fe}from"react";
Ce qui me va bien.
Ce que je ne comprends vraiment pas, c'est comment une importation restructurée le briserait, mais simplement faire React.useEffect fonctionnerait très bien?
Voici mon package.json
{
"name": "xxx",
"version": "1.1.4",
"repository": "[email protected]: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": "**"
}
}
A noter également, c'est seulement React avec lequel j'ai ce problème. Toutes mes autres importations restructurées fonctionnent très bien.
global
indicateur--globals react=React
et ajouter React en tant que dépendances entre pairs <- Bien que ce ne soit pas une solution appropriée. Regardez ce problème: github.com/developit/microbundle/issues/537 il semble provenir deyarn
microbundler
au lieu dereact-scripts
pour la génération de production, ou quelque chose de mauvais dans les configurations de bundler. Je veux attirer votre attention sur les noms des hooks react qui doivent commencer paruse
et qui peuvent se trouver dans cette ligneimport ue,{useEffect as pe,useState as fe}from"react";
qui utilise Importer les effets carpe
quelque chose s'est mal passé avec react. Alors, aviez-vous essayé de construire aveccreate-react-app
etreact-scripts
?Réponses:
Il semble que
microbundler
cela ne tolère pas de réagir. Celui-ci crée un bundle qui tente d'utiliser àreact
partir de la portée globale, au lieu deReact
cela vraiment exposé.Pour la même raison, votre solution de contournement
React.useEffect
fonctionne comme prévu, imaginez simplement à quoi cela ressemblewindow.React.useEffect
.Voici un exemple d'application primitive:
Après le regroupement avec juste
microbundle
complètement cassé, mais lorsque vous essayez de regrouper aveccomme le suggère correctement @Jee Mok, il produira un ensemble correct. J'espère que les commentaires expliqueront ce qui s'est passé.
Et, soit dit en passant, "importation restructurée" pas du tout à blâmer.
la source