Next.js: [Next 9] ์•ฑ ๋นŒ๋“œ์‹œ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ

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

๋ฒ„๊ทธ ์‹ ๊ณ 

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

๋‹ค์Œ 8์—์„œ ๋‹ค์Œ 9๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋™
next build ํ•˜๋ฉด ํ”„๋กœ์„ธ์Šค ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•˜์—ฌ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋นŒ๋“œ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ, 20 ๊ฐœ์˜ ๊ฒฝ๋กœ๊ฐ€ ๋‹ค์†Œ์žˆ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.

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

๋ฌด์—‡์ด ์ž˜๋ชป๋˜์—ˆ๋Š”์ง€ ์ „ํ˜€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์žฌํ˜„ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. Next 8์€ ๋ฌธ์ œ์—†์ด ์ปดํŒŒ์ผ๋˜์ง€๋งŒ Next9๋Š” ์ปดํŒŒ์ผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ์Šคํƒ ์ถ”์ ์ž…๋‹ˆ๋‹ค. ๋” ์„ค๋ช…์ ์ธ ์ถœ๋ ฅ์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ ์žˆ๋Š” ๊ฒฝ์šฐ ์•Œ๋ ค ์ฃผ์‹œ๋ฉด ๋‹ค์Œ์„ ์ œ๊ณตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

<--- Last few GCs --->

[28143:0x102634000]   231190 ms: Mark-sweep 1278.7 (1441.0) -> 1263.4 (1438.5) MB, 838.4 / 0.0 ms  (average mu = 0.290, current mu = 0.268) allocation failure scavenge might not succeed
[28143:0x102634000]   231308 ms: Scavenge 1278.1 (1438.5) -> 1266.6 (1440.0) MB, 8.2 / 0.0 ms  (average mu = 0.290, current mu = 0.268) allocation failure 
[28143:0x102634000]   231365 ms: Scavenge 1279.3 (1440.0) -> 1271.6 (1443.0) MB, 21.6 / 0.0 ms  (average mu = 0.290, current mu = 0.268) allocation failure 


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x3547db9dbe3d]
Security context: 0x3a36ebf9e6e1 <JSObject>
    1: DoJoin(aka DoJoin) [0x3a36ebf85e89] [native array.js:~87] [pc=0x3547dcd9a7d0](this=0x3a366f3826f1 <undefined>,l=0x3a368f6eb2b9 <JSArray[10]>,m=10,A=0x3a366f3828c9 <true>,w=0x3a36c3aafc69 <String[1]: />,v=0x3a366f3829a1 <false>)
    2: Join(aka Join) [0x3a36ebf85ed9] [native array.js:~112] [pc=0x3547dd85bb38](this=0x3a366f3826f1 <undefined>,l=0x3a368f6...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x10003ae75 node::Abort() [/usr/local/bin/node]
 2: 0x10003b07f node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
 3: 0x1001a7ae5 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 4: 0x100572ef2 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/usr/local/bin/node]
 5: 0x1005759c5 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/usr/local/bin/node]
 6: 0x10057186f v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/usr/local/bin/node]
 7: 0x10056fa44 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
 8: 0x10057c2dc v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/usr/local/bin/node]
 9: 0x10057c35f v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/usr/local/bin/node]
10: 0x10054e1e4 v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/usr/local/bin/node]
11: 0x10082784d v8::internal::Runtime_StringBuilderJoin(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
12: 0x3547db9dbe3d 
[1]    28142 abort      npm run build:next

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

๋นŒ๋“œํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค

์Šคํฌ๋ฆฐ ์ƒท

ํ•ด๋‹น๋˜๋Š” ๊ฒฝ์šฐ ๋ฌธ์ œ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฐ ๋„์›€์ด๋˜๋Š” ์Šคํฌ๋ฆฐ ์ƒท์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

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

  • ์šด์˜์ฒด์ œ : macOS
  • ๋…ธ๋“œ : 10.13.0 (๋…ธ๋“œ 8.X์—์„œ๋„ ์ž‘๋™ํ•ด์•ผ ํ•จ)
  • Next.js ๋ฒ„์ „ : 9.0.1

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

์—ฌ๊ธฐ์— ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ์ปจํ…์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

needs investigation

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

@timneutkens ๋Š” ์ด์ œ repo๊ฐ€ โ€‹โ€‹์žˆ์œผ๋ฏ€๋กœ ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

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

๋ณต์ œ์—†์ด ์ด๊ฒƒ์„ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜ ์•Œ์•„. ์†Œ์Šค ๋งต ์ƒ์„ฑ์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํž™์„ ์–ป๊ธฐ ์ „์— ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋„ค์ดํ‹ฐ๋ธŒ ๋ฐฐ์—ด ํŒŒ์ผ ์ฃผ์œ„์—์ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

๋” ์ž์„ธํ•œ ์Šคํƒ ์ถ”์ ์„ ์–ป์„ ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ฐธ๊ณ ๋กœ ์ง€๊ธˆ ๊ตฌ์ถ• ์ค‘์ด์ง€๋งŒ ๋…ธ๋“œ ํ”„๋กœ์„ธ์Šค์— ๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

NODE_OPTIONS="--max_old_space_size=4096"

์ตœ๋Œ€ 28 ๊ฐœ์˜ ๊ฒฝ๋กœ๋ฅผ ์ž‘์„ฑํ•˜์ง€๋งŒ 30 ๊ฐœ์˜ ๊ฒฝ๋กœ (31 ๊ฐœ์˜ ๊ฒฝ๋กœ๊ฐ€ ์žˆ์Œ)๋ฅผ ์ œ๊ณตํ•˜๋ฉด ํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ตœ๋Œ€ 3GB์˜ ๋ฉ”๋ชจ๋ฆฌ (๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ด์ƒ)๊นŒ์ง€ ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค. 8GB์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€์žˆ๋Š” ํ‰๊ท  ๋…ธํŠธ๋ถ์—์„œ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ผ๋ถ€๋Š” ์ด๋ฏธ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๊ด€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ๊ณ„์† ๊ณต๊ฐœํ•ด์•ผํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
๋„์›€์ด๋œ๋‹ค๋ฉด ๋นŒ๋“œ ๋œ ํŽ˜์ด์ง€์˜ ํ†ต๊ณ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

image

ํ”„๋กœ์„ธ์Šค๋Š” ์†Œ์Šค ๋งต์„ ๋งŒ๋“ค๋ ค๊ณ  ํ•  ๋•Œ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค (๋Œ€๋ถ€๋ถ„).

์šฐ๋ฆฌ๊ฐ€ ์•Œ ์ˆ˜์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ์™„์ „ํ•œ ๋ณต์ œ๊ฐ€ ์ œ๊ณต๋˜๋Š”์ง€ ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๋‹ซ๊ฒ ์Šต๋‹ˆ๋‹ค.

Next 9๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฐ˜๋ฉด Next 8์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค๋„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ CI ํ๋ฆ„์˜ ์ผ๋ถ€๋กœ CircleCi์—์„œ ์•ฑ์„ ๋นŒ๋“œํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Exited with code 137
Hint: Exit code 137 typically means the process is killed because it was running out of memory
Hint: Check if you can optimize the memory usage in your app
Hint: Max memory usage of this container is 4284268544
 according to /sys/fs/cgroup/memory/memory.max_usage_in_bytes

4GB๋Š” CircleCI ์ปจํ…Œ์ด๋„ˆ์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์ด๋ฏ€๋กœ ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค. Next 9๋กœ ๊ฑด๋ฌผ์„ ์ง“๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ ํ•œ๊ณ„์— ๋„๋‹ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๊ณต์œ  ํ•  ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์ผ€์ด์Šค๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

NextJs 9๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜๋Š” ๋™์•ˆ์—๋„์ด ๋ฌธ์ œ์— ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค.

NextJs 9๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ 3 ๊ฐœ์˜ ํ”„๋กœ์ ํŠธ ์ค‘ 2 ๊ฐœ๋Š” Elastic Beanstalk์— ๋ฐฐํฌ ํ•  ๋•Œ ๋žจ ์‚ฌ์šฉ ๋ฌธ์ œ์— ์ง๋ฉดํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ๋˜๋Œ๋ ค ์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„ ๋‚˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ณต์ œํ•˜๊ธฐ ์œ„ํ•ด ๊ณต์œ  ํ•  ์ €์žฅ์†Œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ ๋ชจ๋“  ๋žŒ๋‹ค๊ฐ€ ๋นŒ๋“œ ๋œ ํ›„์— ๋‚ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋žฉํ†ฑ์—์„œ ๋นŒ๋“œ๋ฅผ ์™„๋ฃŒ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฐฐํฌ ํ•  ๋•Œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜์ง€๋งŒ ๋กœ์ปฌ์—์„œ ๊ฐœ๋ฐœํ•˜๋Š” ๋™์•ˆ ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ๋ฌธ์ œ๊ฐ€ ๋ช‡ ๊ฐ€์ง€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. (๋‚˜์—๊ฒŒ) ์•Œ์•„๋ณผ ์ˆ˜์žˆ๋Š” ์œ ์ผํ•œ ๊ฒƒ์€ ๋‹ค์Œ ์ค„์ž…๋‹ˆ๋‹ค.

 readFile [/tmp/b0cc21aa63cece4e/.build-utils/.builder/node_modules/@now/next/dist/index.js:9555]

์—ฌ๊ธฐ์— ๋กœ๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค ...

Aug 22 2019 01:26:51:346 | ฮป  (Lambda)       page was emitted as a lambda (i.e. getInitialProps)
-- | --
Aug 22 2019 01:26:51:346 | โšก  (Static File)  page was prerendered as static HTML
Aug 22 2019 01:26:51:434 | Done in 146.48s.
Aug 22 2019 01:26:51:444 | preparing lambda files...
Aug 22 2019 01:34:22:983 | <--- Last few GCs --->
Aug 22 2019 01:34:22:983 | [430:0x23f5310]   666594 ms: Mark-sweep 4089.3 (4262.1) -> 4089.3 (4261.1) MB, 3898.4 / 0.0 ms  allocation failure GC in old space requested
Aug 22 2019 01:34:22:983 | [430:0x23f5310]   671097 ms: Mark-sweep 4089.3 (4261.1) -> 4089.3 (4225.6) MB, 4502.8 / 0.0 ms  last resort GC in old space requested
Aug 22 2019 01:34:22:983 | [430:0x23f5310]   674990 ms: Mark-sweep 4089.3 (4225.6) -> 4089.3 (4223.1) MB, 3892.4 / 0.0 ms  last resort GC in old space requested
Aug 22 2019 01:34:22:983 | <--- JS stacktrace --->
Aug 22 2019 01:34:22:983 | ==== JS stack trace =========================================
Aug 22 2019 01:34:22:983 | Security context: 0x70e9f6257c1 <JSObject>
Aug 22 2019 01:34:22:983 | 1: toString [buffer.js:611] [bytecode=0x2833662c6061 offset=31](this=0xce2ca70dbc1 <Uint8Array map = 0x6cc06836709>,encoding=0x2fb750b822d1 <undefined>,start=0x2fb750b822d1 <undefined>,end=0x2fb750b822d1 <undefined>)
Aug 22 2019 01:34:22:983 | 2: arguments adaptor frame: 0->3
Aug 22 2019 01:34:22:983 | 3: readFile [/tmp/b0cc21aa63cece4e/.build-utils/.builder/node_modules/@now/next/dist/index.js:9555] [bytecode=0x1814135ff3e1 offset=53](t...
Aug 22 2019 01:34:22:983 | FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
Aug 22 2019 01:34:22:983 | 1:
Aug 22 2019 01:34:22:984 | node::Abort() [/node8/bin/node]
Aug 22 2019 01:34:22:984 | 2:
Aug 22 2019 01:34:22:986 | 0x11e73ec [/node8/bin/node]
Aug 22 2019 01:34:22:986 | 3:
Aug 22 2019 01:34:22:986 | v8::Utils::ReportOOMFailure(char const*, bool) [/node8/bin/node]
Aug 22 2019 01:34:22:986 | 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/node8/bin/node]
Aug 22 2019 01:34:22:986 | 5: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/node8/bin/node]
Aug 22 2019 01:34:22:986 | 6:
Aug 22 2019 01:34:22:986 | v8::internal::Factory::NewStringFromUtf8(v8::internal::Vector<char const>, v8::internal::PretenureFlag) [/node8/bin/node]
Aug 22 2019 01:34:22:986 | 7:
Aug 22 2019 01:34:22:987 | v8::String::NewFromUtf8(v8::Isolate*, char const*, v8::NewStringType, int) [/node8/bin/node]
Aug 22 2019 01:34:22:987 | 8:
Aug 22 2019 01:34:22:987 | node::StringBytes::Encode(v8::Isolate*, char const*, unsigned long, node::encoding, v8::Local<v8::Value>*) [/node8/bin/node]
Aug 22 2019 01:34:22:987 | 9:
Aug 22 2019 01:34:22:988 | 0x12070d6 [/node8/bin/node]
Aug 22 2019 01:34:22:988 | 10:
Aug 22 2019 01:34:22:988 | v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [/node8/bin/node]
Aug 22 2019 01:34:22:988 | 11:
Aug 22 2019 01:34:22:989 | 0xb79dac [/node8/bin/node]
Aug 22 2019 01:34:22:989 | 12:
Aug 22 2019 01:34:22:989 | v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [/node8/bin/node]
Aug 22 2019 01:34:22:989 | 13: 0x47a70c842fd
Aug 22 2019 01:35:32:549 | done

