Next.js: 9.0.6์—์„œ ์ž˜๋ชป๋œ ํ›„ํฌ ํ˜ธ์ถœ

์— ๋งŒ๋“  2019๋…„ 10์›” 10์ผ  ยท  74์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: vercel/next.js

๋ฒ„๊ทธ ์‹ ๊ณ 

๋ฒ„๊ทธ ์„ค๋ช…

ํ›„ํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ณธ Next.js ํ”„๋กœ์ ํŠธ ํด๋” ์™ธ๋ถ€์—์žˆ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ฐ˜์‘ ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Invalid hook call ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ํ›„ํฌ๊ฐ€์—†๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ํด๋” ์™ธ๋ถ€์˜ ํŒŒ์ผ์ด ํŠธ๋žœ์Šค ํŒŒ์ผ๋˜๋„๋ก webpack ๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ•  ๋•Œ ๋ชจ๋“  ๋ฒ„์ „ >9.0.5 ์—์„œ ๋ฒ„๊ทธ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. <=9.0.5 ์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์žฌํ˜„ํ•˜๋ ค๋ฉด

https://github.com/baldurh/next-9.0.6-bug-repro ์—์„œ ์žฌํ˜„์„ ํ™•์ธ

์˜ˆ์ƒ๋˜๋Š” ํ–‰๋™

ํ”„๋กœ์ ํŠธ ํด๋” ์™ธ๋ถ€์˜ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•  ๋•Œ ์ฝ”๋“œ๊ฐ€ ๊นจ์ง€์ง€ ์•Š์•„์•ผํ•ฉ๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ์ •๋ณด

  • ์šด์˜์ฒด์ œ : N / A
  • ๋ธŒ๋ผ์šฐ์ € : N / A
  • Next.js ๋ฒ„์ „ : >=9.0.6

์ถ”๊ฐ€ ์ปจํ…์ŠคํŠธ

๋‚˜๋Š” ์ด๊ฒƒ์ด ์•„๋งˆ๋„ Next.js์˜ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” monorepo๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์—ฌ๋Ÿฌ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€์žˆ๋Š” ๊ณต์œ  ํด๋”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ๋‹ค์‹œ ์ˆ˜ํ–‰ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ๋Œ€์ฒด ๊ตฌ์„ฑ์„ ์ฐพ์œผ๋ฉด ์ €๋„ ๊ธฐ๊บผ์ด ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค ๐Ÿ™‚

story 3 needs investigation

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์•ˆ๋…•ํ•˜์„ธ์š”์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์šฐ๋ฆฌ๋Š” monorepo๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ์ด ์ •ํ™•ํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  74 ๋Œ“๊ธ€

@baldurh ์ด๊ฒƒ์€ ๋งค์šฐ ๋“œ๋ฌธ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. Now์™€ ๊ฐ™์€ ํ”Œ๋žซํผ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” Next.js ์•ฑ์ด์žˆ๋Š” ํด๋” ๋งŒ ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ์™ธ๋ถ€ ๋ชจ๋“ˆ์— ๋Œ€ํ•ด ๋จผ์ € ์•Œ์•„์•ผํ•˜๋ฏ€๋กœ ๊ทธ๋ ‡๊ฒŒํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ๋” ๋‚˜์€ ๋Œ€์•ˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋ชจ๋“  ๊ฒƒ์„ ๋‹จ์ผ Next.js ์•ฑ์œผ๋กœ ์ด๋™
  • lerna ๋˜๋Š” ๊ฐœ์ธ npm ํŒจํ‚ค์ง€ ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ์‚ฌ์šฉ

@lfades ๋‹ต์žฅ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜ต์…˜ ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ Now ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์— ๋ฐฐํฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ์‹ค ์ž‘์—… ๊ณต๊ฐ„์„ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ bazel์„ ํ†ตํ•ฉํ–ˆ๋Š”๋ฐ ์‹ค ์ž‘์—… ๊ณต๊ฐ„์˜ ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ํŠน์„ฑ๊ณผ โ€‹โ€‹์ž˜ ์–ด์šธ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Npm ํŒจํ‚ค์ง€๋Š” ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š”๋งŒํผ ๋นจ๋ฆฌ ๊ณต์œ  ๋ชจ๋“ˆ์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฒ„ ํ—ค๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค.

@baldurh ์ค‘์ฒฉ ๋œ NextJs ์•ฑ์„ ์˜ˆ๋กœ ๋“ค์—ˆ ๊ธฐ ๋•Œ๋ฌธ์—

@isaachinman ์šฐ๋ฆฌ๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์•„์ง ๋‹ค๋ฅธ ์ด์œ ๋กœ 9.x๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์กฐ์‚ฌํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋“ ์ง€ ์ด๊ฒƒ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์ฝ”๋“œ๊ฐ€ ์–ด๋””์— ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋ฌธ์ œ๋ฅผ ๋” ์ž˜ ์ดํ•ดํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์•„์ง์ด ๋ฌธ์ œ๋ฅผ ํŒŒํ—ค์น  ์‹œ๊ฐ„์ด ์—†์—ˆ์ง€๋งŒ ๋ˆ„๊ตฐ๊ฐ€ ์žฌํ˜„์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณต์ œํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. cd ๋ฅผ examples/simple ์— ๋ณต์ œํ•˜๊ณ  NextJs ๋ฒ„์ „์„> = 9.0.6์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ 9.0.3์— ์žˆ์œผ๋ฏ€๋กœ ๊ธฐ์ˆ ์  ์œผ๋กœ ํŒจ์น˜์˜ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

์ตœ๊ทผ์— ๋น„์Šทํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ 9.0.5 (๋ฐ React 16.8.x)๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” Next์˜ MDX ์‚ฌ์šฉ์— ๋Œ€ํ•ด ๋‚ด๊ฐ€ ๋ณธ ๋ฌธ์ œ๋ฅผ ์ขํ˜”์ง€๋งŒ ๊ทธ ์ด์ƒ์˜ ๊ตฌ์ฒด์ ์ธ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ์—†์Šต๋‹ˆ๋‹ค.

Next & next-i18next๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๊ฝค ํฐ ํ”„๋กœ์ ํŠธ๋กœ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํŒŒํ—ค ์ณค์Šต๋‹ˆ๋‹ค.

์ด ์˜ค๋ฅ˜๋Š” ์„ธ ๊ฐ€์ง€ ์ด์œ ๋กœ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

  1. ์ž˜๋ชป ์ •๋ ฌ ๋œ react ๋ฐ react-dom ๋ฒ„์ „-๋‚ด ์•ฑ์— ์ ์šฉ๋˜์ง€ ์•Š์Œ
  2. 2 ๊ฐœ ๋ฒ„์ „์˜ react-dom ๊ฐ€์ ธ ์˜ค๊ธฐ-๋‚ด ์•ฑ์— ์ ์šฉ๋˜์ง€ ์•Š์Œ
  3. React ํ›„ํฌ์˜ ๋ถ€์ ์ ˆํ•œ ์‚ฌ์šฉ-ํ›„ํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์ง€๋งŒ ์ผ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์‚ฌ์šฉํ•˜๋ฉฐ ๋‹ค๋ฅธ ๋ชจ๋“  ์‚ฌ์šฉ์ž์—๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์ด์ƒํ•œ ์ ์€ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ์—์„œ๋งŒ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@timneutkens @Timer ์— ํƒœ๊ทธ๋ฅผ ๋‹ฌ์•„ ์ฃผ์…”์„œ ์ฃ„์†ก ํ•ฉ๋‹ˆ๋‹ค๋งŒ ์—ฌ๋Ÿฌ๋ถ„์˜ ์˜๊ฒฌ์„ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? ์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ๋ช‡ ๊ฐ€์ง€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๊ตฌํ˜„ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ํ˜„์žฌ ์šฐ๋ฆฌ์—๊ฒŒ ๋งค์šฐ ํฐ ์ฐจ๋‹จ์ œ์ž…๋‹ˆ๋‹ค. ๊ฐ์‚ฌ.

