node.js - Ugyldig hook-kall på npm-link-bibliotek
Problembeskrivelse:
Jeg holder for øyeblikket på å lage en pakke kalt
eformlessJeg har brukt CRA til å lage en katalog kalt
sandbox, hvor jeg koblet pakken.Jeg får stadig følgende feil når jeg prøver å starte sandbox React-appen med den tilknyttede pakken som jeg prøver å teste:
// inside my 'sandbox' App.tsx import React from 'react' import { useField } from 'eformless' const App = () => { const [test, handleChange] = useField('testing') return ( <input type="text" value={test.value} onChange={handleChange} /> ) }
Feil: Ugyldig hook-kall. Hooks kan kun kalles inne i kroppen til en funksjonskomponent. Dette kan skje av en av følgende grunner:
- Du kan ha ulike versjoner av React og renderer (for eksempel React DOM)
- Du kan bryte Regler for Hooks
- Du kan ha mer enn én kopi av React i samme app. Se endret lenke på grunn av Stack Overflow sine bruksvilkår for tips om hvordan du kan feilsøke og fikse dette problemet.
Hvor problemet oppstår:
Problemet ser ut til å peke på biblioteket mitt, der jeg har skrevet en tilpasset hook som bruker hooks importert fra React.
Her er det problematiske utdraget fra koden min:
export const useField = <T>(
input: T
...checkFunctions: Array<(...args: unknown[]) => unknown>
): [FieldType<T>, FieldHandlerFunction<T>, FieldHandlerFunction<T>] => {
const [value, setValue] = useState(input)
const [name, setName] = useState('')
// Issue seems to be here ^
}
Oppsettet mitt var ganske normalt og ser ut til å fungere bra i andre prosjekter:
- Først bundlet jeg biblioteket mitt via
rollup -c - Opprettet en lenke inne i min
eformless-bibliotekmappe vianpm link - Og opprettet symlinken inne i
sandbox-mappen min vianpm link eformless
Det jeg prøvde:
Jeg prøvde naturlig å løse problemet via lenken som ble gitt i feilmeldingen. Dette ser ut til å være et problem når man lenker til sitt eget bibliotek, som nevnt her
Dette problemet kan også oppstå når du bruker npm link eller en tilsvarende kommando. I så fall kan din bundler «se» to React-versjoner — en i applikasjonsmappen og en i bibliotekmappen din. Forutsatt at myapp og mylib er søstermapper, er en mulig løsning å kjøre npm link ../myapp/node_modules/react fra mylib. Dette bør få biblioteket til å bruke applikasjonens kopi av React.
Jeg kjørte npm link ../sandbox/node_modules/react i min eformless-mappe, men dette virket ikke å hjelpe, selv etter å ha stengt node-serveren og kompilert på nytt.
Uansett virker det virkelig forvirrende for meg, fordi å kjøre npm ls react bare viser en enkelt versjon av react og det burde være gyldig, gitt at useState brukes på øverste nivå inne i en egendefinert hook.
Reprodusere problemet
Begge lagringsstedene er offentlige
eformlessbibliotekreposandboxrepo
Svar #1
- Du kan ha mer enn én kopi av React i samme app. Se endret lenke på grunn av Stack Overflow sine bruksvilkår for tips om hvordan du kan feilsøke og fikse dette problemet.
Det er fordi du har react i dine devDependencies for eformless. Dette får applikasjonen din til å kjøre to forekomster av React.
I stedet, flytt react til peer dependencies i eformless package.json, slett node_modules-mappen din og kjør npm install.
Ved å legge til react i peer-avhengigheter, informerer du modulbundleren din om å ikke inkludere react, men i stedet forvente at react vil bli gjort tilgjengelig for den av den avhengige applikasjonen.
"peerDependencies": {
"react": "^16.13.1"
}
Jeg la også merke til at du hadde sjekket inn node_modules-katalogen din i eformless. Det bør du ikke gjøre. I stedet bør du legge til node_modules i .gitignore-filen din.
Svar #2
Bare i tilfelle det er nyttig for andre, brukte jeg allerede React som en 'peer-avhengighet' i biblioteket mitt, og fikk fortsatt dette problemet.
Jeg måtte utføre følgende trinn for å løse det:
På biblioteket:
- Hvis du ikke har gjort det allerede, sett opp bibliotekene som genererer problemer som
peerDependenciesipackage.jsoni stedet fordependenciesellerdevDependencies, for eksempel i mitt tilfellereact:
"peerDependencies": {
"react": "^16.8.6",
...
}
- kjør
npm install - bygg biblioteket (i mitt tilfelle, med et
rollup -cnpm-skript)
I hovedappen min:
- endre versjonen av biblioteket mitt for å peke til mitt lokale prosjekt med en relativ sti i
package.json, f.eks.
"dependencies": {
"my-library": "file:../../libraries/my-library",
...
}
Legg til
resolve.symlinks=falsei hovedapplikasjonens webpack-konfigurasjonLegg til
--preserve-symlinks-mainog--preserve-symlinksi minpackage.jsonstartskript, f.eks:
"scripts": {
"build": "set WEBPACK_CONFIG_FILE=all&& webpack",
"start": "set WEBPACK_CONFIG_FILE=all&& webpack && node --preserve-symlinks-main --preserve-symlinks dist/server.js",
}
- kjør
npm install - kjør
npm run start