๋‚ด webpack ๊ตฌ์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const loadConfig = require('./loadConfig');

const reNodeModules = /node_modules/;
const reScript = /\.(js|jsx|mjs)$/;
const reImage = /\.(bmp|gif|jpg|jpeg|png|svg)$/;
const reGraphql = /\.graphql?$/;
const reStyle = /\.(css|less|styl|scss|sass|sss)$/;

module.exports = (nextConfig = {}) => {
  return {
    ...nextConfig,
    webpack(config, options) {
      const { webpack, isServer, dev } = options;

      const staticAssetName = dev ? '[path][name].[ext]?[hash:8]' : '[name]-[hash:8].[ext]';
      const publicPath = '/_next/static/';
      const outputPath = `${isServer ? '../' : ''}static/`;

      // eslint-disable-next-line no-param-reassign
      config.resolve = {
        ...config.resolve,
        modules: [...config.resolve.modules, './src'],
      };

      config.module.rules.push(
        {
          test: reImage,
          exclude: reNodeModules,
          oneOf: [
            // Inline lightweight into CSS
            {
              issuer: reStyle,
              oneOf: [
                // Inline lightweight SVGs as UTF-8 encoded DataUrl string
                {
                  test: /\.svg$/,
                  loader: 'svg-url-loader',
                  options: {
                    name: staticAssetName,
                    limit: 4096, // 4kb
                    publicPath,
                    outputPath,
                  },
                },

                // Inline lightweight as Base64 encoded DataUrl string
                {
                  loader: 'url-loader',
                  options: {
                    name: staticAssetName,
                    limit: 4096, // 4kb
                    publicPath,
                    outputPath,
                  },
                },
              ],
            },

            // Or return public URL to image resource
            {
              loader: 'file-loader',
              options: {
                name: staticAssetName,
                publicPath,
                outputPath,
              },
            },
          ],
        }, // Rules for GraphQL
        {
          test: reGraphql,
          exclude: reNodeModules,
          use: [
            {
              loader: 'webpack-graphql-loader',
              options: {
                removeUnusedFragments: true,
                output: 'document',
              },
            },
          ],
        },
        {
          exclude: [reNodeModules, reScript, reImage, reGraphql, /\.json$/, /\.txt$/, /\.md$/],
          loader: 'file-loader',
          options: {
            name: staticAssetName,
            publicPath,
            outputPath,
          },
        },
      );

      const appConfig = loadConfig();
      if (isServer && dev) {
        console.info(appConfig);
      }
      config.plugins.push(
        new webpack.DefinePlugin({
          __DEV__: dev,
          __SERVER__: isServer,
          __BROWSER__: !isServer,
          __CONFIG__: JSON.stringify(appConfig),
        }),
      );

      if (typeof nextConfig.webpack === 'function') {
        return nextConfig.webpack(config, options);
      }

      return config;
    },
  };
};

@timneutkens Next.js 9๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ปดํŒŒ์ผํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ˆ˜ ๋•Œ๋ฌธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์˜ ์™„์ „ํ•œ ์žฌํ˜„์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ง€์ ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/stramel/styled-icons/tree/ms/add-material-variants

์‹คํŒจํ•œ ๋นŒ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. https://travis-ci.org/jacobwgillespie/styled-icons/builds/582987078

Travis๋Š” NODE_OPTIONS=--max-old-space-size=4096 ์„ธํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@timneutkens ๋Š” ์ด์ œ repo๊ฐ€ โ€‹โ€‹์žˆ์œผ๋ฏ€๋กœ ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

[email protected] ์™€ ๊ฐ™์€ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ 

์ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๋‹จ์ˆœํžˆ ํฌ๊ธฐ ๋ฒ”์œ„์— ๋„๋‹ฌํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์„ ์‹œ์ž‘ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. NODE_OPTIONS=--max-old-space-size=4096 ๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€๋กœ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋˜๋Š” ์ƒˆ๋กœ์šด ์ฒญํ‚น ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// next.config.js
module.exports = {
  experimental: { granularChunks: true }
}

@Timer ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. granularChunks ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‚ด ๋กœ์ปฌ ์ปดํ“จํ„ฐ์˜ ๊ฐ’์œผ๋กœ 8192๋ฅผ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ์ง€ ์ƒ์ƒํ•˜๊ธฐ๊ฐ€ ์กฐ๊ธˆ ๋ฌด์„œ์›Œ์š”.

๋‚˜๋Š” ์˜ค๋ž˜๋œ ๋ฌธ์ œ๋ฅผ ์‚ดํŽด ๋ณด์•˜๊ณ  ๋•Œ๋กœ๋Š” ์ƒˆ๋กœ์šด ์ฃผ์š” ๋ฆด๋ฆฌ์Šค๊ฐ€์žˆ์„ ๋•Œ ์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค ์ด์ด ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ์— ์ง๋ฉดํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ํฐ ํ”„๋กœ์ ํŠธ์—์„œ ๊ธฐ์–ต๋ ฅ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜์‹œ๋‚˜์š”?

์ด ์ƒˆ๋กœ์šด ์ฃผ์š” ๋ฆด๋ฆฌ์Šค๋Š” ๋…ธ๋“œ ๋ฉ”๋ชจ๋ฆฌ ์บก์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์— ์—†์—ˆ๋˜ ๋Œ€์šฉ๋Ÿ‰ ๋ฉ”๋ชจ๋ฆฌ์˜ ์›์ธ์€ ๋ฌด์—‡์ผ๊นŒ์š”?