๋ณ„์นญ์ด react ์ด์ง€๋งŒ react-dom ์•„๋‹Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@ ํƒ€์ด๋จธ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์‹œ๋„ํ–ˆ์ง€๋งŒ ํšจ๊ณผ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค

react ๋ฐ react-dom ์ข…์†์„ฑ์„ ํ•œ ์ˆ˜์ค€ ์œ„๋กœ ์ด๋™ํ•˜์—ฌ ์žฌํ˜„ ์—์„œ ๋ฐฉ๊ธˆ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์‹œ๋„ํ•ด๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐ€์–ด ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๊ทธ๊ฒƒ์ด ์šฐ๋ฆฌ์—๊ฒŒ ํšจ๊ณผ๊ฐ€ ์žˆ๊ธฐ๋ฅผ ํฌ๋งํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด๊ฒƒ์€ @isaachinman , @jaredcwhite ๋ฐ @felixmosh ์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@Timer ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ–ˆ์ง€๋งŒ react ๋ฅผ ํ”„๋กœ์ ํŠธ์˜ node_modules ํด๋”์— ์„ค์น˜ํ•˜๋Š” ๋‹ค๋ฅธ ์ข…์†์„ฑ์ด ์—†๋Š”์ง€ ํ™•์ธํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ์—๋Š” ์Šคํ† ๋ฆฌ ๋ถ๊ณผ ๊ด€๋ จ์ด์žˆ์—ˆ์Šต๋‹ˆ๋‹ค ( yarn why react ๋Š” ๋งŽ์€ ๋„์›€์ด๋˜์—ˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜„). ์–ด์จŒ๋“  ์Šคํ† ๋ฆฌ ๋ถ์„ ๋ณ„๋„์˜ ํ”„๋กœ์ ํŠธ๋กœ ์˜ฎ๊ธธ ๊ณ„ํš ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์—์ด ์†”๋ฃจ์…˜์ด ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ์— ํšจ๊ณผ๊ฐ€์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์•„ ์˜ˆ. ๋ถ€์ ์ ˆํ•˜๊ฒŒ ๊ฒŒ์‹œ ๋œ node_module ํŒจํ‚ค์ง€๋กœ ์ธํ•ด์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค (ํ”ผ์–ด ์ข…์†์„ฑ ๋Œ€์‹  react(-dom|) ๋Œ€ํ•œ ์ข…์†์„ฑ ํฌํ•จ).

react ๋ฐ react-dom ์ข…์†์„ฑ์„ ํ•œ ์ˆ˜์ค€ ์œ„๋กœ ์ด๋™ํ•˜์—ฌ ์žฌํ˜„ ์—์„œ ๋ฐฉ๊ธˆ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์‹œ๋„ํ•ด๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐ€์–ด ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๊ทธ๊ฒƒ์ด ์šฐ๋ฆฌ์—๊ฒŒ ํšจ๊ณผ๊ฐ€ ์žˆ๊ธฐ๋ฅผ ํฌ๋งํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด๊ฒƒ์€ @isaachinman , @jaredcwhite ๋ฐ @felixmosh ์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ์ €์žฅ์†Œ์—์„œ ์ˆ˜ํ–‰ ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

npm ls react ๋˜๋Š” npm ls react-dom ๋ชฉ๋ก์— ๋‹ค์Œ ์•ฑ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.

@felixmosh ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์–ด์ œ ํ‘ธ์‹œ๊ฐ€ ์‹คํŒจํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜… react ๋ฐ react-dom ์„ (๋ฅผ) app ํด๋”์—์„œ ๋ฃจํŠธ ํด๋”๋กœ ์ด๋™ ํ–ˆ์œผ๋ฏ€๋กœ ์ด์ œ ๋‘˜ ๋‹ค์—์„œ yarn/npm install ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. app ํด๋”์™€ ๋ฃจํŠธ ํด๋”๋ฅผ ํ™•์ธํ•œ ํ›„ app ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ถฉ๋ถ„ํžˆ ๋ช…ํ™•ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

ํ”„๋กœ๋•์…˜์—์„œ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋ฏ€๋กœ์ด ์†”๋ฃจ์…˜์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์šฐ๋ฆฌ์—๊ฒŒ ์•ฝ๊ฐ„์˜ ๋ฒˆ๊ฑฐ ๋กœ์›€์ž…๋‹ˆ๋‹ค .๐Ÿ˜

์„ค๋ช… ๊ณ ๋ง™์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ํŒ€์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด ๋ชจ๋…ธ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์˜ ๋ฃจํŠธ์— ๋ฐ˜์‘ deps๋ฅผ ๋‘๋Š” ๊ฒƒ์ด ์•ฝ๊ฐ„ ์ด์ƒํ•˜๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

@felixmosh ๊ทธ๋ž˜, ๋‚˜๋Š” ๋‹น์‹ ์—๊ฒŒ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์›์‚ฌ ์ž‘์—… ๊ณต๊ฐ„๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋„๊ตฌ๊ฐ€ ์ •ํ™•ํžˆ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค. ๋‘ ๊ฐœ ์ด์ƒ์˜ ํ”„๋กœ์ ํŠธ์— ๋™์ผํ•œ ์ข…์†์„ฑ์ด์žˆ๋Š” ๊ฒฝ์šฐ ์ข…์†์„ฑ์„ ๋ฃจํŠธ์— ๊ฒŒ์–‘ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ ๋™์ผํ•œ ๋ฒ„์ „์˜ ์ข…์†์„ฑ์„ ๊ฐ–๋„๋ก ๋ณด์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋Ÿฐ ๋„๊ตฌ๊ฐ€ ์—†๋‹ค๋ฉด ์ง์ ‘ ๊ด€๋ฆฌํ•ด์•ผํ•˜๋Š”๋ฐ ์ด๋Š” ์ฐธ์œผ๋กœ ๋‹ค์†Œ ์–ด์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ์ตœ์„ ์˜ ํ•ด๊ฒฐ์ฑ…์€ Next.js ํŒ€์ด ์šฐ๋ฆฌ ๋ชจ๋‘๋ฅผ ์œ„ํ•ด์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜‡๐Ÿ™๐Ÿป

๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  react ๋ฐ react-dom ํ•œ ์ˆ˜์ค€ ์œ„๋กœ ๊ฐ€์ ธ์™€ ๋ฃจํŠธ์—์„œ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ํ˜„์žฌ 9.1.5์—์„œ ์ž‘๋™ํ•˜๋Š” ์œ ์ผํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ ์ด์ „์— ํ•ด๋‹น ๋งํฌ๋ฅผ ์ฐพ์•˜์œผ๋ฏ€๋กœ ์ฐธ์กฐ๋ฅผ ์œ„ํ•ด https://github.com/facebook/react/issues/13991 ๋ฐ https://github.com/facebook/react/issues/15315#issuecomment -479802153์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์šฐ๋ฆฌ๋Š” monorepo๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ์ด ์ •ํ™•ํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋งŒ๋‚˜์‹ญ์‹œ์˜ค.
v9.0.5๋Š” rootFolder ์™ธ๋ถ€์—์„œ ๊ฐ€์ ธ์˜จ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ํ›„ํฌ์™€ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

9.0.6๋ถ€ํ„ฐ 9.1.6-canary.5๊นŒ์ง€ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ์„œ๋ฒ„ ์ธก์—์„œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. SSR์ด ๋น„ํ™œ์„ฑํ™” ๋œ ๊ฒฝ์šฐ (์˜ˆ : dynamic์„ ํ†ตํ•ด ์™ธ๋ถ€ ๊ตฌ์„ฑ ์š”์†Œ๋กœ๋“œ) ๋ชจ๋“  ๋ฒ„์ „์ด> = 9.0.6 ์ธ ๊ฒฝ์šฐ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

