λλ μΈκΈ°κ° μ¬μ©νκ³ λ°κ²¬ μ
μ΄ NPM ν¨ν€μ§, μμΉ κ²½λ‘ μμ‘΄μ± λ±μ. 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)
λλ μμΉ μ°ΎκΈ° 리ν¬μ§ν 리
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μμ μ¬μ©λμ§λ§ κΈ°λ³Έ λ΄λ³΄λ΄κΈ°μμλ μ¬μ©λμ§ μλ κ°μ Έμ€κΈ°λ₯Ό μ κ±°νλ μ¨κ²¨μ§ λ Όλ¦¬κ° μλ κ² κ°μ΅λλ€. μ¬νν μ μμ λκΉμ§ λλ²κΉ μ λͺ μκ°μ 보λμ΅λλ€. λ¬Έμ μ΄λκ°μ μ°Έκ³ ν κ°μΉκ° μμ κ²μ λλ€. :)
νλ λ‘μ§μ κ·Έλ₯ μΉν©μ νΈλ¦¬ λ¨λ¦Ό μλκ°μ? μκ°ν λ μλ―Έκ° μμ΅λλ€. Nextλ λΈλΌμ°μ λ²λ€μμ getStaticProps
λ₯Ό κ°μ Έμ€μ§ μμΌλ―λ‘ μ¬κΈ°μ μ¬μ©λ κ°μ Έμ¨ κΈ°λ₯μ μ κ±°ν©λλ€.
μ무λ°λ μ°Έμ‘°νμ§ μμΌλ©΄ webpackμ΄ λΆμμ©μ μν΄ κ°μ Έμ¨ κ²μΌλ‘ κ°μ£Όνλ―λ‘ λͺ¨λ λ²λ€μ μ¬μ ν ν¬ν¨λ©λλ€.
νλ λ‘μ§μ κ·Έλ₯ μΉν©μ νΈλ¦¬ λ¨λ¦Ό μλκ°μ? μκ°ν λ μλ―Έκ° μμ΅λλ€. Nextλ λΈλΌμ°μ λ²λ€μμ
getStaticProps
λ₯Ό κ°μ Έμ€μ§ μμΌλ―λ‘ μ¬κΈ°μ μ¬μ©λ κ°μ Έμ¨ κΈ°λ₯μ μ κ±°ν©λλ€.μ무λ°λ μ°Έμ‘°νμ§ μμΌλ©΄ webpackμ΄ λΆμμ©μ μν΄ κ°μ Έμ¨ κ²μΌλ‘ κ°μ£Όνλ―λ‘ λͺ¨λ λ²λ€μ μ¬μ ν ν¬ν¨λ©λλ€.
μλμ, μΉν© νΈλ¦¬ μμ΄νΉμ μ΄λ¬ν λ΄λ³΄λ΄κΈ°λ₯Ό κ·Έλ° μμΌλ‘ νλ€ λ§νΌ μ κ΅νμ§ μμ΅λλ€. νΈλ¦¬ μμ΄νΉ getStaticProps / getServerSideProps / getStaticPathsλ μ°λ¦¬κ° λ§λ μ΄ μ»€μ€ν Babel νλ¬κ·ΈμΈμ μν΄ μ²λ¦¬λ©λλ€: https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform .ts
μ€ ν¬μΈν° μ£Όμ μ κ°μ¬ν©λλ€. μΉν©μ κ³Όλ νκ° ν κ² κ°μ΅λλ€. :)
μ΄κ²μ΄ _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 } }
}
λΉμ μ λ΄κ° μ¬μ©νμ§ μλκ±°μΌ λ³Ό μ μλ―μ΄ BLOG_PATH
μ΄λμμ index.js
νμ§λ§ μ¬μ ν κ·Έκ²μ κ°μ Έ. λλ 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'
κ° ν΄λΌμ΄μΈνΈ μ½λμ ν¬ν¨λμ΄ μμΌλ©° μλ§λ μ€λ₯λ₯Ό νμνκ³ μλ κ²μΌλ‘ 보μ
λλ€. λ¬Έμ λ env λ³μμμ μ½κΈ° μν΄ νμνλ€λ κ²μ
λλ€.
μλ§λ λ€λ₯Έ λ λμ λ°©λ²μ΄ μμ κ²μ λλ€. μ λ μ¬μ ν 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
νμΌμ μμ±ν΄μΌ ν μλ μμ΅λλ€.