@Timer granularChunks ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ๋ณด์•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. 8192 ์„ธํŠธ๋กœ ๋กœ์ปฌ์—์„œ๋„.

์—ฌ๊ธฐ์—๋Š” ์„ธ๋ถ„ํ™” ๋œ ์ฒญํฌ ๊ตฌ์„ฑ ๊ธฐ๋Šฅ ์„ธํŠธ https://github.com/stramel/styled-icons/tree/ms/granular-chunks๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋™์ ์œผ๋กœ ๊ฐ€์ ธ ์˜ค๋Š” ๊ฒƒ์œผ๋กœ ์ „ํ™˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. https://github.com/stramel/styled-icons/tree/ms/dynamic-import-granular-chunks

์ด ๋ฌธ์ œ๋Š” ํ˜„์žฌ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด์žˆ๋Š” ์ถ•์†Œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋นŒ๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ ์ €์žฅ์†Œ ์ค‘ ํ•˜๋‚˜์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ : ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ๋ฌธ์ œ๊ฐ€ withSourceMaps ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

"@zeit/next-source-maps": "^0.0.4-canary.1"

์ด๊ฒƒ์€ ๋งค์šฐ ๋Š๋ฆฐ hidden-source-map ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ NextJS 8๋ณด๋‹ค ์™œ ๊ธฐํ•˜ ๊ธ‰์ˆ˜์ ์œผ๋กœ ๋Š๋ฆฐ ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ v9๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„ ์—„์ฒญ๋‚œ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค ... ์ €๋Š” 2015 ๋…„ ๋งฅ๋ถ ํ”„๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ด์ „์—๋Š” ์ง€์—ฐ๋œ ์ ์ด ์—†์œผ๋ฉฐ ๊ฝค ๋ฌด๊ฑฐ์šด ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ–ˆ์ง€๋งŒ ์ด์ œ๋Š” ๋‹ค์Œ ์•ฑ์„ ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ๊ทธ๊ฒƒ์€ ์™„์ „ํžˆ ์ง€์—ฐ๋˜๊ณ  ๋ชจ๋“  ๊ฒƒ์ด ์—„์ฒญ๋‚˜๊ฒŒ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค.

์ €๋Š” ๋ณดํ†ต 10 ๋ถ„ ์ •๋„๋งˆ๋‹ค ์•ฑ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ ์ธ๋‚ดํ•˜๊ณ  ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•œ ์ฒซ ๋‚ ์ด์—ˆ๊ณ , dev move์—์„œ ๋ช‡ ์‹œ๊ฐ„์„ ์‹คํ–‰ ํ•œ ํ›„ ๋™์ผํ•œ JavaScript heap out of memory ๋ฅผ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋นŒ๋“œ ์‹คํ–‰์— ๋Œ€ํ•ด๋ณด๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์–ด๋”˜๊ฐ€์— ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€์žˆ์„๊ฑฐ์•ผ