@nodkz ๋ฐ˜์‘ ํŒจํ‚ค์ง€ ํ•ด๊ฒฐ ๋ฌธ์ œ์ด๋ฏ€๋กœ ๋…ธ๋“œ์—์„œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@Timer ์ด ๋ฌธ์ œ๋Š” ์•ฝ 6 ๊ฐœ ๋ฒ„์ „์˜ "๋‹ค์Œ"์ด์ •ํ‘œ๋กœ ์ด๋™ํ•˜์—ฌ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ•˜๋ฃจ ์ข…์ผ ์ˆ™๋ฐ• ์‹œ์„ค์— ์‹œ๊ฐ„์„ ๋‚ญ๋น„ํ–ˆ์œผ๋ฉฐ ๊ทธ ์›์ธ์ด ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅด๊ณ  ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค (์ž‘๋™ํ•˜์ง€ ์•Š์Œ).

๋ฐฉํ–ฅ์„ ์กฐ์‚ฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ํ•„์š”ํ•˜์‹ญ๋‹ˆ๊นŒ?
๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ง๊ฐ์ด ์žˆ์Šต๋‹ˆ๊นŒ?
ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ์—์„œ๋งŒ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
์ด์™€ ๊ด€๋ จ์ด์žˆ์„ ์ˆ˜์žˆ๋Š” 9.0.5 ์—์„œ 9.0.6 ๋กœ ๋ณ€๊ฒฝ๋œ ์‚ฌํ•ญ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๊ณ ๋ง™์Šต๋‹ˆ๋‹ค ๐Ÿ™๐Ÿผ

๋ฌธ์ œ๋ฅผ ์ฐพ์€ ๊ฒƒ ๊ฐ™์•„์š” !!!
๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋‘ ๊ฐ€์ง€์˜ ์กฐํ•ฉ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  1. node_modules์— ๋Œ€ํ•œ ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ์‚ฌ์šฉ
  2. i18next / react-i18next ์€ (๋Š”) ์„œ๋ฒ„ ๋ฒˆ๋“ค์˜ ์™ธ๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค !!
    image
    ์ œ ๊ฒฝ์šฐ์—๋Š” ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ์—์„œ ํญ๋ฐœ ํ•  ๋•Œ i18next useTranslation hook ...

๊ทธ๋ž˜์„œ ๋‚˜๋Š” ์™œ ์„œ๋ฒ„ ๋ฒˆ๋“ค ์•ˆ์— ๋…ธ๋“œ ๋ชจ๋“ˆ์ด ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์ด์œ ๋ฅผ ์กฐ์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค (์„œ๋ฒ„ ๋ฒˆ๋“ค์— ๋Œ€ํ•œ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋Š” ๊ทธ๊ฒƒ๋“ค์„ ์™ธ๋ถ€๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค).

๋‚˜๋Š” (์™œ?), ์žฌ๋ฏธ์žˆ๋Š” ๋ถ€๋ถ„์ด๋‹ค ๊ทธ ๋‹ค์Œ ๋‹ค์Œ lib ๋””๋ ‰ํ† ๋ฆฌ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์˜ˆ์™ธ๊ฐ€ ๋ณธ ์ด ์ •๊ทœ์‹์€ ๋ชจ๋“  libs์™€ ์žก๋Š”๋‹ค ๊ทธ๊ฒŒ ๋ next/dist/ ๋กœ, i18next & react-i18next ์•Š์Šต๋‹ˆ๋‹ค !!

๋”ฐ๋ผ์„œ ์ด๊ฒƒ์„ ๋ณ€๊ฒฝํ•˜๋ฉด :

res.match(/next[/\\]dist[/\\]/) 

์œผ๋กœ

res.match(/[/\\]next[/\\]dist[/\\]/) 

์„œ๋ฒ„ ๋ฒˆ๋“ค์€ next ์ด์™ธ์˜ ๋ชจ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ œ์™ธํ•˜๊ณ  next/dist ๋๋‚˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค!

์ €์—๊ฒŒ ์ฃผ์š” ๋ฌธ์ œ๋Š” ์š”์ฒญ์ด ํ•ด๊ฒฐ๋˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค : https://github.com/zeit/next.js/blob/canary/packages/next/build/webpack-config.ts#L446

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ์™ธ๋ถ€์— ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์š”์ฒญ ํ•ด๊ฒฐ์‹œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ react ๊ฐ€ ์„œ๋ฒ„ ์ฒญํฌ์— ๋ฒˆ๋“ค๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์„œ๋ฒ„์—์„œ Invalid hook call ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ํ•œ ์‹์˜ @baldurh context ๋Š” webpack์—์„œ ์ œ๊ณตํ•˜๋ฉฐ ์ปดํŒŒ์ผ ๋ฃจํŠธ (ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ)์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
ํ•ญ์ƒ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๋ฐœํ–‰ํ•˜๋Š” ํŒŒ์ผ์˜ ๋””๋ ‰ํ† ๋ฆฌ์ž…๋‹ˆ๋‹ค.

๊ถŒ๋ฆฌ. ์ง€๊ธˆ์€ ์šฐ๋ฆฌ๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•˜๋„๋ก ํŒจ์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ์ƒ์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ ์ˆ˜์ค€์—์„œ ์ข…์†์„ฑ์ด ๊ณต์œ ๋˜๋„๋ก ์ฝ”๋“œ์˜ ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ react ๊ฐ€ ์™ธ๋ถ€ ํด๋” (๋ฃจํŠธ ์™ธ๋ถ€)์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋”๋ผ๋„ ์—ฌ์ „ํžˆ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ๋œ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ ํ•˜๋Š”๋ฐ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์Šฌํ”„๊ฒŒ๋„ https://github.com/facebook/react/issues/13991 ์˜ ์ˆ˜์ • ์‚ฌํ•ญ์€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ๐Ÿ™

yarn link ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ๋œ ๊ตฌ์„ฑ ์š”์†Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ v9.0.6-canary.4 ๊นŒ์ง€ ์ž˜ ์ž‘๋™ํ–ˆ๊ณ  ์ง€๊ธˆ์€ ๋‹ค๋ฅธ ๋Œ“๊ธ€ ์ž‘์„ฑ์ž์™€ ๊ฐ™์€ ์œ„์น˜์— ์žˆ์œผ๋ฉฐ์ด ์ดํ›„๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค ..์ด PR์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ •ํ™•ํ•˜๊ฒŒ ์ง€์ ํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/zeit /next.js/pull/8739

๋‚ด ๊ตฌ์„ฑ ์š”์†Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” react , react-dom ๋ฐ styled-components ํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ๊ตฌ์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํŒจํ‚ค์ง€๋ฅผ devDependencies๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  peerDependencies์— ํฌํ•จํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋‚ด ์›นํŒฉ ๊ตฌ์„ฑ์— ํŒจํ‚ค์ง€๋ฅผ ์™ธ๋ถ€๋กœ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋‚ด ๋‹ค์Œ ๊ตฌ์„ฑ์—์„œ ์ด๋Ÿฌํ•œ ํŒจํ‚ค์ง€์— ํ•ด๊ฒฐ ๋ณ„์นญ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋‹ค์Œ ํŠธ๋žœ์Šค ํŒŒ์ผ ๋ชจ๋“ˆ๋กœ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋“ˆ์„ ํŠธ๋žœ์Šค ํŒŒ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  ์ •๋ณด

