依存関係としてlocate-pathを持つ人気のあるfind- upnpmパッケージを使用しています。 locate-path
は、コード内にfs
が必要です。
アプリを実行しようとすると、次のエラーメッセージが表示されます。
[ error ] ./node_modules/locate-path/index.js
Module not found: Can't resolve 'fs' in 'C:\...\node_modules\locate-path'
Could not find files for /index in .next/build-manifest.json
Promise { <pending> }
ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in 'C:\...\node_modules\locate-path'
at factory.create (C:\...\node_modules\webpack\lib\Compilation.js:823:10)
at factory (C:\...\node_modules\webpack\lib\NormalModuleFactory.js:397:22)
at resolver (C:\...\node_modules\webpack\lib\NormalModuleFactory.js:130:21)
at asyncLib.parallel (C:\...\node_modules\webpack\lib\NormalModuleFactory.js:224:22)
at C:\...\node_modules\neo-async\async.js:2830:7
at C:\...\node_modules\neo-async\async.js:6877:13
at normalResolver.resolve (C:\...\node_modules\webpack\lib\NormalModuleFactory.js:214:25)
at doResolve (C:\...\node_modules\enhanced-resolve\lib\Resolver.js:184:12)
at hook.callAsync (C:\...\node_modules\enhanced-resolve\lib\Resolver.js:238:5)
at _fn0 (eval at create (C:\...\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:15:1)
at resolver.doResolve (C:\...\node_modules\enhanced-resolve\lib\UnsafeCachePlugin.js:37:5)
at hook.callAsync (C:\...\node_modules\enhanced-resolve\lib\Resolver.js:238:5)
at _fn0 (eval at create (C:\...\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:15:1)
at hook.callAsync (C:\...\node_modules\enhanced-resolve\lib\Resolver.js:238:5)
at _fn0 (eval at create (C:\...\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:27:1)
at resolver.doResolve (C:\...\node_modules\enhanced-resolve\lib\DescriptionFilePlugin.js:42:38)
私はlocate-pathリポジトリに問題を作成しましたが、問題が彼らにあるのではなく、おそらくwebpackにあることを確認しました。 アプリでwebpackを使用していないため、Next.jsでのwebpackの使用が原因で問題が発生している可能性があります。
https://github.com/TidyIQ/nextjs-issueのクローンを作成し、 npm run dev
ます。
問題ない
getStaticProps
またはgetServerSideProps
内でfs
を安全に使用でき、追加の構成は必要ありません。 データライフサイクルで変数を参照していることを確認してください。そうすることで、変数が正しくツリーシェイクされます。
このツールを使用して
getInitialProps
レガシーNext.jsバージョンをまだ構築している場合は、以下をお読みください👇
提供されたコードは無効です。このファイルは、レンダリング中にクライアント側で使用できることはありません。
FS関連の操作は、_サーバー上_でのみ実行できることを忘れないでください。 これは、レンダリング中にfs
を使用できないことを意味します。
fs
を使用する場合は、 getInitialProps
以内にあることを確認してください。
クライアントバンドルをビルドするには、次のコンテンツを含むnext.config.js
ファイルを作成する必要がある場合もあります。
module.exports = {
webpack: (config, { isServer }) => {
// Fixes npm packages that depend on `fs` module
if (!isServer) {
config.node = {
fs: 'empty'
}
}
return config
}
}
ローカルの実質的にバニラのインストールでも同じ問題が発生しますが、nextjsの例では、これは問題ではないようです。
https://github.com/zeit/next.js/tree/5787cbd9de33ea9add7cadeb04689b0d4b02976d/examples/blog-starter
設定ファイルを変更せずにそこで機能する理由は何ですか?
getStaticProps / getServerSidePropsではfs
のみを使用してください。これらは、ブラウザーバンドルから削除されます。
私は問題が何であるかを知りました。 fs
使用する関数をインポートしたが、getStaticProps内でその関数を実行/使用しない場合、その関数はブラウザーバンドルに含まれることになります。 関数がgetStaticProps内で参照されると、ブラウザーバンドルに表示されなくなります。
getStaticPropsで使用されているが、メインのエクスポートでは使用されていないインポートを削除する隠しロジックがあると思います。 再現できるようになるまでデバッグに数時間を費やしました。ドキュメントのどこかに補足説明を付ける価値があるかもしれません:)
隠されたロジックは、webpackのツリーが揺れているだけではありませんか? 考えてみると、NextはブラウザバンドルにgetStaticProps
をインポートしないため、そこで使用されているインポートされた関数を削除します。
どこにも参照していない場合、webpackは副作用のためにインポートしたと見なすため、すべてのバンドルに含まれていると思います。
隠されたロジックは、webpackのツリーが揺れているだけではありませんか? 考えてみると、Nextはブラウザバンドルに
getStaticProps
をインポートしないため、そこで使用されているインポートされた関数を削除します。どこにも参照していない場合、webpackは副作用のためにインポートしたと見なすため、すべてのバンドルに含まれていると思います。
いいえ、webpackツリーの揺れは、これらのエクスポートをそのように揺さぶるほど洗練されていません。 ツリーの揺れgetStaticProps / getServerSideProps / getStaticPathsは、作成したこのカスタムBabelプラグインによって処理されます: https :
ポインタをありがとう、私はwebpackを過大評価したようです:)
これが_within _ getServerSideProps
から発生する理由
こんにちは、みんな。 @aloukissasのように、 index.js
getStaticProps()
内でdotenv
を使用する場合にも同じ問題が発生します。 @Timerの最初のコメントに示されているように、 next.config.js
ファイルを追加すると解決されます。
なぜこれが起こっているのか手がかりはありますか? Next.js
v.9.4.0を歌っていません
ありがとう!
fast-glob
使用中にこのエラーが発生しました。
この優れたツールを使用して、クライアント側にバンドルされるコードを理解しました。
内部でfs
を使用するfast-glob
を使用するファイルから変数をインポートしていましたが、 getStaticProps
内のどこにも変数を使用していなかったため、ファイルはfast-glob
インポートします。
例:
import glob from 'fast-glob'
import path from 'path'
export const BLOG_PATH = path.join(process.cwd(), 'posts')
export const blogFilePaths = glob.sync(`${BLOG_PATH}/blog/**/*.mdx`)
import { BLOG_PATH, blogFilePaths } from './mdxUtils'
export const getStaticProps = () => {
const posts = blogFilePaths.map((filePath) => {
...
}
return { props: { posts } }
}
ご覧のとおり、 index.js
どこでもBLOG_PATH
を使用していませんが、インポートしています。 blogFilePaths
のみを使用しているため、このエラーが発生しました。
詳細については→ https://github.com/vercel/next.js/discussions/17138
ありがとう@ deadcoder0904これは私のコードです:
import Layout from '../components/template'
import Main from '../components/main'
import Menu from '../components/menu'
import 'dotenv/config'
export async function getStaticProps () {
const avatarLocation = process.env.AVATAR_URL
const avatarTitle = process.env.AVATAR_TITLE
return {
props: {
avatarLocation,
avatarTitle
}
}
}
export default function RenderMainPage ({ avatarLocation, avatarTitle }) {
return (
<Layout
avatarURL={avatarLocation}
topLeft={<Menu />}
middle={<Main avatarURL={avatarLocation} avatarTitle={avatarTitle} />}
/>
)
}
あなたが言及したツールは、 import 'dotenv/config'
がクライアントコードに含まれていることを示しており、おそらくそれがエラーを引き起こしています。 問題は、環境変数から読み取るために必要なことです。
おそらくそれを行うための別のより良い方法があります、私はまだNext.jsを学んでいます:)
@ ig-perez Next v9.4以降、環境変数をロードする方法が組み込まれています→ https: //nextjs.org/docs/basic-features/environment-variables
ドキュメントを読んで解決策を見つけることをお勧めします:)
それは素晴らしいです、私はドキュメントのその部分を逃しました、ありがとう! コードを更新します👍🏽
最も参考になるコメント
最新のNext.js(9.4以降)の更新
getStaticProps
またはgetServerSideProps
内でfs
を安全に使用でき、追加の構成は必要ありません。 データライフサイクルで変数を参照していることを確認してください。そうすることで、変数が正しくツリーシェイクされます。このツールを使用して
getInitialProps
レガシーNext.jsバージョンをまだ構築している場合は、以下をお読みください👇提供されたコードは無効です。このファイルは、レンダリング中にクライアント側で使用できることはありません。
https://github.com/TidyIQ/nextjs-issue/blob/aef67b12d91d299d0978550005a40cbb34f74b71/pages/index.js#L5
FS関連の操作は、_サーバー上_でのみ実行できることを忘れないでください。 これは、レンダリング中に
fs
を使用できないことを意味します。fs
を使用する場合は、getInitialProps
以内にあることを確認してください。クライアントバンドルをビルドするには、次のコンテンツを含む
next.config.js
ファイルを作成する必要がある場合もあります。