๋‚˜๋„ ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•ด. ๋‚ด ๋™๋ฃŒ๋Š” ๋” ์ตœ๊ทผ์˜ MacBook์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ๋‹ค์Œ 9๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ ์ดํ›„๋กœ ๊ฐœ๋ฐœ ์„œ๋ฒ„๋Š” ์žฌ ์ปดํŒŒ์ผ ์†๋„๊ฐ€ ๋Š๋ ค์กŒ์Šต๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” 20 ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  32GB ์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ MacBook Pro์—์„œ NODE_OPTIONS = 16384๋ฅผ ์‹œ๋„ํ–ˆ์ง€๋งŒ ํšจ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋กœ๊ทธ๊ฐ€ ๋‚˜์—ด๋ฉ๋‹ˆ๋‹ค.

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x335bafb5be3d]
Security context: 0x0fe28be1e6e9 <JSObject>
    1: createPrinter [0xfe25fe2c0b9] [/Users/my-name/my-project/node_modules/typescript/lib/typescript.js:~86713] [pc=0x335bb12e86f3](this=0x0fe280c03329 <Object map = 0xfe2df152cc9>,printerOptions=0x0fe2f39e8ae1 <Object map = 0xfe20ac205a9>,handlers=0x0fe28e1026f1 <undefined>)
    2: arguments adaptor frame: 1->2
    3: reportImplicitAny(aka reportImpli...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x10003d035 node::Abort() [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
 2: 0x10003d23f node::OnFatalError(char const*, char const*) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
 3: 0x1001b8e15 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
 4: 0x100586d72 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
 5: 0x100589845 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
 6: 0x1005856ef v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
 7: 0x1005838c4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
 8: 0x10059015c v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
 9: 0x1005901df v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
10: 0x10055fb24 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
11: 0x1007e7e04 v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/opt/nvm/versions/node/v10.16.3/bin/node]
12: 0x335bafb5be3d
13: 0x335bb12e86f3
14: 0x335bafb0a5c3

@timneutkens ์ด ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ์—ด๊ฑฐ ๋‚˜ ์ƒˆ ๋ฌธ์ œ๋ฅผ ์—ฝ๋‹ˆ ๋‹ค. ์ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์™€ ์ด์ƒํ•œ ๋ฌดํ•œ HMR ์š”์ฒญ์œผ๋กœ ์ธํ•ด ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ์•ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ๋˜๊ณ  ์—„์ฒญ๋‚œ ์‹œ๊ฐ„์ด ์†Œ๋ชจ๋ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ฆ์ธ ์ถ”๊ฐ€.
Next ๋ฒ„์ „ 4.2.3์œผ๋กœ ์•ฑ์„ ์ƒ์†ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹ค์Œ ๋ฒ„์ „ 9.1.3์œผ๋กœ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.
  • package.json์˜ ๋‹ค๋ฅธ ๋ชจ๋“  ํŒจํ‚ค์ง€ ๋ฒ„์ „์„ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.
  • node_modules ํด๋” ๋ฐ package.lock.json ์‚ญ์ œ
  • npm ์„ค์น˜ ์‹คํ–‰

ํ”„๋กœ์ ํŠธ์˜ ๋กœ์ปฌ ์„œ๋น„์Šค๋ฅผ ์ˆ˜ํ–‰ํ–ˆ์„ ๋•Œ ๋‹ค์Œ ์˜ค๋ฅ˜๋กœ ์ธํ•ด ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
์‹คํŒจ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์•ฑ์„ ์‹œ์ž‘ํ•œ ํ›„ 10 ๋ถ„ ์ด๋‚ด์— ๋ฐœ์ƒํ•˜๋ฉฐ ์•ฑ์—์„œ ๋” ๋งŽ์€ ํƒ์ƒ‰์„ ํŠธ๋ฆฌ๊ฑฐํ•˜์—ฌ ์„œ๋‘˜๋Ÿฌ ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒ„์ „ 8.1.0์œผ๋กœ ๋˜ ๋Œ๋ ธ๊ณ  ๋” ์ง„์ง€ํ•œ ํƒ์ƒ‰ (๋”ฐ๋ผ์„œ ํŽ˜์ด์ง€ ๋นŒ๋“œ)์œผ๋กœ๋„ ๋™์ผํ•œ ์‹คํŒจ๋ฅผ ์žฌํ˜„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋„ค, ์šฐ๋ฆฌ๋„ ์ด๊ฑธ๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค ...

๋‹ค์‹œ ์—ด ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค @timneutkens

์–ด์ œ ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ bootstrap.min.css๋ฅผ ๊ฐ€์ ธ ์˜ค๊ธฐ ์‹œ์ž‘ํ•œ ์ดํ›„๋กœ react-router ์‚ฌ์šฉ์ž ์ •์˜ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” [email protected]์—์„œ๋„์ด ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

js๋ฅผ ํ†ตํ•ด require / import ๋˜๋Š” css / scss๋ฅผ ํ†ตํ•ด @import ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ bootstrap.min.css๋ฅผ ์ง์ ‘ ๊ฐ€์ ธ์˜ฌ ๋•Œ ๋‘˜ ๋‹ค. ๋‚ด nodejs ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์€ ๊ฐœ๋ฐœ ์ค‘์— ๋ช‡ ๊ฐ€์ง€ ์ค€์ˆ˜ ํ›„ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ cdn์—์„œ ๋ถ€ํŠธ ์ŠคํŠธ๋žฉ์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์—

๋‹ค์Œ / ๋จธ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์˜ค๋žœ ๊ฐœ๋ฐœ ์‹œ๊ฐ„์— ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ค€์ˆ˜ํ•œ ํ›„์—๋„ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ดœ์ฐฎ์•„ ๋ณด์ž…๋‹ˆ๋‹ค.
<Head>
<meta key="viewport" name="viewport" content="initial-scale=1.0, width=device-width" />
<link key="bootstrapcdn" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" ...  />
...
</Head>

๊ทธ๋ž˜์„œ ๋ฌธ์ œ๋Š” next-css์˜ CSS ์ถ•์†Œ์— ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ํ”„๋กœ์ ํŠธ๋ฅผ 8.1.0์œผ๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ•  ๋•Œ์ด ์ถ•์†Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. https://github.com/zeit/next-plugins/issues/541. ๊ทธ๋ž˜์„œ์ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค (https://github.com/zeit/next-plugins/issues/392#issuecomment-475845330). ์•„์ง ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ๊ฐ€ ๋‹ค์‹œ ๋ฐœ์ƒ

// next.config.js
const withCSS = require('@zeit/next-css');

function HACK_removeMinimizeOptionFromCssLoaders(config) {
  console.warn(
    'HACK: Removing 'minimize' option from 'css-loader' entries in Webpack config',
  );
  config.module.rules.forEach(rule => {
    if (Array.isArray(rule.use)) {
      rule.use.forEach(u => {
        if (u.loader === 'css-loader' && u.options) {
          delete u.options.minimize;
        }
      });
    }
  });
}

module.exports = withCSS({
  webpack(config) {
    HACK_removeMinimizeOptionFromCssLoaders(config);
    return config;
  },
});

Next 9.1.3์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„์—๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” next-css๋„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์•„๋งˆ๋„ ๊ทธ๊ฒƒ์ด ์‹ค์ œ๋กœ ๊ทธ๊ฒƒ์„ ์ถฉ๋Œ์‹œํ‚ค๋Š” ๊ฒƒ์ผ๊นŒ ์š”?

์ด๊ฒƒ์ด ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ๋™์ผํ•œ ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์š”์ฒญํ•˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์‹ค์ œ๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์•ฑ์—์„œ ์ฐพ์„ ์ˆ˜์—†๋Š” ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์—ˆ๊ณ  ํž™ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์† ๊ฒ€์ƒ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ ์ด๋ฏธ์ง€์— ๋Œ€ํ•œ ์–ธ๊ธ‰์„ ์ œ๊ฑฐํ–ˆ๊ณ  ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๋‹ค์‹œ ์˜ค๋ฅ˜๋ฅผ์ฃผ์ง€ ์•Š์•˜๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ ์ด๊ฒƒ์„ ๊ณ ์น  ์ˆ˜ ์žˆ์—ˆ๊ณ  @lloan ์ฝ”๋ฉ˜ํŠธ๋Š” ๋ฌธ์ œ๋ฅผ ๋””๋ฒ„๊ทธํ•˜๋Š” ๋ฐ ๋„์›€์ด๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ๊ฒฝ์šฐ, ๋‚˜๋Š” ์ฐธ์กฐ ๋œ /public/manifest.json A์™€ meta ํƒœ๊ทธ <head/> ์ž์› ๋‚ด ํ”„๋กœ์ ํŠธ์— ์กด์žฌํ•˜์ง€ ์•Š์•˜๋‹ค ๊ทธ๋Ÿฌ๋‚˜ ๊ฒƒ์„,์ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ์›์ธ์ด๋˜์—ˆ๋‹ค.

icon.png ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”์ด ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

<Head>
  <link rel="icon" href="/static/icon.png" type="image/png" />
</Head>

ํŒŒ๋น„์ฝ˜ ๊ฐ€์ ธ ์˜ค๊ธฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋” ์ด์ƒ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

<Head>
  <link rel="icon" href="/icon.png" type="image/png" />
</Head>

์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด https://github.com/zeit/now/issues/3307 static / public ํด๋”์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋„์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. bukinoshita๊ฐ€ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์ •์  ํด๋”๋ฅผ ์กฐ์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค. public/static/ ํด๋”์—์„œ 674 ๊ฐœ์˜ json ํŒŒ์ผ (ํ…Œ์ŠคํŠธ ์šฉ) ํด๋”๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ ์ดํ›„๋กœ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ํ˜„์žฌ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด์žˆ๋Š” ์ถ•์†Œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋นŒ๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ ์ €์žฅ์†Œ ์ค‘ ํ•˜๋‚˜์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ : ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ๋ฌธ์ œ๊ฐ€ withSourceMaps ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

"@zeit/next-source-maps": "^0.0.4-canary.1"

์ด๊ฒƒ์€ ๋งค์šฐ ๋Š๋ฆฐ hidden-source-map ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ NextJS 8๋ณด๋‹ค ์™œ ๊ธฐํ•˜ ๊ธ‰์ˆ˜์ ์œผ๋กœ ๋Š๋ฆฐ ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

"@zeit/next-source-maps": "^0.0.4-canary.1" ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„์—๋„์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ํ•ด๊ฒฐ์ฑ…์ด๋‚˜ ์†Œ์Šค ๋งต์„ ์ œ๊ฑฐํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

@focux ๋‚˜๋Š” ์†Œ์Šค ๋งต์„ ์ „ํ˜€ ๋น„ํ™œ์„ฑํ™”ํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ํ›„ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ํฌ๊ฒŒ ๊ฐ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ์˜ ํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํฌ๋ฉด ์ถฉ๋Œํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Typescript์—์„œ ๋ฌด์–ธ๊ฐ€๋ฅผ ๊ฐ€์ ธ ์™”๊ณ  ๋นŒ๋“œ์˜ ํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ 2.41MB๊นŒ์ง€ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ 2GB ๋žจ์ด์žˆ๋Š” CI๊ฐ€ ์ถฉ๋Œํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. Typescript ๊ฐ€์ ธ ์˜ค๊ธฐ๋ฅผ ์ œ๊ฑฐํ•œ ํ›„ ํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ 100kb๋กœ ์ค„์–ด๋“ค์—ˆ๊ณ  ๋‹ค์‹œ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

Nextjs 9๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ CI์—์„œ ๋งค์šฐ ๋Š ๋ ธ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๋งค์šฐ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๊ณ  ํŠน๋ณ„ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ฐ˜์‘ํ•˜๋Š” ๊ฒƒ, ์žฌ๋ฃŒ UI, ์—ฌ๊ธฐ์ €๊ธฐ์„œ ์ผ๋ถ€ ํŒจํ‚ค์ง€. ๋‚˜๋Š” ๋…ธ๋“œ / ์ต์Šคํ”„๋ ˆ์Šค, ์ผ๋ถ€ dotnet ์ฝ”์–ด, php ๋“ฑ์ด์žˆ๋Š” ๋™์ผํ•œ ํด๋Ÿฌ์Šคํ„ฐ์— CI๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.์ด ๋ชจ๋“  ๊ฒƒ๋“ค์€ CI์— 1GB ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ๋นŒ๋“œ๋ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•œ ๋‚ด ๋Š๋‚Œ๋ณด๋‹ค ๋” ๋งŽ์€ ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Mac OS / Github ์ž‘์—…. ์—ฌ๊ธฐ์— ์–ธ๊ธ‰ ๋œ ์ž‘์—…์€ ๋„์›€์ด๋˜์ง€ ์•Š์œผ๋ฉฐ ๋งํฌ๋˜์—ˆ์ง€๋งŒ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ํ”„๋กœ์ ํŠธ๋Š” Zeit Now์—์„œ ๋นŒ๋“œ (์ƒ์‚ฐ ์ค‘)๋ฉ๋‹ˆ๋‹ค.

๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ๋•๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค (MacOS). ๋‚ด๊ฐ€ ์ฐพ์€ ๊ฒƒ์€ :

  • Next 9.1.5 ๋ฐ 9.1.6์—์„œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. 9.1.4๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
  • ํ”„๋กœ์ ํŠธ ๋‚ด์— ๋‚ด ์ž์‹ ์˜ _ckeditor_ ๋นŒ๋“œ๊ฐ€ ์žˆ์œผ๋ฉฐ ํฌ๊ธฐ๋Š” 606KB์ž…๋‹ˆ๋‹ค. ์ œ๊ฑฐํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

๋„์›€์ด ํ•„์š”ํ•˜๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”. ์—ฌ๊ธฐ์— ์˜ค๋ฅ˜ ๋กœ๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค ...

<--- Last few GCs --->

[83442:0x102804000]   123060 ms: Scavenge 1371.3 (1422.4) -> 1370.7 (1422.9) MB, 8.3 / 0.0 ms  (average mu = 0.120, current mu = 0.058) allocation failure 
[83442:0x102804000]   123066 ms: Scavenge 1371.7 (1422.9) -> 1370.9 (1423.9) MB, 4.1 / 0.0 ms  (average mu = 0.120, current mu = 0.058) allocation failure 
[83442:0x102804000]   123071 ms: Scavenge 1371.7 (1423.9) -> 1371.0 (1424.4) MB, 3.9 / 0.0 ms  (average mu = 0.120, current mu = 0.058) allocation failure 


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x3b944125be3d]
Security context: 0x164494d1e6e9 <JSObject>
    1: SourceMapConsumer_allGeneratedPositionsFor [0x16448b97d331] [/Users/alberto.iglesias/Coding/iteisa/projects/ceoe-gis/node_modules/@babel/core/node_modules/source-map/lib/source-map-consumer.js:~178] [pc=0x3b944240968c](this=0x1644193fb679 <BasicSourceMapConsumer map = 0x16448ea8a239>,aArgs=0x16447d082249 <Object map = 0x16448ea98939>)
    2: /* anonym...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x10003d035 node::Abort() [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
 2: 0x10003d23f node::OnFatalError(char const*, char const*) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
 3: 0x1001b8e15 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
 4: 0x100586d72 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
 5: 0x100589845 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
 6: 0x1005856ef v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
 7: 0x1005838c4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
 8: 0x10059015c v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
 9: 0x1005901df v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
10: 0x10055fb24 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
11: 0x1007e7e04 v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/Users/alberto.iglesias/.nvm/versions/node/v10.16.3/bin/node]
12: 0x3b944125be3d 
13: 0x3b944240968c 
Abort trap: 6

SourceMapConsumer_allGeneratedPositionsFor ์ด๊ฒƒ์ด ๋ฒ”์ธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ๋Š” ์†Œ์Šค ๋งต์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์ด ์†Œ์Šค ๋งต ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์œ ์ง€ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์†Œ์Šค ๋งต ์ƒ์„ฑ์„ ๋„๋”๋ผ๋„ ์—ฌ์ „ํžˆ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ะกะตั€ะณะตะน.

2019 ๋…„ 12 ์›” 24 ์ผ 10:01 GMT์— Emanuele [email protected] ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

SourceMapConsumer_allGeneratedPositionsFor ์ด๊ฒƒ์ด ๋ฒ”์ธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ๋Š” ์†Œ์Šค ๋งต์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ด๋Ÿฌํ•œ ์†Œ์Šค ๋งต ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์œ ์ง€ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

โ€”
๋Œ“๊ธ€์„ ๋‹ฌ์•˜ ๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜์‹  ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub ์—์„œ ํ™•์ธํ•˜๊ฑฐ๋‚˜ ์ˆ˜์‹ ์„ ๊ฑฐ๋ถ€ ํ•˜์„ธ์š”.

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

๋Œ“๊ธ€์ด ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์œ ์šฉํ•œ ์ง€ ํ•ญ์ƒ ํ™•์ธํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด ematipico์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ์กฐ์‚ฌํ•˜์—ฌ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. "์•„์ง๋„์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค"๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์€ ์œ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด CI / CD ํŒŒ์ดํ”„ ๋ผ์ธ์ด 1GB RAM์—์„œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

@timneutkens ์žฌํ˜„ ๋‹จ๊ณ„๋Š”์ด ๋‹ซํžŒ ๋ฌธ์ œ์—์„œ ์–ธ๊ธ‰ ํ•œ๋Œ€๋กœ์ž…๋‹ˆ๋‹ค.

https://github.com/zeit/next.js/issues/9442#issuecomment -554839437

๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ•œ @ Vista1nik ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ •์  ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋‹ค์‹œ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ด€๋ จ๋œ ์ง€๊ธˆ ๋ฌธ์ œ :

https://github.com/zeit/now/issues/3307

๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด ๋  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ํ† ๋ก ์— ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.
๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์„ ๊ฒฝํ—˜ ํ•œ ๋‹ค์Œ ๋‚ด ๊ฒฝ์šฐ์— ๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„ ๋ƒˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์ฝ”๋“œ ์กฐ๊ฐ์—์„œ const Icon ๊ฐ€ undefined ๊ฒฝ์šฐ ์ฝ”๋“œ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•˜๋Š” ๋ฌดํ•œ ๋ฃจํ”„์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

const iconMapping = {
  "flash-outline": FlashOutline,
};

export const Icon = ({ name }) => {
  const Icon = iconMapping[name];

  return <Icon />;
}

const Icon ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ ํ™•์ธ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ๋ฌธ์ œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

...
  const Icon = iconMapping[name];

  if (!Icon) return null;
  return <Icon />;
}

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

const Button = ({ children }) => {
  // BUG: the button should be lower case (the HTML input)
  //      instead of CamelCase (an undefined component)
  return <Button>{children}</Button>
}

์ตœ์‹  ๋ฒ„์ „์˜ Next.js๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•ด๋ณด์„ธ์š”. ์ตœ๊ทผ์— ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ตœ์ ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

@timneutkens , ์ตœ์‹  ๋ฒ„์ „ (9.3.5)์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜ ์•„์นจ์— ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ  ๋ช‡ ๋ถ„ ํ›„์— ๊ทธ ์˜ค๋ฅ˜์— ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค.

next-source-maps ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์Šค ๋งต์œผ๋กœ ์•ฑ์„ ๋นŒ๋“œํ•˜๋Š” ๋™์•ˆ CricleCI์—์„œ ์œ ์‚ฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

NODE_OPTIONS="--max_old_space_size=4096" ๋กœ์ปฌ์—์„œ ๋„์›€์ด๋˜์—ˆ์ง€๋งŒ CircleCI์—์„œ๋Š” ๋ฆฌ์†Œ์Šค ํด๋ž˜์Šค https://circleci.com/docs/2.0/configuration-reference/#resource_class ๋ฅผ ์ตœ์†Œํ•œ large ๋กœ ๋Š˜๋ ค์•ผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ.

์˜ค๋Š˜ ๋‹ค์Œ 9.3.6์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•œ ํ›„์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

<--- Last few GCs --->

[66325:0x108008000]    17639 ms: Mark-sweep 1936.2 (2071.4) -> 1923.6 (2073.4) MB, 283.4 / 0.0 ms  (average mu = 0.157, current mu = 0.048) allocation failure scavenge might not succeed
[66325:0x108008000]    17937 ms: Mark-sweep 1938.1 (2073.4) -> 1925.4 (2075.4) MB, 285.8 / 0.0 ms  (average mu = 0.108, current mu = 0.042) allocation failure scavenge might not succeed


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x0fb9ac667d09 <JSObject>
    0: builtin exit frame: stringify(this=0x0fb9ac6598a9 <Object map = 0xfb921b01449>,0x0fb958e804d1 <undefined>,0x0fb958e804d1 <undefined>,0x0fb910180ec1 <Object map = 0xfb9d8491399>,0x0fb9ac6598a9 <Object map = 0xfb921b01449>)

    1: arguments adaptor frame: 1->3
    2: callAsync [0xfb9320a6cf9] [0x0fb958e804d1 <undefined>:~1] [pc=0x1aa09fe84627](this=0x0fb9320a6909 <Hook map = 0xfb9d8495179>...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
...

# 12280์— ์ œ์•ˆ ๋œ๋Œ€๋กœ tsconfig.json ์—์„œ paths ์„ ์ˆ˜์ •ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ๋‹ค๋ฅธ ์›์ธ

9.0.5์—์„œ 9.3.6์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„์—๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์—ฌ๊ธฐ์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

Creating an optimized production build ..
<--- Last few GCs --->

[1600:0000020DB9FFEBE0]    26245 ms: Mark-sweep 1958.0 (2080.3) -> 1945.0 (2081.5) MB, 266.4 / 0.0 ms  (average mu = 0.179, current mu = 0.077) allocation failure scavenge might not succeed
[1600:0000020DB9FFEBE0]    26530 ms: Mark-sweep 1959.9 (2082.0) -> 1947.2 (2083.8) MB, 265.9 / 0.0 ms  (average mu = 0.127, current mu = 0.068) allocation failure scavenge might not succeed


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 00007FF77B4D4DDD]
Security context: 0x00e7d00c08d1 <JSObject>
    1: /* anonymous */(aka /* anonymous */) [000002BB3E5CAA29] [C:\Users\...\node_modules\enhanced-resolve\lib\UnsafeCachePlugin.js:~27] [pc=00000147695447FC](this=0x00d9404004b1 <undefined>,0x001a9e083681 <Object map = 000003D51551D3A9>,0x001a9e0838d9 <Object map = 000003D515521AE9>,0x001a9e083979 ...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 00007FF77A8D363F napi_wrap+128063
 2: 00007FF77A872836 v8::base::CPU::has_sse+35142
 3: 00007FF77A8734F6 v8::base::CPU::has_sse+38406
 4: 00007FF77B089F4E v8::Isolate::ReportExternalAllocationLimitReached+94
 5: 00007FF77B072021 v8::SharedArrayBuffer::Externalize+833
 6: 00007FF77AF3E57C v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1436
 7: 00007FF77AF497D0 v8::internal::Heap::ProtectUnprotectedMemoryChunks+1312
 8: 00007FF77AF462F4 v8::internal::Heap::PageFlagsAreConsistent+3204
 9: 00007FF77AF3BB13 v8::internal::Heap::CollectGarbage+1283
10: 00007FF77AF3A184 v8::internal::Heap::AddRetainedMap+2452
11: 00007FF77AF5C734 v8::internal::Factory::NewInternalizedStringImpl+132
12: 00007FF77AD9C7FD v8::internal::DescriptorArray::Allocate+4941
13: 00007FF77ADAD0C5 v8::internal::StringTable::LookupString+373
14: 00007FF77AAAF356 v8::internal::Factory::InternalizeName+54
15: 00007FF77ACAB0BE v8::internal::Runtime::GetObjectProperty+9662
16: 00007FF77B4D4DDD v8::internal::SetupIsolateDelegate::SetupHeap+546637
17: 00000147695447FC

์–ด๋–ค ์ƒ๊ฐ?

@szaza ๋Š” next@canary ๋ฅผ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ๊ฒฝ์šฐ๋Š” ์—ฌ๊ธฐ์— ์„ค๋ช… ๋œ ๋ฌธ์ œ๊ฐ€์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. https://github.com/zeit/next.js/issues/12280

์ข‹์•„์š”, node_modules ์„ ์‚ญ์ œํ•˜๊ณ  ์ข…์†์„ฑ์„ ๋‹ค์‹œ ์„ค์น˜ํ•˜๋ฉด ์นด๋‚˜๋ฆฌ์•„ ๋ฒ„์ „์—์„œ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ ์ด์ œ Cannot find module 'next-server/dist/server/next-server'. ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ต์ˆ™ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ?

์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. import Server from "next/dist/next-server/server/next-server"; ๋กœ ์ด๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์˜ ๋„์›€์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@szaza ํ”„๋กœ์ ํŠธ์—์„œ ํ•ด๋‹น ๋ชจ๋“ˆ์„ ์–ด๋–ป๊ฒŒ ๊ฐ€์ ธ ์™”์Šต๋‹ˆ๊นŒ? ๋‚ด๋ถ€ ๋ชจ๋“ˆ์ธ๊ฐ€์š”? ๋Œ€์‹  'next' ๋ฅผ ๊ฐ€์ ธ ์˜ค๋ ค๊ณ  ํ•˜์…จ๋‚˜์š”?

TypeScript๋กœ ์ž‘์„ฑ๋œ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค. ์ธ์ฆ๋˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž๋ฅผ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋‹ค์‹œ ๋ฆฌ๋””๋ ‰์…˜ํ•˜๋Š” ์—ฌ๊ถŒ ์ธ์ฆ ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.

import Server from "next-server/dist/server/next-server";
...
export const initPassport = (
    server: Express,
    app: Server,
    authStrategies: string[]
) => {
...
return app.render(req, res, AuthRoutes.LOGIN_PAGE);
...
}

๋‹ค์Œ ๋ฒ„์ „์„ 9.0.5์—์„œ 9.3.7-canary.0์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•œ ํ›„ Server ์œ ํ˜•์„ ๋” ์ด์ƒ next-server/dist/... ์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์ง€๋งŒ ์œ„์—์„œ ์–ธ๊ธ‰ ํ•œ ๊ฒฝ๋กœ์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด package.json์˜ ๋ชจ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•  ๋•Œ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ €๋Š” ๋ฌธ์ œ์—†์ด @ zeit / next-css ์™€ ํ•จ๊ป˜ NextJS 9.2.2 ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ฒ„์ „์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๊ฑฐ๋‚˜ ์–ด๋–ป๊ฒŒ ๋“  NextJS์™€ ์ถฉ๋Œํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๋‚ด ํ˜„์žฌ ํŒจํ‚ค์ง€ ๊ตฌ์„ฑ์€-

{
"dependencies": {
    "@zeit/next-css": "^1.0.1",
    "axios": "^0.19.2",
    "body-parser": "^1.19.0",
    "compression": "^1.7.4",
    "cookie-parser": "^1.4.4",
    "cookie-session": "^1.4.0",
    "express": "^4.17.1",
    "helmet": "^3.21.3",
    "json-server": "^0.16.1",
    "morgan": "^1.9.1",
    "next": "^9.2.2",
    "passport": "^0.4.1",
    "passport-local": "^1.0.0",
    "passport-strategy": "^1.0.0",
    "prop-types": "^15.7.2",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-mathjax2": "0.0.2",
    "shaka-player": "^2.5.10",
    "styled-components": "^5.0.1"
  },
  "devDependencies": {
    "@babel/cli": "^7.8.4",
    "@babel/core": "^7.9.0",
    "@babel/preset-env": "^7.8.6",
    "@babel/preset-react": "^7.8.3",
    "babel-jest": "^25.1.0",
    "babel-plugin-module-resolver": "^4.0.0",
    "babel-plugin-styled-components": "^1.10.7",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "jest": "^25.1.0",
    "react-test-renderer": "^16.13.0"
  }
}

๋‚ด ํŠน์ • ๋ฌธ์ œ๋ฅผ https://github.com/google/schema-dts ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์œผ๋กœ ์ขํ˜”์Šต๋‹ˆ๋‹ค

pages/ ์—์„œ ํ•œ ํŽ˜์ด์ง€๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ํŽ˜์ด์ง€๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ํ”„๋กœ์ ํŠธ๊ฐ€ ๋นŒ๋“œ ๋  ๋•Œ๊นŒ์ง€ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•œ ๋‹ค์Œ ์ ์ฐจ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์‚ฝ์ž…ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ๋””๋ฒ„๊น…ํ–ˆ์Šต๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ์ด๊ฒƒ์€์ด ์Šค๋ ˆ๋“œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค ๐Ÿคทโ€โ™‚๏ธ

next-source-maps ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์Šค ๋งต์œผ๋กœ ์•ฑ์„ ๋นŒ๋“œํ•˜๋Š” ๋™์•ˆ CricleCI์—์„œ ์œ ์‚ฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

NODE_OPTIONS="--max_old_space_size=4096" ๋กœ์ปฌ์—์„œ ๋„์›€์ด๋˜์—ˆ์ง€๋งŒ CircleCI์—์„œ๋Š” ๋ฆฌ์†Œ์Šค ํด๋ž˜์Šค https://circleci.com/docs/2.0/configuration-reference/#resource_class ๋ฅผ ์ตœ์†Œํ•œ large ๋กœ ๋Š˜๋ ค์•ผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ.

์ด๊ฒƒ์ด ์šฐ๋ฆฌ๋ฅผ ์œ„ํ•ด ์ผํ•œ ์œ ์ผํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค ๐Ÿ‘

์ƒ๋‹นํžˆ ํฐ Next.js ์•ฑ (v9.3.6)์—์„œ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์•ฑ ์‹œ์ž‘ (๊ฐœ๋ฐœ ๋ชจ๋“œ)์‹œ ํž™ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. NODE_OPTIONS="--max_old_space_size=4096" ์„ค์ •์ด ๋…ธ๋“œ 10์— ๋„์›€์ด๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋…ธ๋“œ 12 ์ด์ƒ์—์„œ๋Š”์ด ์ปค๋ฐ‹ ๊ณผ ์ปจํ…Œ์ด๋„ˆ์— ํ• ๋‹น ๋œ ๋ฉ”๋ชจ๋ฆฌ ์–‘์„ ๊ณ ๋ คํ•˜๋Š” ๋‹ค๋ฅธ ์ปค๋ฐ‹ ์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค (Linux ๋งŒ ํ•ด๋‹น).

๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด ๋  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ํ† ๋ก ์— ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.
๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์„ ๊ฒฝํ—˜ ํ•œ ๋‹ค์Œ ๋‚ด ๊ฒฝ์šฐ์— ๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„ ๋ƒˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์ฝ”๋“œ ์กฐ๊ฐ์—์„œ const Icon ๊ฐ€ undefined ๊ฒฝ์šฐ ์ฝ”๋“œ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•˜๋Š” ๋ฌดํ•œ ๋ฃจํ”„์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

const iconMapping = {
  "flash-outline": FlashOutline,
};

export const Icon = ({ name }) => {
  const Icon = iconMapping[name];

  return <Icon />;
}

const Icon ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ ํ™•์ธ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ๋ฌธ์ œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

...
  const Icon = iconMapping[name];

  if (!Icon) return null;
  return <Icon />;
}