์ด ๋ชจ๋“ˆ์„ ์„œ๋ฒ„ ์™ธ๋ถ€์— ํฌํ•จ์‹œ์ผœ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋Œ“๊ธ€์— @HosseinAgha ๋•๋ถ„์— https://github.com/martpie/next-transpile-modules/issues/50#issuecomment -558318688

if (isServer) {
  config.externals = [
    'react',
    'react-dom',
    'styled-components',
    ...config.externals
  ]
}

๋˜‘๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ง€๊ธˆ๊นŒ์ง€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ํšจ๊ณผ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ํŒจํ‚ค์ง€๋Š” ๊ฒŒ์‹œํ•˜๊ณ  ์„ค์น˜ํ•˜๋ฉด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค (๊ทธ๋ฆฌ๊ณ  next.config.js์—์„œ resolve.alias ์‚ฌ์šฉ).

๊ทธ๋Ÿฌ๋‚˜ yarn link @mypackage ๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ๋œ ํŒจํ‚ค์ง€๋กœ ๊ฐœ๋ฐœ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํ•ญ์ƒ ์ž˜๋ชป๋œ ํ›„ํฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ node_modules/dist/build/wepack-config.js ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  https://github.com/zeit/next.js/pull/8739์— ์ถ”๊ฐ€ ๋œ ์ค„์„ ์ฃผ์„์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ž‘๋™์‹œํ‚ฌ ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

baseRes ๋ฐ res๋ฅผ ๊ธฐ๋กํ•˜๋ฉด ๋‚ด๊ฐ€ ๋ณด๋Š” ๊ฒƒ์€ if ์กฐ๊ฑด์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŠธ๋ฆฌ๊ฑฐ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • /myApp/node_modules/react/index.js! == /myApp/node_modules/myPackage/node_modules/react/index.js
  • ๋‚ด ์ดํ•ด์—์„œ ํŒŒ์ผ / ๋ฒ„์ „์ด 100 % ๋™์ผํ•˜๋”๋ผ๋„ ๊ฒฝ๋กœ๊ฐ€ ๋™์ผํ•˜์ง€ ์•Š์œผ๋ฉด ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

์ตœ์‹  ์ •๋ณด:

์šฐ๋ฆฌ๋Š” ํŒจํ‚ค์ง€๋ฅผ yarn ์ž‘์—… ๊ณต๊ฐ„์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค (๋ ˆํฌ์— ๋‹จ์ผ ํŒจํ‚ค์ง€ ๋งŒ ํฌํ•จ๋˜์–ด ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ ).
์ฝ”๋“œ๋ฅผ ./src์—์„œ ./package/our-package-name/src๋กœ ์ด๋™ํ•˜๊ณ  yarn ์ž‘์—… ๊ณต๊ฐ„์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค => https://classic.yarnpkg.com/en/docs/workspaces/

์ด๊ฒƒ์€ ์ตœ์ƒ์œ„ ./node_modules ํด๋”์— ๋Œ€ํ•œ ๊ณตํ†ต ์ข…์†์„ฑ์„ ๋Œ์–ด ์˜ฌ๋ฆฌ๊ณ  ./package/our-package-name/node_modules๊ฐ€ ๊ฑฐ์˜ ๋น„์–ด์žˆ๋Š” ์ƒํƒœ๋กœ ์œ ์ง€๋˜๋ฏ€๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ํŒจํ‚ค์ง€๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด ๋‹ค์Œ ๋ฒ„์ „์ด ๋” ์ด์ƒ ๋ฐ˜์‘์˜ ๋‘ ๋ฒˆ์งธ ๋ฒ„์ „์„ ๊ฐ€์ ธ ์˜ค์ง€ ์•Š๊ณ  (ํŒจํ‚ค์ง€ node_modules ํด๋”์— ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—) ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€์žˆ์–ด. ยฌยฌ '

์šฐ๋ฆฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ–‰๋™ ๊ฐ•๋ น์— ์œ„๋ฐฐ๋˜๋ฏ€๋กœ ์š•์„ค์„ ์ ‘์Šต๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.์ด ๋ฒ„๊ทธ๋กœ ํ™”๊ฐ€๋‚ฌ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ €๋Š” Next.JS๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜์ด ๋ฌธ์ œ๋Š” ์ง€๋ฃจํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์™ธ๋ถ€ ๋กœ์ปฌ ํŒจํ‚ค์ง€ ๋ฐ next-transpile-modules ์ž‘์—… ํ•  ๋•Œ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ตœ์‹  ๋ฒ„์ „์˜ Next.js๋ฅผ ๊ณ ์ˆ˜ํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— ๊ทผ๋ณธ ์›์ธ์„ ์ฐพ์œผ๋ฉด Next.js์— ํŒจ์น˜๋ฅผ ์ œ์ถœํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

[email protected] ์„ ์„ค์น˜ ํ•œ ํ›„์—๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
๋‚ด ์ข…์†์„ฑ์€ [email protected] , [email protected] , [email protected] ๋ฐ ๋ฌผ๋ก  ๋‹ค๋ฅธ ๋งŽ์€ libs์ž…๋‹ˆ๋‹ค (๊ทธ๋Ÿฌ๋‚˜ next-i18next๋ฅผ ์„ค์น˜ํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค). ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ๋Œ€๋‹จ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค : +1 :

์ด ๋ฌธ์ œ๋ฅผ ๊ฒŒ์‹œ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋””์ž์ธ ์‹œ์Šคํ…œ (๋ฐ˜์‘ ๊ตฌ์„ฑ ์š”์†Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ) ํŒจํ‚ค์ง€๋ฅผ ์‹ฌ๋ณผ๋ฆญ ๋งํฌํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ https://github.com/martpie/next-transpile-modules๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์Šค ํŒŒ์ผํ•˜๊ณ 

์—ฌ๊ธฐ์— ์ œ์•ˆ ๋œ ์ˆ˜์ • ์‚ฌํ•ญ์ด ์šฐ๋ฆฌ์—๊ฒŒ ํšจ๊ณผ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ node_modules ํด๋”์— ์‹ฌ๋ณผ๋ฆญ ๋งํฌํ•ฉ๋‹ˆ๋‹ค ( npm link ๋Œ€์‹  ์ž์ฒด ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋™์ผํ•ด์•ผ ํ•จ).
  • next.config.js ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
// next.config.js
const nextConfig = {
    webpack: (config, options) => {
        // modify the `config` here

        if (options.isServer) {
            config.externals = ["react", ...config.externals];
        }
        config.resolve.alias["react"] = path.resolve(__dirname, ".\\node_modules\\react");

        return config;
    },
};
// more plugins etc...

๊ตฌ์„ฑ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋Œ€์ฒด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  • ํŒจํ‚ค์ง€์—์„œ node_modules ๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๊ฒƒ์„ Symlinkํ•˜์‹ญ์‹œ์˜ค. ๋‚˜๋Š” ์ด๊ฒƒ์„ ์œ„ํ•ด ๋‚ด ์ž์‹ ์˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ  ์•„๋งˆ๋„ github์— ๊ฒŒ์‹œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด NextJS์—์„œ ์ˆ˜์ • ๋œ ๊ฒƒ์„ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์™œ ๋‚ด NextJS๊ฐ€ ์•„๋‹Œ ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ webpack ๋ณ„์นญ์ด ์ž‘๋™ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ์‹œ๊ฐ„์„ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค.

์ถ”์‹ . ์ด๊ฒƒ์ด ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น ์ง€ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๊ฐœ๋ฐœ ์ค‘์— ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

if (options.isServer) {
            config.externals = ["react", ...config.externals];
        }

react ์€ (๋Š”) ์ด๋ฏธ ์™ธ๋ถ€ ์„œ๋ฒ„ ์ธก์ž…๋‹ˆ๋‹ค.

config.resolve.alias["react"] = path.resolve(__dirname, ".\\node_modules\\react");

