typescript - Fel: Kan inte hitta modul .../node_modules/next/link importerad från ... Menade du att importera .../node_modules/next/link.js?
Jag försöker paketera ett React-komponentbibliotek för min Next.js-app men jag kan inte lista ut vad som orsakar följande fel. Jag har tillbringat de senaste dagarna med att prova olika konfigurationer av Rollup, TS-kompilatorn och package.json men jag känner att jag helt enkelt saknar viss erfarenhet och någon viktig kunskapsbit här, eftersom jag egentligen inte förstår vad felmeddelandeloggen försöker säga mig.
Server Error
Error: Cannot find module '/home/ola/Projects/lifeitself/flowershow/node_modules/.pnpm/file+packages+core+flowershow-core-0.0.4.tgz_wwvq4sry3mrfcince3djb3idna/node_modules/next/link' imported from /home/ola/Projects/lifeitself/flowershow/node_modules/.pnpm/file+packages+core+flowershow-core-0.0.4.tgz_wwvq4sry3mrfcince3djb3idna/node_modules/@flowershow/core/dist/index2.js
Did you mean to import [email _biqbaboplfbrettd7655fr4n2y/node_modules/next/link.js?
This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
new NodeError
node:internal/errors (387:5)
finalizeResolution
node:internal/modules/esm/resolve (330:11)
moduleResolve
node:internal/modules/esm/resolve (907:10)
defaultResolve
node:internal/modules/esm/resolve (1115:11)
nextResolve
node:internal/modules/esm/loader (163:28)
ESMLoader.resolve
node:internal/modules/esm/loader (837:30)
ESMLoader.getModuleJob
node:internal/modules/esm/loader (424:18)
ModuleWrap.<anonymous>
node:internal/modules/esm/module_job (76:40)
link
node:internal/modules/esm/module_job (75:36)
Sammanhang :
@flowershow/coreär paketet för komponentbiblioteket skrivet i TS@flowershow/coreär ett beroende av `@flowershow/template`- hela arkivet är ett monorepo byggt med Nx (https://github.com/flowershow/flowershow), och det inkluderar både
coreochtemplate-paketet, med följande struktur (förenklad):
flowershow
├── packages
│ ├── ...
│ ├── core
| | ├── src
| | ├── project.json (Nx file)
| | ├── tsconfig.json
| | └── package.json
│ └── template
| ├── ... pretty standard Next.js app contents
| ├── project.json (Nx file)
| └── package.json
├── nx.json
├── package.json
├── pnpm-workspace.yaml
└── tsconfig.base.json
Relevanta konfigurationsfiler för @flowershow/core
package.json:
{
"name": "@flowershow/core",
"version": "0.0.4",
"description": "Core Flowershow components, configs and utils.",
"repository": {
"type": "git",
"url": "git+https://github.com/flowershow/flowershow.git",
"directory": "packages/core"
},
"author": "Rufus Pollock",
"license": "MIT",
"bugs": {
"url": "https://github.com/flowershow/flowershow/issues"
},
"homepage": "https://github.com/flowershow/flowershow#readme",
"publishConfig": {
"access": "public"
},
"type": "module",
"main": "./dist/index.js",
"dependencies": {
"@docsearch/react": "^3.3.0",
"@headlessui/react": "^1.7.6",
"clsx": "^1.2.1",
"kbar": "0.1.0-beta.39",
"mdx-mermaid": "^1.3.2",
"mermaid": "^9.3.0"
},
"peerDependencies": {
"next": "^13.0.0",
"next-contentlayer": "^0.2.9",
"next-themes": "^0.2.1",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
project.json (Nxs konfigurationsfil):
{
"name": "core",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/core/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"executor": "@nrwl/web:rollup",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "packages/core/dist",
"tsConfig": "packages/core/tsconfig.lib.json",
"project": "packages/core/package.json",
"entryFile": "packages/core/src/index.ts",
"format": ["esm", "cjs"],
"external": [
"react/jsx-runtime",
"react",
"next",
"next-contentlayer",
"next-themes"
],
"generateExportsField": true,
"rollupConfig": "@nrwl/react/plugins/bundle-rollup",
"compiler": "babel",
"assets": [
{
"glob": "packages/core/README.md",
"input": ".",
"output": "."
}
]
}
},
...
}
}
tsconfig.json:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react-jsx",
"module": "es2020",
"moduleResolution": "node",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": false,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
tsconfig.lib.json:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"types": ["node"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"jest.config.ts",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}
Produktion av dist/index.js-filen, med importen klagar Next på:
export { e as BlogLayout, B as BlogsList, C as CustomLink, D as DocsLayout, L as Layout, N as Nav, P as Pre, S as SearchProvider, d as SimpleLayout, U as UnstyledLayout, g as collectHeadings, p as pageview } from './index2.js';
import 'react/jsx-runtime';
import 'react';
import 'next/link';
import 'next-themes';
import 'next/dynamic';
import '@headlessui/react';
import 'next/router';
import 'next/head';
import 'mdx-mermaid/lib/Mermaid';
import 'clsx';
Hur testar jag detta:
För att testa detta packar jag core-paketet och installerar det med hjälp av utdatafilen tgz i template, med hjälp av "file:"-protokollet som följer:
(packages/template/package.json)
"dependencies": {
"@flowershow/core": "file:../core/flowershow-core-0.0.4.tgz",
Annan information
Jag har försökt ändra importuttrycket manuellt från import 'next/link' till import 'next/link.js' och det verkade fungera (förutom att felet då kastades för ett annat importerat bibliotek).
Jag är också inte riktigt säker på varför Rollup producerar alla deras importdeklarationer under exporten, så jag skulle vara oerhört tacksam för någon ledtråd här också. Jag är ganska ny på detta och det är första gången jag använder Rollup eller någon annan bundler för att paketera mitt eget bibliotek.
Här är hela kodbasen: https://github.com/flowershow/flowershow
Jag har stött på detta problem med ett liknande problem som någon annan hade: Fel [ERR_MODULE_NOT_FOUND]: Kan inte hitta modul
Jag har försökt pilla med TS-kompilatorns konfiguration, Rollup-konfiguration och olika package.json-fältvärden (t.ex. lägga till/ta bort type: module i core-paketet) men utan framgång.
Och att lägga till filändelser i importuttalanden är inte ett alternativ här eftersom dessa genereras automatiskt av Rollup.
Svar #1
Jag har också varit i kaninhålet kring detta på sistone. Jag tror att denna smärta är ett resultat av en felkonfiguration i Next.js själv när det gäller att exportera korrekta typer för ESModules. Se detta GitHub-ärende som länkar till 3 fler GitHub-ärenden som förklarar historien lite: https://github.com/vercel/next.js/issues/46676#issuecomment-1451731653
Såvitt jag förstår kan Next.js-kompilatorn ta dina importerade moduler och paketera dem åt dig. Det brukade finnas ett next-transpile-modules-plugin för next.config som nu är inbyggt: https://nextjs.org/blog/next-13-1#built-in-module-transpilation-stable. När jag lade till mitt paket i denna array i konfigurationen kunde jag få saker att köra i utvecklingsläge, men byggläge misslyckades oavsett vad jag försökte.
Så förhoppningsvis kommer detta problem att åtgärdas uppströms snart, och om det inte är ett problem där kommer det att finnas någon vägledning om hur man paketerar ett komponentbibliotek för Next.js eftersom jag har en liknande erfarenhet där saker inte verkar fungera som avsett.
redigera: Efter att ha experimenterat lite mer verkar det som att boven är "type: module" i package.json för komponentbiblioteket. Kanske finns det ett sätt att få det att fungera, men när du bygger din nästa app transpilerar den ändå allt till commonjs, så kanske det inte är så mycket värt att lägga energi på att bunta komponentbiblioteket utan bara publicera en entrypoint och låta Next.js sköta resten? Inte ett tillfredsställande svar men det har varit det enda sättet jag har kunnat köra i bygg- och utvecklingsläge.