์ด ์ฝ”๋“œ๊ฐ€์ด ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚จ๋‹ค๋Š” ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์•Œ์•˜์Šต๋‹ˆ๊นŒ?

ํฅ๋ฏธ๋กญ๊ฒŒ๋„์ด ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ๋ณด๋ฉด ์‹ค์ œ๋กœ ๋‹ค๋ฅธ
๋ฌธ์ œ. Icon์€ ๊ตฌ์„ฑ ์š”์†Œ์ด๋ฉฐ Icon ๋‚ด๋ถ€์—์„œ Icon์„ ์ฐธ์กฐํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ ์ž์ฒด.

๋‚ด๊ฐ€ ์•Œ์•„ ๋‚ธ ๋ฐฉ๋ฒ•์€ ๋Œ€๋ถ€๋ถ„ ๊ตฌ์„ฑ ์š”์†Œ๋ณ„๋กœ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ 
์–ด๋–ค ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ž๊ทน์„ ๋ฐ›์•˜๋Š”์ง€ ์•Œ ๋•Œ๊นŒ์ง€ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜์‹ญ์‹œ์˜ค.
๊ทธ.

2020 ๋…„ 5 ์›” 21 ์ผ ๋ชฉ์š”์ผ 18:20์— Vivek_Neel [email protected]์ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด ๋  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ํ† ๋ก ์— ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.
๋‚˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์„ ๊ฒฝํ—˜ํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ
์ œ ๊ฒฝ์šฐ์—๋Š” ๋ฌธ์ œ :