์ด๊ฒƒ์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ž์„œ ๋งํ–ˆ๋“ฏ์ด์ด ๋ฌธ์ œ๋Š” react ์— ์˜์กดํ•˜๋Š” ์ข…์†์„ฑ๊ณผ ๊ด€๋ จ์ด ์žˆ์ง€๋งŒ peerDependency ์— react ๊ฐ€ ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค (ํ•„์š”ํ•œ ๊ฒฝ์šฐ react-dom).

๋ฟก ๋นต๋€จ

์Œ, ํ•ญ์ƒ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ™•์‹คํžˆ ๋ฐ˜์‘๊ณผ ๋ฐ˜์‘์„ ํ”ผ์–ด ์˜์กด์„ฑ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ nextjs ํ”„๋กœ์ ํŠธ์— ์‹ฌ๋ณผ๋ฆญ ๋งํฌํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด์— node_modules ํด๋”๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค (์ ์–ด๋„ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํด๋”์—์„œ npm i ๋˜๋Š” npm link ๋ฅผ ์‹คํ–‰ ํ•œ ๊ฒฝ์šฐ).

react๊ฐ€์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํด๋”์—์„œ ํ•ด๊ฒฐ๋˜๋ฉด node_modules ํด๋”์—์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํ•ด๊ฒฐ๋˜๊ณ  ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” react์˜ ์ด์ค‘ ์‚ฌ๋ณธ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋‚ด lib ๋‚ด์—์„œ node_modules ํด๋”๋ฅผ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ npm link ์ด์™ธ์˜ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์น˜ํ•˜๋ฉด yes ofc๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค (ํ”ผ์–ด ์ข…์†์„ฑ ๋˜๋Š” ์ •ํ™•ํžˆ ๋™์ผํ•œ ๋ฐ˜์‘ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ).

๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ ์ค‘์—์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋ณ„์นญ ๋ฐ˜์‘์„ ํ†ตํ•ด ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๋™์ผํ•œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋„๋กํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์–ธ๊ธ‰ ๋œ ๋ฌธ์ œ๋กœ ์ธํ•ด config.externals ... ๋ถ€๋ถ„ (์ ์–ด๋„ ์ €์—๊ฒŒ๋Š”)์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ ๋Š” ํ˜„์žฌ NextJS ๋ฒ„์ „์—์„œ ํšจ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์—ฌ๊ธฐ์— ์–ธ๊ธ‰ ๋œ ์ผ๋ถ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์—์„œ ์–ธ๊ธ‰ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ # 8739?

๋‹จ์ง€ ์ถ”๊ฐ€ ์œ ์‚ฌํ•œ ๋ฌธ์ œ๋Š” ๋‚˜์—๊ฒŒ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ์ง€๋งŒ (์ž ์žฌ์ ์œผ๋กœ) ๋•Œ๋ฌธ์— (# 10162์— ์„ค๋ช… ๋œ๋Œ€๋กœ) ์žฌ๋ฃŒ-UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ์ง€๊ธˆ์€ ๋‚ด ์ž„์‹œ ์ˆ˜์ •ํ–ˆ๋‹ค npm run clean ๋‚ด preserve ์™€ dev ์Šคํฌ๋ฆฝํŠธ :
https://github.com/zeit/next.js/issues/10162#issuecomment -612501431

@timneutkens ์ด๋Ÿฌํ•œ ์ข…์†์„ฑ์ด ์ž์‹ ์˜ deps (deps ๋Œ€ peer-dep)๋ฅผ ๋‚˜์—ดํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๊ด€๋ จํ•˜์—ฌ ์‹ค์ œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ์„ ์ดํ•ดํ•˜์ง€๋งŒ์ด๋ฅผ ๋” ์˜๊ตฌ์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ž์ฒด ์•ฑ์—์„œ ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@ ryan-0 ํŠน๋ณ„ํ•œ ์„ค์ •์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์žฌ๋ฃŒ Ui๊ฐ€ ํ”ผ์–ด dep๋กœ ๋ฐ˜์‘ํ•˜์ง€ ์•Š์œผ๋ฉด ๋†€๋ž„ ๊ฒƒ์ž…๋‹ˆ๊นŒ? ์•„์ฃผ ์˜ค๋ž˜๋œ ๋ฐ˜์‘ ๋ฒ„์ „์ด๋‚˜ ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ?

ํŠน๋ณ„ํ•œ ์„ค์ •์ด ์—†์Šต๋‹ˆ๋‹ค .. ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ๋ฐ ๋ฐ˜์‘ ์—†์Œ 16.13.1 -> ๋ฌธ์ œ๋ฅผ ๊ณต์ •ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜์žˆ๋Š” ๋‹ค๋ฅธ deps๊ฐ€ ์žˆ์ง€๋งŒ ์ ์–ด๋„ ๊ทธ ์žฌํ˜„์— ๋”ฐ๋ฅด๋ฉด material-ui / core์™€ ๊ด€๋ จ์ด์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์šฐ๋ฆฌ๋„ ์‚ฌ์šฉ) :
https://github.com/zeit/next.js/issues/10162

@ ryan-0 material-ui ํด๋” ์•ˆ์— ๋ฐ˜์‘์ด์žˆ๋Š” node_modules ํด๋”๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋˜ํ•œ npm ์ค‘๋ณต ์ œ๊ฑฐ๋ฅผ ์‹คํ–‰ ํ•œ ํ›„ ์ž‘๋™์ด ์‹œ์ž‘๋ฉ๋‹ˆ๊นŒ?