๋‹ค์Œ ์ฝ”๋“œ ์Šค ๋‹ˆํŽซ์—์„œ const ์•„์ด์ฝ˜์ด ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
์ฝ”๋“œ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•˜๋Š” ๋ฌดํ•œ ๋ฃจํ”„์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

const iconMapping = {
"flash-outline": FlashOutline,
};
๋‚ด๋ณด๋‚ด๊ธฐ const ์•„์ด์ฝ˜ = ({์ด๋ฆ„}) => {
const ์•„์ด์ฝ˜ = iconMapping [์ด๋ฆ„];

๋ฐ˜ํ™˜ ;
}

const Icon์ด ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธ์„ ์ถ”๊ฐ€ํ•˜๋ฉด
๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ.

...
const ์•„์ด์ฝ˜ = iconMapping [์ด๋ฆ„];

(! Icon) ๋ฐ˜ํ™˜ null;
๋ฐ˜ํ™˜ ;
}

์ด๊ฒƒ์ด ์ฝ”๋“œ์˜ ์ผ๋ถ€๋ผ๋Š” ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์•Œ์•˜์Šต๋‹ˆ๊นŒ?
๋ฐœํ–‰๋ฌผ?

โ€”
๋Œ“๊ธ€์„ ๋‹ฌ์•˜ ๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜์‹  ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/zeit/next.js/issues/7929#issuecomment-632187103 ๋˜๋Š”
๊ตฌ๋… ์ทจ์†Œ
https://github.com/notifications/unsubscribe-auth/ABA2CL7ZJQY5YPYJVCJMCODRSVIE7ANCNFSM4ICM4RAA
.

>

๋‚ด ํœด๋Œ€ ์ „ํ™”์—์„œ ๋ณด๋ƒ„

๋‚ด๊ฐ€ ์ดํ•ดํ•˜๋Š” ํ•œ Next.js (v9.0.0 ์ดํ›„)๋Š” ๋Œ€๊ทœ๋ชจ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋Š” ํ”„๋กœ์ ํŠธ์˜ ์„œ๋ฒ„ ์ธก ๋ถ€๋ถ„์„ ์ปดํŒŒ์ผํ•˜๊ธฐ ์‹œ์ž‘ํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์— ๋„๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ๋กœ์ปฌ ์„œ๋ฒ„๋Š” ์ฒ˜์Œ์—๋Š” ์ •์ƒ์ด์ง€๋งŒ ์–ผ๋งˆ ํ›„ ํ• ๋‹น ๋œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํญ๋ฐœํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ํž™ ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ํŒ€์˜ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€์ด ๋ฌธ์ œ๋ฅผ ์ธ์ •ํ•˜๊ณ  ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์ €์™€ ์ œ ํŒ€์€ ๊ฐ•๋ ฅํ•œ ๋žฉํ†ฑ์„ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๋•Œ๋•Œ๋กœ ๋กœ์ปฌ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ๊ฑฐ์˜ 1 ๋…„์ด ์ง€๋‚ฌ์ง€ ๋งŒ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜์žˆ๋Š” ์œ ์ผํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋‘ ๊ฐœ์˜ ํ•˜์œ„ Next.js ํ”„๋กœ์ ํŠธ๋กœ ๋ถ„ํ• ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ธ์  ๊ฐ€๋Š” CI์—์„œ๋„ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋นŒ๋“œ ํ•  ์ˆ˜ ์—†์„ ๊นŒ๋ด ๊ฑฑ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค (์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๊ฐ•๋ ฅํ•œ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ์œ„ํ•œ VM).

์—ฌ๊ธฐ์„œ ๋‚˜์œ ๋†ˆ์ด๋˜์–ด์„œ ์ •๋ง ๋ฏธ์•ˆ ํ•ด์š”, ๊ทธ๋ƒฅ ๋„์›€์„ ๊ตฌํ•˜๊ณ  ์žˆ์–ด์š”.

ํŽธ์ง‘ : Next.js 9.3.3์œผ๋กœ ์—…๋ฐ์ดํŠธํ–ˆ์ง€๋งŒ ๊ฐœ์„ ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ํŒ€์˜ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€์ด ๋ฌธ์ œ๋ฅผ ์ธ์ •ํ•˜๊ณ  ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

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

https://github.com/zeit/next.js/issues/7929#issuecomment -618297553๊ณผ ๊ฐ™์€ FWIW ์‚ฌ๋ก€๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑ ๋œ ๋ฌดํ•œ ๋ฃจํ”„์ด๋ฉฐ์ด๋ฅผ ์ž˜ ๊ฐ์ง€ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ).

๋‚ด๊ฐ€ ์ดํ•ดํ•˜๋Š” ํ•œ Next.js (v9.0.0 ์ดํ›„)๋Š” ๋Œ€๊ทœ๋ชจ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋Š” ํ”„๋กœ์ ํŠธ์˜ ์„œ๋ฒ„ ์ธก ๋ถ€๋ถ„์„ ์ปดํŒŒ์ผํ•˜๊ธฐ ์‹œ์ž‘ํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์— ๋„๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๊ท€ํ•˜๊ฐ€ ๋ณต์ œ๋ฌผ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ์ €๋Š” ์šฐ๋ฆฌ ์ž์‹ ์˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๋งŒ ์ฐธ์กฐ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Next.js์—์„œ ์ˆ˜๋ฐฑ๋งŒ ๊ฑด์˜ ์š”์ฒญ์„ ์‹คํ–‰ํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” 300 ๊ฐœ ์ด์ƒ์˜ ํŽ˜์ด์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํŒ€์—์„œ๋ณด๊ณ  ๋œ ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ๋Š” ์—†์—ˆ์œผ๋ฉฐ ํ•˜๋ฃจ ์ข…์ผ ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์—์„œ ์ž‘์—…ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ถ€์ธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์šฐ๋ฆฌ๊ฐ€ ํ”„๋กœํŒŒ์ผ ๋ง ํ•  ์ˆ˜์žˆ๋Š” ๋ช…ํ™•ํ•œ ๋ณต์ œ ๋˜๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ๋‚˜๋Š” ์œ ๋ฃŒ ์ปจ์„คํŒ…์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‹ ์ฒญ์„œ๋ฅผ ๋ฌด๋ฃŒ๋กœ ์‚ดํŽด๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

๋‚ด๊ฐ€ ๋ฌธ์ œ๋ฅผ ์—ฐ ์ดํ›„๋กœ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์—ฌ๊ธฐ์— ์ €์žฅ์†Œ๋ฅผ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋‹ค์‹œ ์—ด๋ฆฐ ์ด์œ ์ด๋ฉฐ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๋ ค๋ฉด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๋ ˆ์ด๋ธ”์ด์—†๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐœ๋ด‰ ํ•œ ์ดํ›„๋กœ

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‚ด ํด๋ผ์ด์–ธํŠธ์— ์†ํ•˜๊ณ  ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ๋‹ซํ˜€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ €์žฅ์†Œ๋ฅผ ์ œ๊ณต ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

9.4 btw์—์„œ ์†Œ์Šค ๋งต ์ƒ์„ฑ์„ ๋ณ€๊ฒฝ ํ–ˆ์œผ๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ์ด ์˜ตํŠธ ์ธ / ์˜ตํŠธ ์•„์›ƒ์ž…๋‹ˆ๊นŒ? (์•„์ฃผ ์˜ค๋ž˜ ์ „) ์ด์Šˆ๋ฅผ ์—ฐ ํ›„ ์†Œ์Šค ๋งต ์ƒ์„ฑ (ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋จ)์„ ์ œ๊ฑฐํ–ˆ์ง€๋งŒ ๊ทธ๋‹ค์ง€ ๋„์›€์ด๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋ฉด ๋‹ซ์œผ์‹ญ์‹œ์˜ค. ์ €์žฅ์†Œ๋Š” ์˜ค๋ž˜ ์ „์— ๊ณต์œ ๋˜์—ˆ์œผ๋ฉฐ ๋” ์ด์ƒ ์œ ํšจํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ฌ์‚ฌ๋ฅผ ๋„์™€ ๋“œ๋ฆด ์ˆ˜ ์žˆ์ง€๋งŒ ์•ˆ๋‚ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

โ–ฒ  styled-icons (master) โœ— yarn build:ci
yarn run v1.22.4
$ lerna run build
lerna notice cli v3.21.0
lerna info Executing command in 25 packages: "yarn run build"
lerna info run Ran npm script 'build' in '@styled-icons/styled-icon' in 6.6s:
$ tsc --project tsconfig.esm.json && mv dist/index.js dist/index.esm.js && tsc --project tsconfig.json
lerna ERR! yarn run build exited 1 in '@styled-icons/boxicons-logos'
lerna ERR! yarn run build stdout:
$ build-pack
Reading icon packs...
Error reading icons from pack
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

lerna ERR! yarn run build stderr:
error Command failed with exit code 1.

lerna ERR! yarn run build exited 1 in '@styled-icons/boxicons-logos'
lerna WARN complete Waiting for 4 child processes to exit. CTRL-C to exit immediately.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

์žฌ์ƒ์€ ๋‚ด๊ฐ€์ด ๊ฐ™์€ ํ”ผํ•˜๊ธฐ ๊ฒฝ์šฐ์— ์žฌ์ƒ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์—๋ณด๊ณ  ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋ฌผ์—ˆ๋‹ค ๋”ฐ๋ผ์„œ ์™œ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๊ฐ€ 100 % ๋™์ผ ํ•  ๊ฐ€๋Šฅ์„ฑ์€ ๋งค์šฐ ๋‚ฎ์Šต๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ์ด ์˜ตํŠธ ์ธ / ์˜ตํŠธ ์•„์›ƒ์ž…๋‹ˆ๊นŒ? (์•„์ฃผ ์˜ค๋ž˜ ์ „) ์ด์Šˆ๋ฅผ ์—ฐ ํ›„ ์†Œ์Šค ๋งต ์ƒ์„ฑ (ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋จ)์„ ์ œ๊ฑฐํ–ˆ์ง€๋งŒ ๊ทธ๋‹ค์ง€ ๋„์›€์ด๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์†Œ์Šค ๋งต์€ ๊ฐœ๋ฐœ์‹œ ํ•ญ์ƒ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์ง€๋งŒ ํ‰๊ฐ€ ์†Œ์Šค ๋งต์œผ๋กœ ์ „ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋‹ค์‹œ ์—ด๋ฆฐ ์ด์œ ์ด๋ฉฐ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๋ ค๋ฉด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๋ ˆ์ด๋ธ”์ด์—†๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋” ๋งŽ์€ ๋ณด๊ณ ์„œ๊ฐ€ ๊ณ„์† ๋“ค์–ด์˜ค๊ณ  ๊ณ„์† ๋ณต์ œ๋ฌผ์„ ์š”์ฒญํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค : https://github.com/zeit/next.js/issues/7929#issuecomment -568760542