์•„๋‹ˆ์š” ์ค‘์ฒฉ ๋œ ๋…ธ๋“œ ํด๋”๊ฐ€์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด ํ˜ผ๋ž€ ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. npm dedupe ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. :(

์ด์ƒํ•˜๊ฒŒ๋„ resolve.alias ์€ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ์™ธ๋ถ€์˜ ํŒจํ‚ค์ง€์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‚ด next.config.js ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const path = require('path')

module.exports = {
  webpack: config => {
    const { alias } = config.resolve || {}
    alias.react$ = path.resolve('node_modules/react')
    alias['react-dom$'] = path.resolve('node_modules/react-dom')

    config.resolve = {
      ...config.resolve,
      alias,
    }

    return config
  }
}

Lerna monorepo์—์žˆ๋Š” ๋กœ์ปฌ ํŒจํ‚ค์ง€์— yarn link ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. node_modules ์—๋Š” react ๋ณต์‚ฌ๋ณธ์ด ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ monorepo ๋ฃจํŠธ ์—๋Š” ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. resolve.alias ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•œ ์ฐจ์ด๊ฐ€์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜์ง€ ์•Š์ง€๋งŒ, ๋ถˆํ–‰ํžˆ๋„ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. monorepo ๋ฃจํŠธ์—์„œ react ๋ณต์‚ฌ๋ณธ์„ ์ œ๊ฑฐํ•œ ํ›„ ๋Œ€์‹  Cannot find module 'react' ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€ ์ด๊ฒƒ์— ๋Œ€ํ•œ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•˜์Šต๋‹ˆ๊นŒ?

๋‚ด '์†Œ๋น„์ž'ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด next-transpile-modules ์„ ์‚ฌ์šฉํ•˜๋Š” ๋งํฌ ๋œ ๋‹ค์Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ์— ์–ธ๊ธ‰ ๋œ๋Œ€๋กœ react ๋ณ„์นญ์„ next.config.json ํ–ˆ์ง€๋งŒ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. React์— ๋Œ€ํ•œ ์ค‘๋ณต ์ข…์†์„ฑ ์˜ค๋ฅ˜๊ฐ€ ์—ฌ์ „ํžˆ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@mweststrate์˜ relative-deps ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€ ์ด๊ฒƒ์— ๋Œ€ํ•œ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•˜์Šต๋‹ˆ๊นŒ?

๋‚ด '์†Œ๋น„์ž'ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด next-transpile-modules ์„ ์‚ฌ์šฉํ•˜๋Š” ๋งํฌ ๋œ ๋‹ค์Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ์— ์–ธ๊ธ‰ ๋œ๋Œ€๋กœ react ๋ณ„์นญ์„ next.config.json ํ–ˆ์ง€๋งŒ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. React์— ๋Œ€ํ•œ ์ค‘๋ณต ์ข…์†์„ฑ ์˜ค๋ฅ˜๊ฐ€ ์—ฌ์ „ํžˆ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ์œ„์˜ ๊ฒŒ์‹œ๋ฌผ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ์ƒ˜ํ”Œ์— config.externals ๋ถ€๋ถ„์„ ์ถ”๊ฐ€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ณ„์นญ์ด ๋‹ค์‹œ ์ž‘๋™ํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

@johot ๊ท€ํ•˜์˜ ์†”๋ฃจ์…˜์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์ €์—๊ฒŒ ํšจ๊ณผ์ ์ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด์ƒํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ ์ฃผ๋กœ ์†”๋ฃจ์…˜์„ ์‹œ๋„ํ•œ ํ›„ cannot destructure property 'query' of 'Object(...)(...)' as it is null ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๋„๋กœ์„œ ๋ณธ ๋ชฉ์ ์€ ์ธ useRouter ์—์„œ next/router .

@aleclarson ํŒ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์„ค์ •์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฉด ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

next-transpile-modules ๋ฐ Yarn์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์†”๋ฃจ์…˜์€ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. https://github.com/martpie/next-transpile-modules#i -have-trouble-with-duplicated-dependencies-or-the -์ž˜๋ชป๋œ ํ›„ํฌ ํ†ตํ™” ์˜ค๋ฅ˜ ๋ฐ˜์‘

npm ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์—ฌ์ „ํžˆ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค .c

์ข‹์•„, ๊ทธ๋ž˜์„œ ์ตœ์ข… ํ•ด๊ฒฐ์ฑ…์€ yarn link ์—์„œ yalc ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๊ฒƒ์ด ์—ˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฐ์‹œํ•˜๊ณ  ํŒŒ์ผ์„ dist ํด๋”์— ๋ณต์‚ฌ ํ•œ ๋‹ค์Œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ yalc ์ €์žฅ์†Œ์— ํ‘ธ์‹œํ•˜๋Š” gulp ์ž‘์—…์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด '์†Œ๋น„์ž'์—์„œ tsconfig.json ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๋กœ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

 "paths": {
      "~/*": ["/src/*"],
      "my-library/*": ["./node_modules/my-library/dist/*"]
    },

๊ทธ๋ฆฌ๊ณ  next.config.js ์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

 experimental: {
      jsconfigPaths: true, // enables it for both jsconfig.json and tsconfig.json
    }

๋”ฐ๋ผ์„œ ๋‹ค์Œ์€ tsconfig.json paths ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒฝ๋กœ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋” ๋งŽ์€ ์ •๋ณด๊ฐ€

๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ yalc + next-transpile-modules ํ•˜๋ฉด ๋กœ์ปฌ ๊ฐœ๋ฐœ ์„ค์ •์ด ๋งŽ์ด ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ค‘๋ณต ์ข…์†์„ฑ ๋ฐ ์ด์ƒํ•œ ์˜ค๋ฅ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“ˆ ์ถ”๊ฐ€์˜ ๋™์ž‘ yarn add ํ•˜๊ณ ์™€ ๋ชจ๋“ˆ์„ ์—ฐ๊ฒฐ yalc ๊ฑฐ์˜ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

styled-components ์— ์˜์กดํ•˜๋Š” ๋กœ์ปฌ๋กœ ์—ฐ๊ฒฐ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. https://styled-components.com/docs/faqs#linking -in-an-ssr-scenario

server/index.js :

const moduleAlias = require('module-alias');
moduleAlias.addAlias('styled-components', path.join(__dirname, '../node_modules/styled-components'));

๊ทธ๋Ÿฌ๋‚˜ next.config.js ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

config.resolve.alias['react'] = path.resolve(__dirname, './node_modules', 'react');
config.resolve.alias['react-dom'] = path.resolve(__dirname, './node_modules', 'react-dom');
config.resolve.alias['prop-types'] = path.resolve(__dirname, './node_modules', 'prop-types');
config.resolve.alias['styled-components'] = path.resolve(__dirname, './node_modules', 'styled-components');

๋„์›€์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.


ํ…Œ์ŠคํŠธ ๋Œ€์ƒ :

๋‹ค์Œ : 9.3.5
๋ฐ˜์‘ : 16.13.1
์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ : 5.1.0

์—ฌ๋Ÿฌ๋ถ„, ๊ฐ„๋‹จํ•œ ์ˆ˜์ •์€ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ react, next ๋ฐ react-dom์˜ ๊ธ€๋กœ๋ฒŒ ๋ฒ„์ „์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
npm remove -g react next react-dom

์—ฌ๋Ÿฌ๋ถ„, ๊ฐ„๋‹จํ•œ ์ˆ˜์ •์€ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ react, next ๋ฐ react-dom์˜ ๊ธ€๋กœ๋ฒŒ ๋ฒ„์ „์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

npm remove -g react next react-dom

๋‚˜๋Š” ๋‹น์‹ ์„ ์œ„ํ•ด ์ผํ•œ ๊ฒƒ์ด ๊ธฐ์˜์ง€๋งŒ์ด ์Šค๋ ˆ๋“œ์˜ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ด๋Ÿฌํ•œ ์ข…์†์„ฑ์„ ์ „ ์„ธ๊ณ„์ ์œผ๋กœ ์„ค์น˜ํ–ˆ๋Š”์ง€ ์˜์‹ฌํ•ฉ๋‹ˆ๋‹ค.

์›น๋ฟ๋งŒ ์•„๋‹ˆ๋ผ!
๋ฐ˜์‘ 16.9
๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ 0.62
Android์—์„œ ์‹คํ–‰
์•„๋งˆ๋„ ์—ญ์‚ฌ์ƒ ๊ฐ€์žฅ ์ž‘์€ ์žฌ์ƒ์‚ฐ ์ž์ผ๊นŒ์š”?

import React, { Component, useState } from 'react';
import {
  AppRegistry,
} from 'react-native';

function hooker() {
  const [count, setCount] = useState(0)
}

class ClassA extends Component {
  constructor(props) {
    super(props)
    //hooker();  //Invalid hook call Error
  }
  componentDidMount(){
    //hooker();  //Invalid hook call Error
  }
  render() {
    hooker();  //Invalid hook call Error
    return (      
      null   
    );
  }
} 
export default function App(props) {
  //hooker();  //No problem
  return (
    <ClassA/>
  );
};

AppRegistry.registerComponent('default', () => App);

๋‚˜๋Š” ๋˜ํ•œ์ด ๋ฌธ์ œ์— ์ง๋ฉดํ•˜์—ฌ yarn ๋Œ€์‹  npm (npm ์‚ฌ์šฉ์‹œ ์ž‘๋™ํ•˜์ง€ ์•Š์Œ)์„ ์‚ฌ์šฉํ•˜๊ณ  https://github.com/vercel/next.js/๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ธ์› ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋ฒ„์ „ 9.4.4์—์„œ ์™„์ „ํžˆ ๊ณ ์ฐฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์˜ ๊ฐœ์ธ ๊ฒฝ๋กœ์— ๋Œ€ํ•ด HOC์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ withRouter ์‚ฌ์šฉ์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๋Œ€์‹  ๋ž˜ํ•‘ ๋œ ๊ตฌ์„ฑ ์š”์†Œ์— ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

import { useRouter } from 'next/router'

function withPrivateRoute(WrappedComponent) {
const router = useRouter();                    //**** ERROR IS THROWN HERE *******
class WPR extends React.Component {
    componentDidMount(){
        console.log('wrappeed', WrappedComponent);
        // const { router } = this.props;
        const intendedRoute = router.pathname;
        // const isAdmin = !!cookies.get('isAdmin');
        // const isAuthenticated = !!cookies.get('username');
        const isAuthenticated = false;
        const isAdmin = false;
        if (!isAuthenticated) {
            router.push({
                pathname: '/login',
                query: { from: intendedRoute },
            });
        }
        if (
            isAuthenticated &&
            router.pathname.includes('admin') &&
            !isAdmin
        ) {
            router.push('/');
        }
    }

    render() {
        return ({ ...props }) => <WrappedComponent {...props} />;
    }
}
return WPR;
 }

  export default withPrivateRoute;

๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ด์ „ ์ง€์  (์ด ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๊ณ  ๊ฐ€์ •)์œผ๋กœ ๋Œ์•„๊ฐ€์„œ ์ตœ์‹  ์ฝ”๋“œ ํŒŒ์ผ์„ ํŒŒ์ผ๋ณ„๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ฌธ์ œ๊ฐ€

import { useToasts, AppearanceTypes } from 'react-toast-notifications';

export const showToast = (message: string, appearance: AppearanceTypes) => {
    const { addToast } = useToasts();
    addToast(message, {
        appearance,
    });
};

ํ† ์ŠคํŠธ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ๋ชจ๋“  ์š”์ฒญ์— โ€‹โ€‹์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด showToast ํŒ์—…์ด ํ‘œ์‹œ๋˜์ง€๋งŒ ์ด์ œ์ด ์˜ค๋ฅ˜๋กœ ์ธํ•ด์ด ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@arcanis์˜ PR https://github.com/vercel/next.js/pull/8739 ์™€ ๊ด€๋ จ์ด ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์–ธ๊ธ‰ ๋œ PR์ด ๋ณ‘ํ•ฉ ๋œ ์ด์œ ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” Rush ๋ฐ pnpm ๊ณผ ํ•จ๊ป˜ monorepo ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ https://github.com/vercel/next.js/issues/9022#issuecomment -610255555์—์„œ ๋งŒ๋“  @timneutkens ์˜ ์š”์ ์ด ์ ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  dependencies: next, react, react-dom, library
library
  devDependencies: react, react-dom (for tests)
  peerDependencies: react, react-dom

library.devDependencies.(react|react-dom) ๋Š” website.dependencies(react|react-dom) ์™€ ์ •ํ™•ํžˆ ๋™์ผํ•œ ํŒŒ์ผ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์‹ฌ๋ณผ๋ฆญ ๋งํฌ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ https://github.com/vercel/next.js/blob/f98e38c9b634b85e6679e7b5f953a9d98074cfc3/packages/next/lib/resolve-request.ts#L16 ์—์„œ ์‚ฌ์šฉ๋˜๋Š” [email protected] ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋ณด์กดํ•˜์—ฌ ๊ธฐ๋ณธ Node.js ๋™์ž‘.

๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. library ์—์„œ ์ฝ”๋“œ๋ฅผ ํŠธ๋žœ์Šค ํŒŒ์ผ ํ•˜๊ธฐ์œ„ํ•œ
  2. resolve.symlinks = true ๋‚ด๋ถ€์˜ ์›นํŒฉ ๊ตฌ์„ฑ์—์„œ next.config.js
  3. ๋กœ๋ถ€ํ„ฐ ์š”์ฒญ ๋œ ์™ธ๊ด€ ์กฐ์ž‘ library ์œผ๋กœ๋ถ€ํ„ฐ ์š”์ฒญํ•˜๊ธฐ library/node_modules (์ œ๋Œ€๋กœ ํ•ด๊ฒฐ ๋ชจ๋“ˆ์„ ์„œ๋ฒ„ ์ธก ๋นŒ๋“œ)
  4. https://github.com/vercel/next.js/blob/f98e38c9b634b85e6679e7b5f953a9d98074cfc3/packages/next/build/webpack-config.ts#L601 ์ค„ ์ฃผ์„ ์ฒ˜๋ฆฌ

์ด๊ฒƒ์€ ์˜๋„ ํ•œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ, Next.js๊ฐ€ Apple ๊ณผ ๊ฐ™์€ ์ค‘์š”ํ•œ ์›น ์‚ฌ์ดํŠธ๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ, ๊ทธ ํฐ ํ”„๋กœ์ ํŠธ์—์„œ ๊ณต์œ  ์ฝ”๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋…ธ ๋ ˆํฌ์— ๋Œ€ํ•œ ๋” ๋‚˜์€ ์ง€์›์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ์ด๊ฒƒ๋“ค์„ ๊ฐ€์ง€๊ณ  ๋†€์•˜๊ณ  HOC๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ž˜ํผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€ ๊ด€์‹ฌ์ด ์žˆ๋‹ค๋ฉด ์ด๊ฒƒ์„ ์žฌํ˜„ ํ•  ์ˆ˜์žˆ๋Š” repo๊ฐ€ โ€‹โ€‹์žˆ์Šต๋‹ˆ๋‹ค : next-components-hooks-error

HOC ํ…Œ์ŠคํŠธ-์˜ค๋ฅ˜ ๋ฐœ์ƒ

components/withPrivateRoute.js -> ์ƒ์œ„ ๊ตฌ์„ฑ ์š”์†Œ

import React, { useEffect } from 'react';
import { useRouter } from 'next/router';
const withPrivateRoute = WrappedComponent => {

    const router = useRouter();
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const user = localStorage.getItem('user');
        console.log(user);

        if (!user) {
            router.push('/login');
        } else {
            setLoading(false);
        }

    }, []);

    return ({ ...props }) => !loading && <WrappedComponent test={test} {...props}/>;
};