์ด ์Šค๋ ˆ๋“œ์—๋Š” 2 ๊ฐœ์˜ ๋ณต์ œํ’ˆ ๋งŒ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” Next.js ( now dev ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„)์™€ ์™„์ „ํžˆ ๊ด€๋ จ์ด ์—†์œผ๋ฉฐ ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์‹คํ–‰ / ๋นŒ๋“œ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‚ด๊ฐ€ ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ „์ฒด ๋ณต์ œ๋ฅผ ์š”์ฒญํ•˜๋Š” ์ด์œ ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์กฐ์‚ฌ๊ฐ€ ๊ณ„์† ๋ถˆ๊ฐ€๋Šฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‚ด ํด๋ผ์ด์–ธํŠธ์— ์†ํ•˜๊ณ  ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ๋‹ซํ˜€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ €์žฅ์†Œ๋ฅผ ์ œ๊ณต ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

[email protected] ์œผ๋กœ ์—ฐ๋ฝํ•ด ์ฃผ์‹œ๋ฉด NDA๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.์ด ๋ชจ๋“  ๊ฒƒ์„ ์„ค์ •ํ•˜๋Š” ๋ฐ ์ƒ๋‹นํ•œ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋”๋ผ๋„ ์ž ์žฌ์ ์œผ๋กœ ๊ท€ํ•˜๋ฅผ ์œ„ํ•ด ์ปจ์„คํŒ…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ๋„์›€์ด๋˜๋ฉฐ ํด๋ผ์ด์–ธํŠธ ์šฉ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๋„ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๋‹จ์ˆœํžˆ ํฌ๊ธฐ ๋ฒ”์œ„์— ๋„๋‹ฌํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์„ ์‹œ์ž‘ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. NODE_OPTIONS=--max-old-space-size=4096 ๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€๋กœ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋˜๋Š” ์ƒˆ๋กœ์šด ์ฒญํ‚น ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// next.config.js
module.exports = {
  experimental: { granularChunks: true }
}

์ด๊ฒƒ์€ ์šฐ๋ฆฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ.

๋ˆ„๊ตฌ๋‚˜์ด ๋ฌธ์ œ๊ฐ€ ๋‚ด์žฅ ๋œ ๋‹ค์Œ ์„œ๋ฒ„ ์‹œ์ž‘์—์„œ ๋ฐœ์ƒํ•˜๋Š”์ง€ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
์ฆ‰ : Next start ๋Œ€์‹  NODE_ENV=production node server.js" ?

๋‚ด ๋ฌธ์ œ๋Š” ๋นŒ๋“œ ์ƒ์„ฑ ํ›„ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. "node server.js"๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋‚ด ์‚ฌ์šฉ์ž ์ •์˜ ์„œ๋ฒ„์—์„œ ํ•ด๋‹น ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‹ค์‹œ ์‹œ์ž‘๋  ๋•Œ๊นŒ์ง€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์บ์‹œ ๋œ ๋ชจ๋“  ๊ฒฝ๋กœ์™€ ํ•ญ๋ชฉ์„ ์žƒ์–ด ๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ์ดํ›„์— ํŽ˜์ด์ง€๋ฅผ ์ž…๋ ฅํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋ชจ๋“  SSR์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
0|profiles |  1: 0xa093f0 node::Abort() [node /home/projects/profiles/server.js]
0|profiles |  2: 0xa097fc node::OnFatalError(char const*, char const*) [node /home/projects/profiles/server.js]
0|profiles |  3: 0xb842ae v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node /home/projects/profiles/server.js]
0|profiles |  4: 0xb84629 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node /home/projects/profiles/server.js]
0|profiles |  5: 0xd30fe5  [node /home/projects/profiles/server.js]
0|profiles |  6: 0xd31676 v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [node /home/projects/profiles/server.js]
0|profiles |  7: 0xd3def5 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node /home/projects/profiles/server.js]
0|profiles |  8: 0xd3eda5 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node /home/projects/profiles/server.js]
0|profiles |  9: 0xd4185c v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node /home/projects/profiles/server.js]
0|profiles | 10: 0xd0830b v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [node /home/projects/profiles/server.js]
0|profiles | 11: 0x1049f4e v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [node /home/projects/profiles/server.js]
0|profiles | 12: 0x13cf019  [node /home/projects/profiles/server.js]

์ด๊ฒƒ์€ ๋‚ด package.json์ž…๋‹ˆ๋‹ค.

{
  "name": "profiles",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "node server.js",
    "build": "yarn relay && next build",
    "start": "NODE_ENV=production node server.js",
    "relay": "relay-compiler --src ./ --exclude '**/.next/**' '**/node_modules/**' '**/test/**'  '**/__generated__/**' --exclude '**/schema/**' --schema ./var/schema.graphql --artifactDirectory __generated__",
    "relay-get-schema-stage": "graphql get-schema --project sourcr --endpoint stage && yarn run relay",
    "relay-get-schema-prod": "graphql get-schema --project sourcr --endpoint prod && yarn run relay",
    "relay-get-schema-dev": "graphql get-schema --project sourcr --endpoint dev && yarn run relay",
    "pm2": "pm2"
  },
  "dependencies": {
    "@babel/plugin-proposal-class-properties": "^7.10.4",
    "@babel/plugin-proposal-decorators": "^7.10.5",
    "@babel/plugin-proposal-export-default-from": "^7.10.4",
    "@babel/plugin-proposal-optional-chaining": "^7.11.0",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/plugin-transform-runtime": "^7.11.0",
    "@fortawesome/fontawesome": "^1.1.8",
    "@fortawesome/fontawesome-free-regular": "^5.0.13",
    "@fortawesome/fontawesome-free-solid": "^5.0.13",
    "@fortawesome/react-fontawesome": "^0.1.11",
    "@sentry/browser": "^5.21.0",
    "@svgr/webpack": "^5.4.0",
    "babel-loader": "^8.1.0",
    "babel-plugin-styled-components": "^1.11.1",
    "babel-plugin-transform-export-extensions": "^6.22.0",
    "bootstrap": "^4.5.2",
    "classnames": "^2.2.6",
    "file-loader": "^6.0.0",
    "formsy-react": "^1.1.5",
    "graphql": "^15.3.0",
    "jwt-decode": "^2.2.0",
    "mobx": "^5.15.5",
    "moment": "^2.28.0",
    "next": "9.5.1",
    "path": "^0.12.7",
    "pm2": "^4.5.0",
    "query-string": "^6.13.1",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-helmet": "^6.1.0",
    "react-player": "^2.6.0",
    "react-relay": "^10.0.1",
    "react-relay-network-modern": "^4.7.4",
    "react-relay-network-modern-ssr": "^1.4.0",
    "react-toastify": "^6.0.8",
    "relay-compiler": "^10.0.1",
    "relay-devtools": "^1.4.0",
    "relay-devtools-core": "^0.0.8",
    "relay-runtime": "^10.0.1",
    "sass": "^1.26.10",
    "sass-resources-loader": "^2.0.3",
    "siema": "^1.5.1",
    "transform-class-properties": "^0.1.0"
  },
  "devDependencies": {
    "babel-plugin-relay": "^10.0.1"
  }
}

next build ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ ์žˆ๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด .babelrc ๋˜๋Š” babel.config.js ์‚ญ์ œ ํ•ด๋ณด์„ธ์š”. Next.js์™€ ๊ด€๋ จ์ด์—†๋Š” ๋‚ด ํ”„๋กœ์ ํŠธ์˜ ๋ณ„๋„ ๋ถ€๋ถ„์— ๋Œ€ํ•ด .babelrc ์ด ์žˆ๋Š”๋ฐ next build ๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ œ ์ƒํ™ฉ์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ Docker์—์„œ๋งŒ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด Dockerfile์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

FROM node:12
WORKDIR /app
COPY package.json package-lock.json /app/
ENV NODE_ENV production
RUN npm install
COPY . /app
RUN npm run build
RUN npm run next-build
EXPOSE 8081
CMD ["npm", "start"]

์ด์—

FROM node:12
WORKDIR /app
COPY package.json package-lock.json /app/
ENV NODE_ENV production
RUN npm install
COPY . /app
RUN npm run build
# Let Next.js use its own Babel config
RUN rm .babelrc
RUN npm run next-build
EXPOSE 8081
CMD ["npm", "start"]

GitLab CI์—์„œ ๊ณต์œ  ์‹คํ–‰๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ์‹คํ–‰๊ธฐ๋Š” SIGABRT ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ์ฐจ๋ก€๋กœ์ด ์˜ค๋ฅ˜๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๋ฃน ์ฃผ์ž๋กœ ๋‹ค์‹œ ์ „ํ™˜ํ–ˆ๊ณ  ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

next-transpile-modules ๊ฒฝ์šฐ ๋‚ด ํ•ด๊ฒฐ์ฑ…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด resolveSymlinks -setting (v4.1.0๋ถ€ํ„ฐ)์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

// next.config.js
const withTM = require("next-transpile-modules")([
    "somepackage"
], {
    resolveSymlinks: true
})
module.exports = {
    ...withTM()
}

somepackage ๊ฐ€ "๋„ˆ๋ฌด ์ปค์กŒ์„ ๋•Œ"(500kb์—์„œ 700kb๋กœ) ์ฒ˜์Œ์— ์—ฌ๊ธฐ์— ์„ค๋ช… ๋œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๊ฐ‘์ž๊ธฐ ๋ชจ๋“  ๋ฉ”๋ชจ๋ฆฌ (8GB ์˜ต์…˜์œผ๋กœ ์‹œ๋„)๊ฐ€์ด ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. .

๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ธฐํ•˜ ๊ธ‰์ˆ˜์ ์œผ๋กœ ๋ถ€ ํ’€๋ฆฌ๋Š” ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋กœ ์ธํ•œ ๋ฃจํ”„๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

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