export default withPrivateRoute;

pages/hoc.js -> ์ž‘๋™ํ•˜์ง€ ์•Š์Œ (HOC ์‚ฌ์šฉ ํŽ˜์ด์ง€)

import React from 'react';
import withPrivateRoute from '../components/withPrivateRoute';

const HocTest = () => <p>Authorization HOC Test!</p>;

export default withPrivateRoute(HocTest);

๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ ํ…Œ์ŠคํŠธ

components/AuthLayout.js -> ๊ตฌ์„ฑ ์š”์†Œ (๋ž˜ํผ)

import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router';

const AuthLayout = ({ children }) => {

    const router = useRouter();
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const user = localStorage.getItem('user');
        console.log(user);

        if (!user) {
            router.push('/login');
        } else {
            setLoading(false);
        }

    }, []);

    return !loading && (
        <React.Fragment>
            {children}
        </React.Fragment>
    );
};

export default AuthLayout;

pages/wrapper.js -> ๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŽ˜์ด์ง€, ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

import React from 'react';
import AuthLayout from '../components/AuthLayout';

const WrapperTest = () => (
    <AuthLayout>
        <p>Authorization Wrapper Test!</p>
    </AuthLayout>
);

export default WrapperTest;

@Timer ์— ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ?

https://github.com/vercel/next.js/issues/9022#issuecomment -609969178์„ ์†”๋ฃจ์…˜์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.
๋‚ด ๋ฌธ์ œ๋Š” ๋‚ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  yarn link ๋‚ด ์•ฑ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์˜ˆ
package.json

{
  "dependencies": {
    "next": "9.5.1",
    "myUILibrary": "git+ssh://[email protected]/MyRepo/library-web-ui.git#master",
    "react": "16.13.1",
    "react-dom": "16.13.1"
  }
}

yarn link myUILibrary ๋„ react ์„ค์น˜๋œ ๋‚ด ๋กœ์ปฌ ์ฒดํฌ ์•„์›ƒ MyRepo/library-web-ui ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

์†”๋ฃจ์…˜์„ ๊ฒŒ์‹œ ํ•ด ์ฃผ์‹  @johot ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

5 ๐ŸŒŸ 3 ์  ๋งŒ์  (์˜ˆ! ๋ชจ๋“  ๋ณ„๊ณผ ๊ทธ ์ด์ƒ!)

Rush + PNPM monorepo์—์„œ @ wasd171 ๊ณผ ๋™์ผํ•œ ๊ฒฝํ—˜์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ค‘๊ฐ„์— ~9.4.4 ๋งŒ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Rush + PNPM๊ณผ ๋˜‘๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ‘

์ด ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ๋งค์šฐ ์–ด๋ฆฌ์„์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

import React, { useState } from 'React';

๋Œ€์‹  R์˜ ์–ด๋ฆฐ์• ๋“ค์ž…๋‹ˆ๋‹ค ์‚ฌ๋žŒ๋“ค์„ ๋Œ€ํ”ผ์˜ r์— ์–ด๋ฆฐ์• ๋“ค์ž…๋‹ˆ๋‹ค ์‚ฌ๋žŒ๋“ค์„ ๋Œ€ํ”ผ๋ฅผํ•ด์•ผํ•œ๋‹ค :

import React, { useState } from 'react';

์˜ˆ. 9.5.x ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.- 9.4.4 ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ์ž‘์—…- next-site ๋กœ๋„ ์žฌํ˜„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Capture

9.5.2์—์„œ์ด ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ๊ฒƒ์ด ํŠธ๋ฆญ์—†์ด 9.5.3์—์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

pnpm์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋„ˆ๋ฌด ๋นจ๋ฆฌ ๋ง ํ–ˆ์–ด์š”. 9.5.3์—์„œ๋„ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ 9.5.3์—์„œ ์•ˆ์ •์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿคท ๋” ์ด์ƒ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

9.5.3์ด ๋‚˜๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค-๋™์ผํ•œ ์˜ค๋ฅ˜. Rush + NPM์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์•Œ๋ ค์ง„ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? (btw๋Š” ๋” ์ด์ƒ 9.0.6์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ œ๋ชฉ์„ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)

์ฐธ๊ณ ๋กœ, ๋‚ด ์กฐ์ง์ด npm ์—์„œ yarn ๋กœ ์ด๋™ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ์ด์œ  ์ค‘ ํ•˜๋‚˜์˜€์Šต๋‹ˆ๋‹ค. (๋ถˆํ–‰ํžˆ๋„) ํ›จ์”ฌ ๋” ์ž˜ ์žฌ์ƒ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ์›€์ง์ž„์€ ์„ฑ๊ฐ€ ์‹œ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ง€๊ธˆ ๋งค์šฐ ํ–‰๋ณตํ•ฉ๋‹ˆ๋‹ค.

ํ›„ํฌ๊ฐ€์žˆ๋Š” ํŠธ๋žœ์Šค ํŒŒ์ผ ๋œ ๋ชจ๋“ˆ๋„ ๋‚˜์—๊ฒŒ ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , next-transpile-modules ๋ฐ npm ์‚ฌ์šฉํ•  ๋•Œ์ด ๋ฌธ์ œ๋ฅผ ๊ฒฝํ—˜ํ•˜๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ๋ฌธ์ œ์™€ ์ž ์žฌ์  ์†”๋ฃจ์…˜์„ ์„ค๋ช…ํ•˜๋Š” FAQ ์„น์…˜์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. https://www.npmjs.com/package/ ๋‹ค์Œ transpile-modules # i- ์ค‘๋ณต ๋œ ์ข…์†์„ฑ ๋˜๋Š” ์œ ํšจํ•˜์ง€ ์•Š์€ ํ›„ํฌ ํ˜ธ์ถœ ์˜ค๋ฅ˜๋กœ ์ธํ•ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ์›์‚ฌ์˜ ๋ฒ„์ „ ํ•ด์ƒ๋„๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€ํ•˜์—ฌ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ๋ฐ˜์‘ ์ข…์†์„ฑ์„ ๋ฃจํŠธ package.json ๋กœ ์ด๋™ํ•˜๋Š” ๋Œ€์‹  ๋‹ค์Œ ์ค„์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

  "resolutions": {
    "react": "16.13.1",
    "react-dom": "16.13.1"
  }

์ฐธ์กฐ : https://classic.yarnpkg.com/en/docs/selective-version-resolutions/

์ œ ๊ฒฝ์šฐ์—๋Š” ๋กœ์ปฌ ๋นŒ๋“œ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐ˜๋ฉด Vercel์˜ ๋นŒ๋“œ๋Š” Invalid hook call ์˜ค๋ฅ˜๋ฅผ๋ณด๊ณ ํ–ˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Next 10์˜ ์บ์น˜ ์˜ฌ ํŽ˜์ด์ง€๋กœ _app.js ์—์„œ ๋น„์Šทํ•œ ๋ฌธ์ œ๋ฅผ ์‹คํ—˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

image

์•ผ,

์ œ ๊ฒฝ์šฐ์—๋Š” npm link ๋ฅผ ํ†ตํ•ด ๋งํฌ ๋œ ๋ชจ๋“ˆ์„ ํŠธ๋žœ์Šค ํŒŒ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.

React์™€ ๊ฐ™์€ ์ข…์†์„ฑ์€ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค์šด๋กœ๋“œํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜ ์ข…์†์„ฑ ๋Œ€์‹  peerDependencies ๋กœ ํฌํ•จ๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž˜๋ชป๋œ ํ›„ํฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค.

  1. ํƒ€์‚ฌ ๋ชจ๋“ˆ์„ ๊ธฐ๋ณธ ํ”„๋กœ์ ํŠธ์˜ ์ข…์†์„ฑ์œผ๋กœ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  2. npm install ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋ชจ๋“  ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค.
  3. ํ„ฐ๋ฏธ๋„ / ์ฝ˜์†”์„ ์—ด๊ณ  ๋ชจ๋“ˆ๋กœ ์ด๋™ ํ•œ ๋‹ค์Œ sudo npm link ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ฉ”์ธ ํ”„๋กœ์ ํŠธ๋กœ ๋Œ์•„๊ฐ€ npm link @example/project ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. Visual Studio Code๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ node_modules ๋‚ด๋ถ€์˜ ๋ชจ๋“ˆ ์ด๋ฆ„ ๊ทผ์ฒ˜์— ์ž‘์€ ํ™”์‚ดํ‘œ ์•„์ด์ฝ˜์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  5. npm run dev ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, @ example / project์— ์ผ๋ฐ˜ ์ข…์†์„ฑ ๋Œ€์‹  React๋ฅผ peerDependency๋กœ ํฌํ•จํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋„์›€์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋‚ด๋ถ€์— next.js ํ”„๋กœ์ ํŠธ๊ฐ€์žˆ๋Š” monorepo๊ฐ€ โ€‹โ€‹์žˆ์Šต๋‹ˆ๋‹ค. storybook ์„ค์น˜ ํ›„ ์ž˜๋ชป๋œ ํ›„ํฌ ํ˜ธ์ถœ๋กœ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. @aengl ์˜ ์ œ์•ˆ์— ๋”ฐ๋ผ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. resolutions ์„ ๋ฃจํŠธ ์ˆ˜์ค€ package.json .

"resolutions": {
  "react": "^17.0.1",
  "react-dom": "^17.0.1"
}

๊ทธ๋ž˜๋„ ๋” ๋งŽ์€ ํด๋ผ์ด์–ธํŠธ์™€ ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์ด๊ฒƒ์ด ์ข‹์€ ์†”๋ฃจ์…˜์ด ๋ ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