ํธ์ง: ์์ํ๊ธฐ ์ํ ๋น ๋ฅธ ๊ฐ์ด๋: https://jestjs.io/docs/en/ecmascript-modules
ESM ์ง์์ Node 12์ ํฅํ ๋ฆด๋ฆฌ์ค์์ ํ๋๊ทธ๊ฐ ํด์ ๋ ์์ ์ด๋ฉฐ(4์ ์ด์ ์ด ์๋ ์๋ ์์ https://github.com/nodejs/node/pull/29866#issuecomment-574055057) Node 13.2์์ ์ด๋ฏธ ํ๋๊ทธ๊ฐ ํด์ ๋์ด ์์ผ๋ฏ๋ก ๋ค์๊ณผ ๊ฐ์ด ์๊ฐํฉ๋๋ค. Jest์์ ๊ธฐ๋ณธ ์ง์์ ์ถ๊ฐํ ์ ์๋ ๋ฐฉ๋ฒ์ ํ๊ฐํ ์๊ฐ์ ๋๋ค. ESM ์ง์์ ์ํฅ์ ๋ฐ๋ Jest๊ฐ ํ์ฌ ์ ๊ณตํ๋ ๊ธฐ๋ฅ๊ณผ ์ด๋ฅผ ํด๊ฒฐ/์กฐ์ฌํ๋ ๋ฐฉ๋ฒ์ ๋์ดํ๋ ค๊ณ ํฉ๋๋ค.
๋ฌธ์ #4842๊ฐ ์์ง๋ง ํ ๋ก ๋ฌธ์ ์ ๋ ๊ฐ๊น๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด ๋ฌธ์ ๋ ์ค์ ๋ก ์ง์์ ๊ตฌํํ๋ ๋ฐ ์ด์ ์ ๋ง์ถ๊ณ ํ์ฌ ๊ตฌํ ์ํ๋ฅผ ํ์ธํ๋ ค๋ ์ฌ๋๋ค์ ์ถ์ ํ๋ ๋ฐ ๋ ์ ํฉํ ๊ฒ์ ๋๋ค. ์๋ ์ด๊ฑฐ๋ ๊ธฐ๋ฅ์ ๋ํ ์ง์์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ๊ณผ ๊ด๋ จ์ด _์๋_ ์ด ๋ฌธ์ ์ ์ถ๊ฐ๋ ๋ชจ๋ ์๊ฒฌ์ ์คํธ์ผ๋ก ํ์๋ฉ๋๋ค. ํด๊ฒฐ ๋ฐฉ๋ฒ/ํ ๋ก ์ ๋ณ๋์ ๋ฌธ์ ๋ก ๋ณด๋ด์ฃผ์ญ์์ค. ๋ํ ESM ๊ธฐ๋ฅ๊ณผ ๊ด๋ จ๋ ํญ๋ชฉ์ด ๋ชฉ๋ก์์ ๋๋ฝ๋ ๊ฒฝ์ฐ ์ธ์ ๋ ์ง ์ ํฌ์๊ฒ ์๋ ค์ฃผ์ญ์์ค!
Jest๋ vm
API(https://nodejs.org/api/vm.html)๋ฅผ ์ฌ์ฉํ๋ฉฐ ์์ฑ ์์ (node โโv13.6) ์ด API์ ESM ๋ถ๋ถ์ ์ฌ์ ํ โโํ๋๊ทธ๊ฐ ์ง์ ๋์ด ์์ต๋๋ค( --experimental-vm-modules
). ๋ฐ๋ผ์ ESM์ด ํ๋๊ทธ๊ฐ ์ง์ ๋์ง ์์๋ค๊ณ ๋งํ๋ ๊ฒ์ ํ์ฌ๋ก์๋ ์ฝ๊ฐ ์๋ชป๋ ๋ช
์นญ์
๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ์ฐ๋ฆฌ๊ฐ ์คํ์ ์์ํ๊ณ ์ ์ฌ์ ์ผ๋ก Modules WG์ ํผ๋๋ฐฑ์ ์ ๊ณตํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก, ์ ๋ ์ด ๋ฌธ์ ๋ฅผ ์ฃผ๋ก ์ง์์ ๊ตฌํํ ์ฌ๋๋ค์ ์ํด ์์ฑํ๊ณ ์์ผ๋ฏ๋ก Jest๊ฐ ์๋ํ๋ ๋ฐฉ์์ ๋ฐ๋ผ ๋ค์ ๋ฎ์ ์์ค์ด ๋ ๊ฒ์ ๋๋ค. ์ง์์ด ์์๋์๋์ง ์ฌ๋ถ๋ฅผ ์๊ณ ์ถ์ดํ๋ _๊ทธ๋ฅ__ GH์ ๋ฉ์ง "๋ง์ถค ์๋ฆผ"์ โโ์ฌ์ฉํ๊ณ ๋ซ๊ธฐ/๋ค์ ์ด ๋ ์๋ฆผ์ ๊ตฌ๋ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ฃผ์ด์ง vm.Context
(JSDOM ๋๋ ๋
ธ๋ ์ฝ์ด API์์ ์ ๊ณต) ๋ด์์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ฌ ์๋๋ฐ์ค๋ฅผ ๊ตฌํํฉ๋๋ค. ESM์ ๋ํด์๋ ๋์ผํ ์์
์ ์ํํด์ผ ํ์ง๋ง ๋ชจ๋์ ์คํํ ๋๋ฟ๋ง ์๋๋ผ ๋ชจ๋์ ๊ตฌ์ฑํ๋ ๋์์๋ context
์ก์ธ์คํด์ผ ํฉ๋๋ค. JestEnvironment
ํ์ํ API๋ฅผ ์ถ๊ฐํ๋ #9428์ ์ด์์ต๋๋ค.
expect
, test
, beforeEach
๋ฑ์ ์ฌ์ ํ โโ์ ์ญ์ผ๋ก ์ถ๊ฐ๋๋ฉฐ ์ฌ๊ธฐ์์๋ ์๋ฌด ๊ฒ๋ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค. jasmine
๊ธ๋ก๋ฒ๋ ์ฌ์ ํ ์ฌ๊ธฐ์ ์์ต๋๋ค.
jest
"์ ์ญ" ์์ฑ์ด๊ฒ์ ์ค์ ๋ก ์ ์ญ์ด ์๋๋๋ค. ๋ชจ๋ ๋ฒ์์ ์ฃผ์
๋ฉ๋๋ค. ๋ชจ๋ ๋ฒ์๊ฐ ESM์์ ์ฌ๋ผ์ก๊ธฐ ๋๋ฌธ์ ์ด๋๊ฐ๋ก ์ฎ๊ฒจ์ผ ํฉ๋๋ค. import.meta
์ถ๊ฐํ๋ ๊ฒ์ด ์์ฐ์ค๋ฌ์ ๋ณด์
๋๋ค. initializeImportMeta
๋ผ๋ ์ต์
์ด ์์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํธ์ง: ํด๊ฒฐ์ฑ
์ import {jest} from '@jest/globals'
๋ฅผ ํตํด ๊ฐ์ ธ์ค๋ ๊ฒ์
๋๋ค. ์์ผ๋ก import.meta
๋ฅผ ํตํด ๊ณ์ ์ถ๊ฐํ ์ ์์ง๋ง ์ง๊ธ์ ์ด๊ฒ์ผ๋ก ์ถฉ๋ถํฉ๋๋ค.
jest.(do|un)mock
ESM์ ๋ชจ๋์ ํ๊ฐํ ๋ ๋ค๋ฅธ "๋จ๊ณ"๋ฅผ ๊ฐ์ง๋ฏ๋ก jest.mock
๋ ์ ์ ๊ฐ์ ธ์ค๊ธฐ์ ๋ํด ์๋ํ์ง ์์ต๋๋ค. ํ์ง๋ง ๋์ ๊ฐ์ ธ์ค๊ธฐ์์ ์๋ํ ์ ์์ผ๋ฏ๋ก ๋ฌธ์์์ ์ง์ํ๋ ๊ฒ๊ณผ ์ง์ํ์ง ์๋ ๊ฒ์ ๋ํด ๋ช
ํํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
jest.mock
ํธ์ถ์ด ํธ์ด์คํธ๋์ง๋ง ESM์์๋ ๋์์ด ๋์ง ์์ต๋๋ค. import 'thing'
๋ฅผ import('thing')
๋ณํํ๋ ๊ฒ์ ๊ณ ๋ คํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ํธ์ด์คํ
์ด ์๋ํ ์ ์์ง๋ง ๋น๋๊ธฐ์
๋๋ค. ์ต์์ await
๊ฒ์ ์๋ง๋ ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์์ ํ์ ์์์ผ ๊ฒ์
๋๋ค. ๋๋ ๋ํ ๋ณ๋์ ์ ํ์ ์ ๋นํํ๊ธฐ์ ์ถฉ๋ถํ ์นจ๋ต์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋
ผ์ํ ์ฌํญ - ์ด๊ธฐ ๋ฆด๋ฆฌ์ค์ ๋ํด jest.mock
ํ ์ ์๋ ๋ชจ๋ ๊ฒ์ ์ง์ํ ํ์๋ ์์ต๋๋ค.
jest.requireActual
ESM์์ ์ด๋ป๊ฒ ์๋ํด์ผ ํ๋์ง ํ์คํ์ง ์์ต๋๋ค. jest.importActual
๋ฅผ ์ ๊ณตํ๊ณ requireActual
CJS
ํญ์
import.meta
๋
ธ๋์ ์ ์ผํ ์์ฑ์ url
(์ ์ด๋ ํ์ฌ๋ก์๋). Jest์๋ ์ฑ์์ ธ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ ๊ณต identifier
๋์ filename
๋๋ ๊ทธ๊ฒ์ด ์๋์ผ๋ก ์ผ์ด๋ ๊ฒ์
๋๋ค ์๊ฐํ์ง ์๋๋ก ๋ชจ๋์ ๊ตฌ์ฑ ํ ๋,ํ์ง๋ง url
๋ณธ์ง์ ์ผ๋ก filename
๋ถ๊ตฌํ๊ณ ํต๊ณผ pathToFileURL
.
import.meta.resolve
๋ํ ๊ณต๊ฐ PR๋ ์์ต๋๋ค. https://github.com/nodejs/node/pull/31032
import thing from 'thing'
์ด๊ฒ์ ์ค์ ๋ก ๋งค์ฐ ๊ฐ๋จํด์ผ ํฉ๋๋ค. linker
๋ฅผ ๊ตฌํํ๋ฉด ๋ฉ๋๋ค. ์ฌ๊ธฐ์ ์์ค๋ฅผ ๋ฐํํ๊ธฐ ์ ์ ๋ณํํ ์๋ ์์ต๋๋ค. ์ฆ, ๋ก๋ API(์์ง ์กด์ฌํ์ง ์์)๊ฐ ํ์ํ์ง ์์ต๋๋ค. ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ๋ชจ์ ๊ฐ์ฒด๋ ๋ฐํํ ์ ์๋๋ก ํฉ๋๋ค( __mocks__
๋๋ ํ ๋ฆฌ์์ ๊ฐ์ ธ์์ผ ํ์ง๋ง).
import('thing')
๋ณธ์ง์ ์ผ๋ก ์์ ๊ฐ์ง๋ง ๋ชจ๋์ ๊ตฌ์ฑํ ๋ importModuleDynamically
๋ก ์ ๋ฌ๋ฉ๋๋ค. ๋ํ jest.mock
, jest.resetModules
๋ฑ์ ๋ณด๋ค ๊น๋ํ๊ฒ ์ง์ํ๋ฏ๋ก ๊ฝค ๋ง์ด ์ฌ์ฉ๋ ๊ฒ์
๋๋ค.
์ด๊ฒ์ ๋์ผํ ์ต์
์ ํตํด vm.Script
๋ํด์๋ ์ํํ ์ ์์ต๋๋ค.
์ง๊ธ์ ๋ฐํ์ ์ค๋ฅ(์: ๋ชจ๋์ ์ฐพ์ ์ ์์)์ด์ง๋ง ESM์์๋ ๋ฐ๋์ ๊ทธ๋ ์ง๋ ์์ต๋๋ค. ์ฐ๋ฆฌ์๊ฒ ์ค์ํฉ๋๊น? ์ค๋ฅ๊ฐ ์ฌ์ ํ ์ข์ ๋ณด์ด๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
module.createRequire
ESM์์ CJS๋ฅผ ์ฌ์ฉํ๋ ค๋ ์ฌ๋๋ค์ ์ํด ์ด๊ฒ์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. ๊ตฌํ์ด ESM ์ง์๊ณผ ์ค์ ๋ก ๊ด๋ จ์ด ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ณ๋๋ก ์ถ์ ํ๊ธฐ ์ํด #9426์ ์ด์์ต๋๋ค.
ํธ์ง: #9469์์ ๊ตฌํ๋จ
module.syncBuiltinESMExports
https://nodejs.org/api/modules.html#modules_module_syncbuiltinesmexports. ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ํด ์ ๊ฒฝ์ ์ฐ๊ณ ์์ต๋๊น, ์๋๋ฉด ๊ทธ๋ฅ ์๋ฌด ์์ ๋ ํ์ง ์๋ ๊ฒ์ผ๋ก๋ง ํ๊ณ ์์ต๋๊น? Jest์ ์ฌ์ฉ ์ฌ๋ก๊ฐ ๋ฌด์์ธ์ง ํ์คํ์ง ์์ต๋๋ค. ๋ด์ฅ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ด๋ฏธ ์๋๋ฐ์ค๋ฅผ ๊นจ๊ณ ์์ผ๋ฉฐ ์ด๊ฒ์ด ์ค์ํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
ํธ์ง: #9469๋ ์ด๊ฒ์ ๋ ธ์ต์ค๋ก ๋ง๋ค์์ต๋๋ค. ๊ด์ฐฎ์ ๊ฒ ๊ฐ์์?
๋ชจ๋์ package.json
์์ type
ํ๋๋ฅผ ๊ฒ์ฌํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ผ๋ก ๋ณด์
๋๋ค: https://nodejs.org/api/esm.html#esm_enabling. ์ฐ๋ฆฌ ์์ ์ ์ค์ ํ๋๊ทธ๋ ์์ด์ผ ํฉ๋๊น? ๋ํ ํ์ผ ๋์ ์กด์คํด์ผ ํฉ๋๋ค.
https://github.com/nodejs/modules/issues/393
moduleNameMapper
์ด๊ฒ์ด ์ด๋ค ์ํฅ์ ๋ฏธ์น๋์ง ํ์คํ์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ค์ค๋ก ๋ชจ๋์ ์ฐ๊ฒฐํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ _์๊ฐ_ํ์ง ์์ต๋๋ค. ์กฐ์ฌ๊ฐ ํ์ํ์ง๋ง.
ํธ์ง: ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ์ ์ดํ๋ โโ๋ชจ๋ ํด๊ฒฐ ๋ ผ๋ฆฌ์ ๋๋ค. ๋ฐ๋ผ์ ์ฌ๊ธฐ์ ๋ณ๊ฒฝ ์ฌํญ์ด ์์ต๋๋ค.
jest.config.mjs
#9291์ ํตํด ์ฐ๋ฆฌ๋ jest.config.cjs
- .mjs
๋ํด ํน๋ณํ ์กฐ์น๋ฅผ ์ทจํด์ผ ํฉ๋๊น? ์๋ง๋ import('path/to/configFile.mjs')
๋ฅผ ์ฌ์ฉํ๋ฉด ๋น๋๊ธฐ์์ด์ด์ผ ํจ์ ์๋ฏธํฉ๋๋ค. ์ด๊ฒ์ด ๋ฌธ์ ์
๋๊น? Jest 25์์ ๊ตฌ์ฑ ํด์๋๋ฅผ async
๋ก ๋ง๋๋ ๊ฒ์ด ๊ฐ์น๊ฐ ์์ ์ ์์ผ๋ฏ๋ก Jest 25์์ ESM์ ์ฆ๋ถ ์ง์์ ์ํ ์ฐจ๋จ๊ธฐ๊ฐ ์๋๋๋ค.
ํธ์ง: #9431
Node๋ Jest์ moduleNameMapper
๋งคํ๋๋ ํจํค์ง ๋ด๋ณด๋ด๊ธฐ๋ฅผ ์ง์ํ์ง๋ง ์บก์ํ ๊ธฐ๋ฅ๋ ์ ๊ณตํฉ๋๋ค. ๋ฐ๋ผ๊ฑด๋ resolve
๊ฐ ์ด๊ฒ์ ๊ตฌํํ์ง๋ง, ๊ตฌํํ์ง ์์ผ๋ฉด ์ฐ๋ฆฌ๋ ๋ญ๊ฐ๋ฅผ ํด์ผ ํฉ๋๋ค. pathFilter
์ต์
์ ์ฌ์ฉํ๊ธฐ์ ์ถฉ๋ถํ ๊น์? ๋ถ์์ ํ.
https://nodejs.org/api/esm.html#esm_experimental_json_modules. ์ฐ๋ฆฌ๊ฐ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์์ต๋๊น? ์๋ง๋ json
๊ฒฝ์ฐ ํนํ ๊ทธ๋ ์ต๋๋ค. ์ฐ๊ฒฐ ๋จ๊ณ๋ฅผ ์ ์ดํ๊ธฐ ๋๋ฌธ์ import thing from './package.json'
๋ฅผ ์ง์ํ๋ ๊ฒ์ ์ฌ์ํ์ง๋ง ๊ธฐ๋ณธ ๋
ธ๋์ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํด์๋ ์ ๋ฉ๋๋ค. ์ฌ๋๋ค์ด ๋ณํ์ ์ ์ํ๋๋ก ๊ฐ์ ํด์ผ ํฉ๋๊น?
์๊ด์ด ์๋? babel๋ก ์์ค๋ฅผ ๋ณํํ ์ ์๊ธฐ ๋๋ฌธ์ ์ํฅ์ ๋ฐ์ง ์๋๋ค๊ณ ์๊ฐํฉ๋๋ค( import
๋ฌธ์ผ๋ก ํผ๋๋ ์๋ ์๊ณ ๊ทธ๋ ์ง ์์ ์๋ ์์). V8 ์ ์ฉ ๋ฒ์๋ ํ์คํ ์ ๊ฒฝ์ฐ์ง ์์์ผ ํฉ๋๋ค. ๊ทธ๋๋ ํ์ธํด์ผ ํฉ๋๋ค.
๋๊ธฐํ ํด์๋๊ฐ ์ ๋๋ก ์๋ํ๋ฏ๋ก ์ด๊ฒ์ ์ ๋์ ์ผ๋ก ์ฐจ๋จ๊ธฐ๊ฐ ์๋๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ์ง๊ธ ๋น๋๊ธฐ ํด์๋๋ฅผ _ํ ์ ์์ต๋๋ค_. ํ๋ฅญํฉ๋๋ค. ์ด๋ฏธ ๋น๋๊ธฐ๋ฅผ ์ง์ํ๊ธฐ ๋๋ฌธ์ npm์์ resolve
๋ชจ๋์ ๋ค์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ด์ผ ํ๋์ง ๊ถ๊ธํฉ๋๋ค. #9505๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
์์ ์ ์ฌํ๊ฒ ์ฐจ๋จ์ ์๋์ง๋ง ์ง์ํด์ฃผ์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค. ๋ค๋ฅธ ํ๊ฒฝ์์๋ @jest/transformer
๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. #9504๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
#5163์ผ๋ก ์ธํด ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก extraGlobals
์ต์
์ด ์์ต๋๋ค. ์ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ ESM์์ ๋ ์ด์ ์คํ ๊ฐ๋ฅํ์ง ์์ต๋๋ค. ์ฌ๊ธฐ์์ ๋
ธ๋๋ฅผ ์ด๊ณ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค. https://github.com/nodejs/node/issues/31658
#9772๋ก ๋งค์ฐ ๊ธฐ๋ณธ์ ์ธ ์ง์์ ๋ฐ์์ต๋๋ค. ๊ฐ์ฅ ๋จ์ํ ๊ฒฝ์ฐ๋ง ํ
์คํธํ์ผ๋ฉฐ ์๋ ค์ง ์ ํ ์ฌํญ์ด ๋ง์ด ์์ต๋๋ค(ํนํ CJS์ ESM์ ํผํฉํ ๋ jest
๊ฐ์ฒด ์ง์ ๋ฐ ๊นจ์ง ์๋ฏธ ์ฒด๊ณ ์์). ๊ทธ๋ฌ๋ ์ ์ด๋ _๋ฌด์ธ๊ฐ_์
๋๋ค. Jest์ ๋ค์ ๋ฆด๋ฆฌ์ค์์ ๋์ฌ ์์ ์
๋๋ค(๊ณง #9806์ผ๋ก ์ฐจ๋จ๋จ)
25.4.0์ด ์ฒซ ๋ฒ์งธ ์ง์๊ณผ ํจ๊ป ๋ฆด๋ฆฌ์ค๋์์ต๋๋ค. ์์์ ์ธ๊ธํ #9772 ์ธ์๋ #9842๋ ํฌํจํ์ต๋๋ค. _์ด๋ก ์ ์ผ๋ก_ CJS์ ESM์ ํผํฉํ๋ฉด ์ด์ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํฉ๋๋ค(๐ค).
ํ ๊ฐ์ง ์ฃผ์ ๋๋ฝ ๊ธฐ๋ฅ์ jest
๊ฐ์ฒด๋ฅผ ์ง์ํ๋ ๊ฒ์
๋๋ค. import.meta
ํ ์ง ์๋๋ฉด import {jest} from '@jest/globals'
ํตํด ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์๊ตฌํ ์ง ๊ฒฐ์ ํ์ง ์์์ต๋๋ค. ํผ๋๋ฐฑ ๊ฐ์ฌํฉ๋๋ค!
์์ง ์ด์ ๋ํ ๋ฌธ์๋ฅผ ์์ฑํ์ง ์์์ง๋ง ํ์ฑํํ๋ ค๋ฉด 3๊ฐ์ง ์์ ์ ์ํํด์ผ ํฉ๋๋ค.
import
๋ฌธ์ ์คํํ์ง ์์๋์ง ํ์ธํ์ญ์์ค(config์์ transform: {}
๋ฅผ ์ค์ ํ๊ฑฐ๋ babel
๋ฅผ ํผํ๋ ๊ฒ๊ณผ ๊ฐ์ด modules
์ฌ์ ์ค์ ํ๊ฒฝ์ ๋ํ ์ต์
)--experimental-vm-modules
ํ๋๊ทธ๋ก node@^12.16.0 || >=13.2.0
์คํjest-environment-node
๋๋ jest-environment-jsdom-sixteen
ํ
์คํธ ์คํ์ฌ์ฉํด๋ณด๊ณ ํผ๋๋ฐฑ์ ์ฃผ์ธ์! ๋ฒ๊ทธ๋ฅผ ๋ณด๊ณ ํ๋ ๊ฒฝ์ฐ Node.js์์ ๋์ผํ ์ฝ๋(ํ ์คํธ๋ณ ์ฝ๋ ์ ์ธ)๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ๋ ํฌํจํ ์ ์๋ค๋ฉด ์ ๋ง ์ข์ ๊ฒ์ ๋๋ค. ์ง๋ ๋ช ์ฃผ ๋์ https://nodejs.org/api/esm.html _๋ง์ด_ ์ฝ์์ง๋ง ์๋ง๋ ๋ญ๊ฐ๋ฅผ ๋์ณค์ ๊ฒ์ ๋๋ค.
ํ ๊ฐ์ง ์ฃผ์ ๋๋ฝ ๊ธฐ๋ฅ์ jest ๊ฐ์ฒด๋ฅผ ์ง์ํ๋ ๊ฒ์ ๋๋ค. import.meta์ ๋ถ์ฌ์ผ ํ๋์ง ์๋๋ฉด ์ฌ๋๋ค์ด '@jest/globals'์์ import {jest}๋ฅผ ํตํด ๊ฐ์ ธ์ค๋๋ก ํด์ผ ํ๋์ง ๊ฒฐ์ ํ์ง ์์์ต๋๋ค.
typescript ์ฌ์ฉ ์ฌ๋ก์ ๊ฒฝ์ฐ ๋ช ์์ ์ผ๋ก ๊ฐ์ ธ์ค๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋ค, ์ ๋ ์ด๊ฒ์ ์ง์ํ๋ @jest/globals
ํจํค์ง๋ฅผ ์ถ๊ฐํ์ต๋๋ค(๊ทธ๋ฆฌ๊ณ ์ผ์์ ์ผ๋ก ๋๋๋ ธ์ต๋๋ค). ๊ทธ๋์ ์๊ด์์ด ์ฌ์ฉํ ์ ์์ต๋๋ค. import.meta
์ ๋
ธ์ถ์ํค๋ ๊ฒ์ด _๋ํ_ ์๋ฏธ๊ฐ ์๋์ง ๊ถ๊ธํฉ๋๋ค. ํ์ฌ๋ ๋์ค์ ์ ๊ฑฐํ๋ ๊ฒ๋ณด๋ค ์ถ๊ฐํ๋ ๊ฒ์ด ๋ ์ฝ๊ธฐ ๋๋ฌธ์ ํ์ฌ ๊ทธ๋ ๊ฒ ํ์ง ์๋ ์ชฝ์ผ๋ก ๊ธฐ์ธ๊ณ ์์ต๋๋ค(๊ฐ์ธ์ ์ผ๋ก ์ ๋ ๊ธ๋ก๋ฒ ํฌ์ด ์๋๋๋ค).
๋ช ์์ ๊ฐ์ ธ์ค๊ธฐ์ ๊ฒฝ์ฐ +1, ์ข ๋ ์ฅํฉํ์ง๋ง ์ดํดํ๊ธฐ ์ฝ์ต๋๋ค.
๋๋ ์ด๊ฒ์ Node 13.2 & Jest 25.4์์ ์ป๊ณ ์์ต๋๋ค: ES Modules are only supported if your test environment has the
getVmContext function
๋ด๊ฐ ๋ฌด์์ ๋์น๊ณ ์์ต๋๊น?
@zandaqo ์ ์ฃ์กํฉ๋๋ค. ๊ทธ ์ ์ ์์ด๋ฒ๋ ธ์ต๋๋ค. ์์ ์ถ๊ฐํ์ง๋ง
jest-environment-node
๋๋jest-environment-jsdom-sixteen
ํ ์คํธ ์คํ
ReferenceError: jest is not defined
@jest/globals
๋๋ฝ์ผ๋ก ์ธํ ๊ฒ ๊ฐ์ต๋๋ค.
์, ์ธ๊ธํ ๋๋ก jest
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ์๋ง ์๋ํฉ๋๋ค.
๋ชจํ๋ ์๋ง ๊นจ์ก์ ๊ฒ์ด๊ณ , ํ
์คํธํ์ง ์์์ต๋๋ค ๐
๋๋ e2e ํ
์คํธ ๋๋ ํ ๋ฆฌ( e2e/native-esm/__tests__/native-esm.test.js
)์ ์ด๋ฒ ํธ์์ ๋ณผ ์ ์๋ ๋งค์ฐ ๊ธฐ๋ณธ์ ์ธ ํ๋ก์ ํธ๋ฅผ ์ปดํ์ผํ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ถํํ๋ ๋๋ ์ฌ์ ํ ๊ทธ๊ฒ์ ์๋ํ๊ฒ ํ ์ ์์ต๋๋ค ๐๋๊ฐ ์ฐ์ฐํ ๊ทธ๊ฒ์ ํ์ธํ ์ ์์ต๋๊น?
https://drive.google.com/file/d/1vyDZjsVKOTu6j55QA11GjO9E7kM5WX8_/view?usp=sharing
์ํ ์คํฌ๋ฆฝํธ ์คํ (๋ค๋ง ์์
double
๊ธฐ๋ฅ์ํ๊ณ ์ธ์๋ฅผ double(2)
) :
npm run main
> [email protected] main /Users/ilya/Projects/jest-esm
> node src/main.js
(node:16961) ExperimentalWarning: The ESM module loader is experimental.
4
์ด์ค ๊ธฐ๋ฅ์ ๋ํ ๋จ ํ๋์ ํ ์คํธ๋ก jest ์คํ:
npm run test
> [email protected] test /Users/ilya/Projects/jest-esm
> jest
FAIL __tests__/native-esm.test.js
โ Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
โข To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
โข If you need a custom transformation specify a "transform" option in your config.
โข If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/ilya/Projects/jest-esm/__tests__/native-esm.test.js:8
import {double} from '../src/index.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime._execModule (node_modules/jest-runtime/build/index.js:1074:58)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.542s
Ran all test suites.
๋น์ ์์ ๋
ธ๋๋ฅผ ์คํํด์ผํฉ๋๋ค --experimental-vm-modules
ํ๊ณ ํ๋๋ ํ์ผ ์ด๋ฆ .mjs
๋๋ "type": "module"
์ package.json
.
ํธ์ง: ์๋ง๋ Jest ์ธ๋ถ์์ ์๋ํ๋ ํ์๋ฅผ ๋ณผ ์ ์์ ๊ฒ์ ๋๋ค. ๋ ธ๋์ ๋ํ ์คํ ํ๋๊ทธ๊ฐ ๋๋ฝ๋ ๊ฒ๋ฟ์ ๋๋ค.
@SimenB ์ค ์์ฐ --experimental-vm-modules
AND --experimental-modules
์์ต๋๋ค. --experimental-modules
๊ฐ ์ผ๋ถ ๋
ธ๋ 13 ๋ฒ์ ๋ถํฐ ํ์ํ์ง ์๋ค๋ ์ฌ์ค์ ํผ๋์ค๋ฌ์ ์ต๋๋ค. ๊ฐ์ฌ ํด์!
TLDR: node --experimental-vm-modules node_modules/jest/bin/jest.js
๊ฐ ์ ์๊ฒ ํจ๊ณผ์ ์
๋๋ค.
์, OP์์
Jest๋
vm
API(https://nodejs.org/api/vm.html)๋ฅผ ์ฌ์ฉํ๋ฉฐ ์์ฑ ์์ (node โโv13.6) ์ด API์ ESM ๋ถ๋ถ์ ์ฌ์ ํ โโํ๋๊ทธ๊ฐ ์ง์ ๋์ด ์์ต๋๋ค(--experimental-vm-modules
). ๋ฐ๋ผ์ ESM์ด ํ๋๊ทธ๊ฐ ์ง์ ๋์ง ์์๋ค๊ณ ๋งํ๋ ๊ฒ์ ํ์ฌ๋ก์๋ ์ฝ๊ฐ ์๋ชป๋ ๋ช ์นญ์ ๋๋ค.
ํ์ง๋ง ๊ทธ๊ฒ์ด ๋น์ ์ ์ํด ์๋ํ๋ค๋ ๊ฒ์ ๊ต์ฅํฉ๋๋ค!
(์ด ๋๊ธ์ ํด๊ฒฐ๋ ๊ฒ์ผ๋ก ํ์ํ๊ฒ ์ต๋๋ค)
@SimenB ๊ฐ์ฌํฉ๋๋ค! ์ง๊ธ๊น์ง ๋ณด๊ณ ์๋ ๋ ๊ฐ์ง ๋ฌธ์ .
ReferenceError: module is not defined
๊ทธ๋์ ์ด๊ฒ์ด ์ ๋๋ก ๊ตฌํ๋์ง ์์์ ์๋ ์๋ค๊ณ ์๊ฐ
import ๋ฌธ์ ES ๋ชจ๋ ๋๋ CommonJS ๋ชจ๋์ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ์ฑ์ ์คํํ ๋ ์ ์๋ํฉ๋๋ค. CJS์ ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ๋ createRequire๋ฅผ ์ฌ์ฉํด์ผ๋ง ๊ฐ์ ธ์ฌ ์ ์์ง๋ง ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ๋ ๊ทธ๋ฅ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ผ๋ฉด ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
TypeError: _vm(...).SyntheticModule is not a constructor
at Runtime._importCoreModule (node_modules/jest-runtime/build/index.js:1198:12)
targets: { node: 12 }
๋ฐ 2๊ฐ์ ํ๋ฌ๊ทธ์ธ์ด ์๋ ์ต์ Babel: babel-plugin-transform-import-meta
๋ฐ rewire-exports
. ( import-meta
ํ๋ฌ๊ทธ์ธ ์ ๊ฑฐ๋ฅผ ์๋ํ์ง๋ง ๋ค์ ์ถ๊ฐํ๋ผ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.)testEnvironment: "node"
๋ ๊ฑฐ์ ์ ์ผํ ๊ตฌ์ฑ์
๋๋ค.node --experimental-vm-modules node_modules/jest/bin/jest.js
์ฌ์์ฐ ๋ฆฌํฌ์งํ ๋ฆฌ๊ฐ ๋์์ด ๋๋ค๋ฉด ์๋ ค์ฃผ์ญ์์ค.
@aldeed ๊ฐ์ฌํฉ๋๋ค!
๋ฌธ์ 1์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ ๋ง ๋ฒ๊ทธ์ฒ๋ผ ๋ณด์ ๋๋ค. ํธ์ง: #9850์ ํตํด ์์ ๋์ด์ผ ํฉ๋๋ค.
๋ฌธ์ 2์๋ ๋ ธ๋ 12.16.0์ด ํ์ํฉ๋๋ค. https://nodejs.org/docs/latest-v12.x/api/vm.html#vm_class_vm_syntheticmodule
Jest์์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ฒ ์ต๋๋ค(์ง๊ธ์ ๋ ๋ง์ ๋ฒ์ ์์ ์ฌ์ฉํ ์ ์๋ vm.SourceTextModule
๋ฅผ ํ์ธํ์ง๋ง SyntheticModule
๋ ํ์ํจ).
12.16.0์ผ๋ก ์คํํ๋ฉด ๋ด ๋ฌธ์ 2๊ฐ ํด๊ฒฐ๋จ์ ํ์ธํ์ต๋๋ค. ํด๋น ์์ ์ฌํญ์ด ๋ฆด๋ฆฌ์ค๋ ํ ๋ฌธ์ 1์ ๋ค์ ํ
์คํธํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ถ๊ฐ ํ
์คํธ๋ฅผ ์ํด jest
๊ฐ์ฒด๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์ค์ด๋ฉฐ ๊ฐ์ ธ์์ผ ํ๋ค๋ ๋ฐ ๋์ํฉ๋๋ค.
๋ฉ์ง ์ํ, @SimenB! ์๊ท๋ชจ ํ๋ก์ ํธ์์ ์ด๊ฒ์ ์๋ํ๊ณ ์์ง๋ง ๋์ ๊ฐ์ ธ์ค๊ธฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์ด๊ฒ์ ๋ด๊ฐ๋ณด๊ณ ์๋ ์ค๋ฅ์ ๋๋ค.
Module status must not be unlinked or linkingError [ERR_VM_MODULE_STATUS]: Module status must not be unlinked or linking
๋์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ ๊ฑฐํ๋ฉด ํ ์คํธ๊ฐ ์คํ๋ฉ๋๋ค(๋ฌผ๋ก ๋ค๋ฅธ ์ด์ ๋ก ์คํจํจ). ๋์ผํ ํ ์คํธ๊ฐ ํ์ฌ Mocha(๋งค์ฐ ์ต๊ทผ์ ESM ์ง์์ ์ ๊ณตํจ)์์ ์๋ํ๊ณ ์์ต๋๋ค.
๋์์ด๋๋ค๋ฉด ๋ฌธ์ ์ ๋์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ https://github.com/beejunk/firn.js/blob/switch-to-jest/lib/renderPage.js#L43 -L55์์ ๋ณผ ์ ์์ต๋๋ค.
ํ ์คํธ ํ์ผ์ https://github.com/beejunk/firn.js/blob/switch-to-jest/test/build.test.js์ ์์ต๋๋ค. ์์ ์ค์ธ Mocha ๋ฒ์ ์ ๋ง์คํฐ ๋ธ๋์น์์ ๋ณผ ์ ์์ต๋๋ค.
๋ด ์ ์ฉํ ๋ค๋ฅธ ์ ๋ณด๊ฐ ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค.
@beejunk ๊ฐ์ฌํฉ๋๋ค! ์์ ํ ๋งํฌ๋๊ธฐ ์ ์ ๋์ผํ ๋ชจ๋์ ๊ฐ์ ธ์ค๋ import
์ฌ์ด์ ๊ฒฝ์ ์กฐ๊ฑด์ด ์์ ์ ์๋์ง ๊ถ๊ธํฉ๋๋ค. ๊ทธ๊ฒ์ด ๋น์ ์ด ์ฌ๊ธฐ์์ ์น๋ ์ผ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ์ค๋ ์์ ํ๊ฒ ์ต๋๋ค. ์ ๋ณด ๊ฐ์ฌํฉ๋๋ค!
ํธ์ง: #9858์์ ์์ ๋์์ต๋๋ค. ๋ฆฌํฌ์งํ ๋ฆฌ์ ์์ ์ฌํญ์ ๋ณต์ฌํ์ต๋๋ค.
์๋ฌด๋ ์ด๊ฒ์ TypeScript์ ํจ๊ป ์๋ํ๋๋ก ๊ด๋ฆฌํ์ต๋๊น? node --experimental-vm-modules node_modules/jest/bin/jest.js
๋ package.json
"type": "module"
๊ฐ ์์ด๋ ๋์ผํ SyntaxError: Cannot use import statement outside a module
node --experimental-vm-modules node_modules/jest/bin/jest.js
๋ฐํํฉ๋๋ค.
babel.config.cjs
module.exports = {
presets: [
'@babel/preset-typescript',
],
};
jest.config.cjs
module.exports = {
testEnvironment: 'jest-environment-node',
transform: {},
};
@dandv ๋น์ ์ ๋ณธ์ง์ ์ผ๋ก ์ด ๊ฒฝ์ฐ๋ฅผ ์น๊ณ ์์ต๋๋ค: https://github.com/facebook/jest/pull/9772/files#r407255029
๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ด โโ์ ์์ต๋๊น? non-js ํ์ฅ์ผ๋ก ๋ฌด์์ ํ ๊ฒ์ธ์ง ์์๋ด์ผ ํฉ๋๋ค.
@SimenB : #9860. ๋ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
@aldeed @beejunk 25.5.0์ด ๊ทํ์ ๋ฌธ์ ์ ๋ํ ์์ ์ฌํญ๊ณผ ํจ๊ป ๋ฆด๋ฆฌ์ค๋์์ต๋๋ค. ๊ณ์ํด์ ๋ฒ๊ทธ ๋ฆฌํฌํธ๋ฅผ ๋ณด๋ด์ฃผ์ธ์ ๐
์, ๊ทธ๋ฆฌ๊ณ ๊ธฐ๋ค๋ฆฌ์๋ ๋ถ๋ค์ ์ํด import { jest } from '@jest/globals'
์ง์๋ ํฌํจ๋์ด ์์ต๋๋ค๐
์ด ๋ชจ๋ ์์ ์ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. @SimenB! ๋ค๋ฅธ ๋ฌธ์ ์ ๋ด์ฐฉํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ฐ๋ฐ ์๋ฒ์์ ๋ชจ๋ ์บ์๋ฅผ ๋ฒ์คํธํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ฐ์ ธ์ค๊ธฐ ๊ฒฝ๋ก์์ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ์คํ์ ํด์์ต๋๋ค. ์์ด๋์ด๋ ๊ตฌ์ฑ ์์์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์งํ ๋ค์ ๊ฐ์ ธ์ค๊ธฐ ๊ฒฝ๋ก๋ฅผ ์์์ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฐ์ดํธํ์ฌ ์๋ฒ๋ฅผ ๋ค์ ์์ํ ํ์ ์์ด ๋ค์ ํ์ด์ง ๋ก๋ ์ ์ ์ฝ๋๋ฅผ ์ฆ์ ๊ฐ์ ธ์ค๋ ํ์ผ ๊ฐ์์๋ฅผ ๊ฐ๋ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ dev ์๋ฒ๋ฅผ ์คํํ ๋ ์๋ํฉ๋๋ค. ๊ทธ๋ฌ๋ Jest์์ ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
Cannot find module '/path/to/project/components/BasePage.js?cache=0' from 'renderPage.js'
๋ค์์ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๊ฐ ์ฌ์ฉ๋๋ ์์น์ ์์ ๋๋ค. https://github.com/beejunk/firn.js/blob/switch-to-jest/lib/renderPage.js#L55 -L56
์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๊ฑฐํ๋ฉด ์ผ๊ด์ฑ์ ์์ง๋ง ํ
์คํธ๋ ํต๊ณผํฉ๋๋ค. ๋จ์ผ ์ ํ๊ตฐ(์: npm test -- test/build.test.js
)์ ์คํํ๋ฉด ํ
์คํธ๋ ํต๊ณผํ์ง๋ง ๋ชจ๋ ํ
์คํธ๋ฅผ ํ ๋ฒ์ ์คํํ๋ฉด ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ชจํธํ ์ค๋ฅ์ ํจ๊ป ์คํจํฉ๋๋ค. ์ผ๊ด์ฑ ์๋ ํ
์คํธ ๋ฌธ์ ๋ฅผ ๊ณ์ ํ๊ณ ๋ค๊ณ ์์ง๋ง ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์ ๋ฌธ์ ๋ฅผ ๋จผ์ ๋ณด๊ณ ํด์ผ ํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
@beejunk ์ ๊ณ ๊ฐ์ฌํฉ๋๋ค. #6282๋ ์ด ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ์ง๋ง ์ฌ๊ธฐ์์ ํ์ํ์ง ์์ ๋ณํ๊ธฐ ๋ฐ ํญ๋ชฉ์ ์ฟผ๋ฆฌ๋ฅผ ์ ๋ฌํ๋ ค๊ณ ํฉ๋๋ค. ๋ฐ๋ผ์ ์ง๊ธ์ ๋ฐํ์์์ ๋ด๋ถ์ ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์ง์ํ๊ณ #6282๊ฐ ํด๋น ์ฟผ๋ฆฌ๋ฅผ ์ ๋ฌํ๋๋ก ํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ผ ์ ์์ต๋๋ค.
๋ด๊ฐ ์ฟผ๋ฆฌ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค ๋ชจ๋ ์บ์๋ฅผ ๋ง๋๋ ์ฝ๋์ ๋นํธ๋ฅผ ์ถ๊ฐํ์ต๋๋ค : https://github.com/facebook/jest/blob/d425a49bd575e7167bc786f3c4f2833589091fa1/packages/jest-runtime/src/index.ts#L330 -L334
๊ทธ๋ฌ๋ ์ด๋ค ์ฝ๋๋ ์ฟผ๋ฆฌ๋ก ํธ์ถํ์ง ์์ต๋๋ค. ๋๋ ์ฐ๋ฆฌ๊ฐ resolvePath.split('?')
๋ฅผ ํ ์ ์์ด์ผ ํ๊ณ ๋ชจ๋ ๊ฒ์ด ์๋ํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ผ์นํ์ง ์๋ ์ค๋ฅ์ ๊ด๋ จํ์ฌ ํด๋น ์ ์ฅ์๊ฐ ์ฌํํ๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๋ณ๋ ฌ ํ ์คํธ๋ก ESM ์ฝ๋๋ฅผ ํ ์คํธํ์ง ์์๊ณ ๋จ์ผ ํ ์คํธ๋ง ํ์ต๋๋ค. ์ ๊ทธ๊ฒ์ด ์ผ์ ์ํฅ์ ๋ฏธ์น ์ง ๋ชจ๋ฅด๊ฒ ์ง๋ง ๋๊ฐ ์๊ฒ ์ด์ ๐
@beejunk ์ฟผ๋ฆฌ ๋ฌธ์ ๊ฐ 25.5.1์์ ์์ ๋์์ต๋๋ค. ์์ง ๋ค๋ฅธ ๋ฌธ์ ๋ฅผ ์กฐ์ฌํ ์๊ฐ์ด ์์์ต๋๋ค.
์ด๊ฒ๊ณผ ๊ด๋ จ์ด ์๋ค๊ณ ์๊ฐ๋๋ ๋ฌธ์ ๊ฐ ์์ง๋ง 25.X
์์ ์์ ๋์ง ์์์ต๋๋ค.
์๋ ์๋๋ฆฌ์ค๋ฅผ ์์ฝํ๋ ค๊ณ ํฉ๋๋ค.
{ default: generator } = require(path.resolve(f))
f
๋ด๋ถ์ ๋ชจ๋ ๊ฒ์ด ๋ณํ๋์ง ์์ "์๊ธฐ์น ์์ ์๋ณ์ ๊ฐ์ ธ์ค๊ธฐ ์ค๋ฅ"๊ฐ ๋ฐ์ํฉ๋๋ค.์ด๊ฒ์ import()๋ก ์๋ํ๋ ๊ฒฝ์ฐ์๋ ๋ฐ์ํฉ๋๋ค.
๋น์ ์ด ๋ฒ์ญ์ ์ธ๊ธํ๊ธฐ ๋๋ฌธ์; import
๋ฅผ require
๋ณํํ๋ ์ค์ ์ด ์๋ ๊ฒฝ์ฐ ์ด ๋ฌธ์ ๋ ์ฌ๋ฐ๋ฅธ ์์น๊ฐ ์๋๋๋ค. ์ด ๋ฌธ์ ๋ ๊ธฐ๋ณธ ์ง์์ ๊ดํ ๊ฒ์
๋๋ค.
์ฆ, require
ESM์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ Node์ API๊ฐ ์๊ธฐ ๋๋ฌธ์ CJS์์ import()
๋ํ ์ง์์ ์ถ๊ฐํ ์ ์์์ต๋๋ค. ์ด์ ๋ํ ์ง์์ Node ๋ง์คํฐ์ ์๋ฅํ์ง๋ง ์์ง ์ถ์๋์ง ์์์ต๋๋ค: https://github.com/nodejs/node/pull/32985. ์ฐ๊ฒฐ๋ ๋ฆด๋ฆฌ์ค PR์์ ๋ณผ ์ ์๋ฏ์ด 13.14.0 ๋ฐ 14.1.0์ผ๋ก ์ ๊ณต๋ฉ๋๋ค. ๊ทธ ์์ ์์ ์ง์์ ๊ตฌํํ๊ฒ ์ต๋๋ค ๐
ํ์ง๋ง .mjs
์ค์ ํ์ผ์ ์ฌ์ฉํ ์ ์์ด์ผ ํฉ๋๋ค.
@SimenB ์ด๊ฒ์ ํ๋ฅญํฉ๋๋ค. ์ด์ ์ฌ๋ฌ ํ ์คํธ ํ์ผ์์ ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค! ๊ฐ ํ์ผ์์ Babel๊ณผ Node ๊ฐ์ ธ์ค๊ธฐ ๊ฐ์ ์ฐจ์ด์ ์ ํด๊ฒฐํ๊ณ jest ๊ฐ์ ธ์ค๊ธฐ ๋ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ฝ๊ฐ์ ํ๋ก์ธ์ค์ด๋ฏ๋ก ์๋ฐฑ ๊ฐ์ ํ ์คํธ ํ์ผ์์ ์ํํ ๋ ๋ ๋ง์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๋ ๋ง์ ์ง๋ฌธ์ด ์๋ ๋ช ๊ฐ์ง ์ฌํญ:
import()
์ง์์ ๋ํ ์ด์ ์๊ฒฌ์์ ๋งํ๋ฏ์ด Jest ๊ตฌ์ฑ ํ์ผ์ ์ด๋ฆ๋ jest.config.js
๋ก ์ง์ ํ ์ ์์ต๋๊น? ํ์ฌ ์ด๋ฆ์ด jest.config.cjs
์ด๊ณ module.exports =
์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ง ์๋ํฉ๋๋ค(์ค๋ฅ๋ TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]: A dynamic import callback was not specified
์).package-lock
๋์ด๋ ํจํค์ง๊ฐ ์๋๊ธฐ ๋๋ฌธ์ eslint ๊ท์น node/no-extraneous-import
์คํจํฉ๋๋ค. ์ด ๋ช
๋ช
๊ท์น์ ๋ํ ์ด์ ๊ฐ ์์ต๋๊น? ๊ทธ๊ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค jest
ํฌํจํ์ง ์๋ @
? ๊ท์น์ ๋ฌด์ํ๊ธฐ ์ฝ์ง๋ง ๊ถ๊ธํฉ๋๋ค.jest
global์ด test
, describe
, before
๋ฑ๊ณผ ๊ฐ์ magic fns์ ๋ค๋ฅธ ์ด์ ๋ ๋ฌด์์
๋๊น? ๊ทธ๊ฒ๋ ๋ชจ๋ ์ง๊ธ ์์
ํด์ผ ํฉ๋๊น?--experimental-vm-modules
ํ๋๊ทธ๋ฅผ ์ค์ ํ ์ ์์ต๋๊น? jest
๋ช
๋ น๊ณผ ํจ๊ป ์๋ํ์ง ์์ผ๋ฉด ์ผ์ข
์ ๋นํ์ค์ผ๋ก ๋ณด์
๋๋ค. ํ๋๊ทธ๋ฅผ ์ง์ ์ ๋ฌํ ์ ์๋ค๋ฉด NODE_OPTIONS
env ๋ณ์๋ฅผ ์ค์ /์์ ํ ์ ์์ต๋๊น?Jest ๊ตฌ์ฑ ํ์ผ์ ์ด๋ฆ์ jest.config.js๋ก ์ง์ ํ ์๋ ์์ต๋๊น?
๊ฐ์ฅ ๊ฐ๊น์ด package.json
์ type: 'module'
๊ฐ ์์ผ๋ฉด .js
๋ก ์ด๋ฆ์ ์ง์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๊ตฌ์ฑ ํ์ผ์์ ESM์ ์ฌ์ฉํ๋ ค๋ฉด .mjs
๋ก ์ด๋ฆ์ ์ง์ ํด์ผ ํฉ๋๋ค. https://nodejs.org/api/esm.html#esm_enabling์ ์ฐธ์กฐ await
ํ๋ ๊ฒ์ ์ฌ์ํ ์ผ์
๋๋ค. PR ํ์ํฉ๋๋ค ๐ #8357์ด ์ค๋จ๋์์ต๋๋ค.
A dynamic import callback was not specified
๋ฐ์๋ค๋ ์ฌ์ค์ ๋งค์ฐ ๋๋์ต๋๋ค. ์ฐ๋ฆฌ๋ VM์์ ๊ตฌ์ฑ ํ์ผ์ ๋ก๋ํ์ง ์์ต๋๋ค... ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ด์ด ์ฃผ์๊ฒ ์ต๋๊น?
"@jest/globals"๋ผ๋ ์ด๋ฆ์
package-lock
๋์ด๋ ํจํค์ง๊ฐ ์๋๊ธฐ ๋๋ฌธ์ eslint ๊ท์นnode/no-extraneous-import
์คํจํฉ๋๋ค. ์ด ๋ช ๋ช ๊ท์น์ ๋ํ ์ด์ ๊ฐ ์์ต๋๊น?jest
์์ด@
์์ต๋๊น? ๊ท์น์ ๋ฌด์ํ๊ธฐ ์ฝ์ง๋ง ๊ถ๊ธํฉ๋๋ค.
devDependency
์ @jest/globals
devDependency
๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ํจํค์ง ์์ฒด๋ ์ ์ ์ผ๋ก ์ ํ ์ ์์
๋๋ค. jest
์๋ ๋ณ๋์ ํจํค์ง์ด๋ฏ๋ก ์ ํ ์ ์๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ฏ๋ก Jest ๋ฐํ์ ์ธ๋ถ์์ ๋ก๋๋๋ ๊ฒฝ์ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
ํ์ฌ ๋ณ๊ฒฝํ ๊ณํ์ ์์ง๋ง ํด๋น ํจํค์ง๋ฅผ ๋ ์ด์ ์ฌ์ฉํ์ง ์๊ณ jest
์์ ์ ํ์ ๋ด๋ณด๋ผ ์ ์์ต๋๋ค. ๊ทธ๋๋ ์ค์ํ ๋ธ๋ ์ดํน ์ฒด์ธ์ง์ด๋ฏ๋ก ๋์ค์ ๋ด
์๋ค ๐
๊ด๋ จ ์ง๋ฌธ,
jest
global์ดtest
,describe
,before
๋ฑ๊ณผ ๊ฐ์ magic fns์ ๋ค๋ฅธ ์ด์ ๋ ๋ฌด์์ ๋๊น? ๊ทธ๊ฒ๋ ๋ชจ๋ ์ง๊ธ ์์ ํด์ผ ํฉ๋๊น?
jest
๋ ํ์ผ๋น ๊ณ ์ ํ๋ค๋ ์ ์์ CJS์ require
๋๋ module
๊ฐ์ฒด์ ๊ฐ์ผ๋ฉฐ ์ค์ ๋ก๋ ์ ์ญ์ด ์๋๋๋ค(์: globalThis.jest === undefined
). ๊ทธ๋ฌ๋ฉด jest.mock('../../file.js')
๋ฑ์ด ์ฝ์
๋ ํ์ผ๊ณผ ๊ด๋ จํ์ฌ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ ์ ์์ต๋๋ค. ์ค์ ์ ์ญ์ ๊ฐ์ ธ์ค๋๋ก ์ ํํ ์๋ ์์ง๋ง ์ฌ์ ํ globalThis.expect
๋ฑ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด๊ฒ์ด ์๋ฃ๋๋ฉด Jest๊ฐ
--experimental-vm-modules
ํ๋๊ทธ๋ฅผ ์ค์ ํ ์ ์์ต๋๊น?
์กฐ์ฉํ ์ค์ ํ๊ธฐ ๋ณด๋ค๋ ๋
ธ๋๊ฐ ํ๋๊ทธ๋ฅผ ํด์ ํ ๋๊น์ง ๊ธฐ๋ค๋ฆด ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ํ๋๊ทธ๊ฐ ์ง์ ๋ ์ด์ ๋ API๊ฐ ์ด๋ ์์ ์์ ๋ณ๊ฒฝ๋ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. NODE_OPTIONS
๋ฅผ ์ค์ ํ๋ ์ต์
์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ํ์ฌ ๋ฐํ์์ ๋ณ๊ฒฝํ๋์ง ํ์คํ์ง ์์ต๋๊น? ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ํ์ฌ ๊ณํ์ ์์ต๋๋ค.
์ด์ ์ด์ ๋ ธ๋์์ ์ด๊ฒ์ ์๋ํ ๋ ์ด์ ๊ณผ ์ฝ๊ฐ ๋ค๋ฅธ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๊ฒ ๊ฐ์ง๋ง ์ต์ ๋ ธ๋ ๋ฒ์ ์ด ๋ฌธ์ ๋ผ๋ ์ค๋ฅ๋ ๋ช ํํ์ง ์์์ต๋๋ค. ๋ ์ ์ฉํ ์ค๋ฅ ๋ฉ์์ง์ ํจ๊ป ์ต์ ๋ฒ์ ํ์ธ์ ์ฝ๊ฒ ์ถ๊ฐํ ์ ์์ต๋๊น?
์, ๊ตฌํ์ด ์กฐ๊ธ ์์ ํ๋๋ฉด ์ผ๋ถ ๋ฌธ์์ ํจ๊ป ๋ ๋์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค. ๊ตฌํ์ด ์คํ ํ๋๊ทธ์ ์ํด ๋ณดํธ๋๋ ๊ฒ์ ๋ณด์์ ๋ ์๋ฌด๋ ๊ทธ๊ฒ์ ์ฐ์ฐํ ๋ฐ๊ฒฌํ์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
@SimenB , Jest๋ฅผ 25.5.2๋ก ์ ๋ฐ์ดํธํ์ผ๋ฉฐ ์ด์ ๋ชจ๋ ํ ์คํธ๊ฐ ํต๊ณผํ๊ณ ์์ต๋๋ค. ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๊ฐ ์๋ ์ค์ด๋ฉฐ ์ด์ ์ ๋ณด์๋ ๊ฐํ์ ์ธ ์ค๋ฅ๊ฐ ๋ ์ด์ ๋ฐ์ํ์ง ์์ต๋๋ค. ๋ชจ๋ ์์ ์ ๋ค์ ํ ๋ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
์ข์์, ํ ์คํธ์ ๋ง์ง๋ง ์คํ์์ ์ค๋ฅ๋ฅผ ๋ค์ ๋ณด์์ผ๋ฏ๋ก ์ฌ์ ํ ๋ฐ์ํฉ๋๋ค. ์ง์์ ์ผ๋ก ์ฌ์์ฐํ๊ณ ๋ค์ ๋ณด๊ณ ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ฐพ์ ์ ์๋์ง ํ์ธํ๊ฒ ์ต๋๋ค.
๋ฌธ์ ๋ฅผ ์ฌํํ ์ผ๊ด๋ ๋ฐฉ๋ฒ์ ์ฐพ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ค์์ ๋ด๊ฐ ์์ ํ๊ณ ์๋ ์ง์ ์ ๋๋ค. https://github.com/beejunk/firn.js/tree/switch-to-jest
์ฌํํ๋ ค๋ฉด:
/tmp/jest_rs
์๋์ผ๋ก ์ญ์ ํ์ต๋๋ค.npm test
์ธ ๋ฒ ์คํํฉ๋๋ค. ์ฒ์ ๋ ์คํ์ ์ฑ๊ณตํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ธ ๋ฒ์งธ ์คํ์ ์คํจํด์ผ ํฉ๋๋ค.๋ค์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๋ ํ์๋๋ ์คํ ์ถ์ ์ ๋๋ค.
Error:
at invariant (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:1866:11)
at Runtime.loadEsmModule (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:480:7)
at Runtime.linkModules (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:548:19)
at importModuleDynamicallyWrapper (internal/vm/module.js:397:21)
at htmPreactPath (internal/process/esm_loader.js:31:14)
at renderPage (/home/brian/Projects/firn.js/lib/renderPage.js:53:15)
at map (/home/brian/Projects/firn.js/lib/build.js:43:12)
at Array.map (<anonymous>)
at build (/home/brian/Projects/firn.js/lib/build.js:36:43)
at Object.<anonymous> (/home/brian/Projects/firn.js/test/build.test.js:57:5)
์ค๋ฅ๋ ๋์ ๊ฐ์ ธ์ค๊ธฐ์์ ๋ฐ์ํ ๊ฒ ๊ฐ์ต๋๋ค. ์ค๋ฅ ๋ฉ์์ง๊ฐ ์์ผ๋ฏ๋ก ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ์์ ํ ํ์ ํ ์ ์์ต๋๋ค.
์ถ๊ฐ ์ฐธ๊ณ ์ฌํญ: Jest ์บ์๋ฅผ ์ง์ฐ๊ณ --no-cache
๋ฅผ ์ถ๊ฐํ์ฌ ํ
์คํธ ์คํฌ๋ฆฝํธ๋ฅผ ์
๋ฐ์ดํธํ๋ฉด ๋ฌธ์ ๋ฅผ ์ฌํํ ์ ์์ต๋๋ค.
ํ, ๋๋ ๊ฑฐ๊ธฐ์์ ๊ฒ์ผ๋ฅด๋ฉฐ ์ ์ ํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ์ง ์์์ต๋๋ค. ๋ฌธ์ ๋ ํ
์คํธ ํ๊ฒฝ์ด ๋ฌด๋์ ธ์ ์ด๋๊ฐ์ await
๊ฐ ๋๋ฝ๋ ๊ฒ ๊ฐ์ต๋๋ค. ํ์ง๋ง ์ฝ๋๋ฅผ ํตํด ๋ณด๋ ๊ฒ์ด ์๋ฌด๊ฒ๋ ์์์ผ๋ฏ๋ก ์ข ๋ ํํค์ณ์ผ ํ ๊ฒ์
๋๋ค.
@SimenB ๋ค์์ ํด๋น ESM ๊ตฌ์ฑ ๋ฌธ์ ์ ์ฌํ์ ๋๋ค. https://github.com/facebook/jest/issues/9935
@SimenB ๋์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ฌ์ฉํ ๋ ์์์ ์ธ๊ธํ Jest ์ค๋ฅ๋ฅผ ์ฌํํ๊ธฐ ์ํ ์ต์ํ์ ์์ ๋ฅผ ๋ง๋ค์์ต๋๋ค.
@beejunk์ ํ๋ฅญํ ์ฌ์์ฐ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค! Jest์ ๋ฒ๊ทธ์ธ์ง Node.js์ ๋ฒ๊ทธ์ธ์ง ์ ๋๋ก ์ดํดํ์ง ๋ชปํ ์ฑ ์ฌ๊ธฐ์์ ์ธ์ ํ๊ณ ์ถ์ ์๊ฐ์ ๋ ๋ง์ด ๋ณด๋์ต๋๋ค. ๋ ธ๋ ์ฝ์ด ๋ชจ๋๋ง ์ฌ์ฉํ์ฌ ๋์์ ์ฌํํ๊ณ ์ด๋ฅผ ์ ์คํธ๋ฆผ์ ๋ณด๊ณ ํ์ต๋๋ค. ๊ทธ๋์ ๊ทธ๋ค์ด ๋งํ๋ ๊ฒ์ ๋ด ์๋ค: https://github.com/nodejs/node/issues/33216
@SimenB๋, ์ฐพ์์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ๋ด ์ฌ์ฉ ์ฌ๋ก์ ์ ํฉํ --no-cache
ํ๋๊ทธ๋ฅผ ์ถ๊ฐํ๋ฉด ํ
์คํธ๊ฐ ์ผ๊ด๋๊ฒ ํต๊ณผํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ชจ๋ ์์
์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
๋ค, ์ ๋ ์์๋ดค์ต๋๋ค. ์ผ์ข ์ ํ์ด๋ฐ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์บ์๊ฐ ์์ผ๋ฉด ์๋ํ๊ธฐ์ ์ถฉ๋ถํ ๋๋ฆฝ๋๋ค.
@SimenB #9935๋ฅผ ํด๊ฒฐํด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ๋๋ ๊ฑฐ๊ธฐ์์ ๋ ๋ฒ์งธ ์ฐ๋ ค๋ฅผ ์ธ๊ธํ๋๋ฐ, ์ฌ์ ํ ์ ํจํ๋ค๊ณ ์๊ฐํฉ๋๋ค. type: "module"
๊ฒฝ์ฐ jest --init
๋ ์ฌ์ ํ module.exports
๋ ๊ตฌ์ฑ ํ์ผ์ ์์ฑํฉ๋๋ค. ์ด๊ฒ์ ์ํ ์ค์ธ ์์
์ ์๊ณ ์๋ ๊ฒฝ์ฐ ์๋์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์๋์ ์ผ๋ก ๋ฏธ๋ฏธํ์ง๋ง Node์์ ESM์ ํ๋๊ทธ๊ฐ ์ง์ ๋์ง ์๊ณ ๋ง์ ์ฌ๋๋ค์ด ESM ํ๋ก์ ํธ๋ฅผ ์์ํ๋ฉด ํผ๋์ค๋ฌ์ด ๋ฒ๊ทธ์ฒ๋ผ ๋ณด์ด๊ธฐ ์์ํ ๊ฒ์
๋๋ค(์: ํ๋ณตํ ๊ฒฝ๋ก ์ ESM ํ๋ก์ ํธ์์ jest --init && jest
์ค๋ฅ๊ฐ ๋ฐ์ํจ). init ๋
ผ๋ฆฌ ๊ฐ์ ์ ๋ํด ๊ตฌ์ฒด์ ์ผ๋ก ๋ค๋ฅธ ๋ฌธ์ ๋ฅผ ์ ์ถํด์ผ ํฉ๋๊น?
@aldeed ํ์คํฉ๋๊น? ์ง๊ธ ํ
์คํธํ๋ ๊ฒ์ ๋์๊ฒ์ฃผ๋ mjs
์ ํ์ผ์ export default
์ด์๋ค. mjs
๊ฐ ์๋๋ผ js
์์ฑํ ์ ์์ง๋ง ์ฌ์ ํ ๊ทธ๋ ์ต๋๋ค. ESM ๊ตฌ๋ฌธ์ ์ฌ์ฉํฉ๋๋ค.
@SimenB ๊ธ์, ๋๋ ๋น์ ์ด ๋ฌผ์ ๋๊น์ง ํ์ ํ์ต๋๋ค. ๐ ํด๋ดค๋๋ฐ ๋ง๋ค์. ์ฒ์์๋ ์ด์ ๋ฒ์ ์ Node ๋๋ Jest๋ก ์ด ์์ ์ ์ํํ์ ์ ์์ต๋๊น? ๋ฌด์.
์ด๊ฒ์ ๊ต์ฅํ๋ค! ๋ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ํ๋์์ ํ ์คํธ๋ฅผ ์ฌ์์ ํ์ฌ ES ๋ชจ๋์ ์ฌ์ฉํ๊ณ Babel์ ์ฌ์ฉํ์ง ์์์ต๋๋ค. @SimenB ๊ฐ์ฌํฉ๋๋ค!
ํ์ผ์ด ESM ๋๋ CJS ๋ชจ๋์ธ์ง ๊ฐ์ง
์ด๊ฒ์ ๋ํด ๋งํ์๋ฉด, ES ๋ชจ๋ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ๋ํ๋ด๊ธฐ ์ํด "module":"<path to es module>"
๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ ๋ธ๋ผ์ฐ์ /๋ฒ๋ค๋ฌ ์งํฅ ํจํค์ง๊ฐ ๋ง์ด ์์ต๋๋ค. ํจํค์ง ์์ฒด ์ค์ ์ ๊ด๊ณ์์ด ์ง์ ๋ ํจํค์ง๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ง์ ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ด ํ๋ช
ํ ์ ์์ต๋๋ค. moduleNameMapper
๋น์ทํ์ง๋ง CJS์ธ์ง ESM์ธ์ง ์ง์ ํฉ๋๋ค.
์๋
ํ์ธ์ @SimenB๋ , ์ด ๋ฌธ์ ๊ฐ ์ข
๋ฃ๋๋ฉด ts-jest
๋ commonjs
๊ฐ์ ํด์ ํ ์ ์์ต๋๋ค. ๋ง์ต๋๊น? esm์ ์ฌ์ฉํ๋ ค๋ฉด ๋ณํ๊ธฐ ์ธก์์ ๋ณ๊ฒฝํ๋ ค๋ฉด ํ์ผ ํ์ฅ์๊ฐ ํ์ํฉ๋๊น?
์ด์ ์๋ฅผ ๋ค์ด ts-jest
์ปดํ์ผ ts
์ js
์ ๋ํด commonjs
,ํ์ง esm
ํ์ ํ์ผ ํ์ฅ์ mjs
์์ ์ปดํ์ผ ํ ๋ ts
์์ js
?
@zandaqo ์ฐ๋ฆฌ๋ modules
ํ๋๋ฅผ ์ง์ํ์ง ์์ผ๋ฉฐ ๋
ธ๋์ ์ฌ์์ ๋ฐ๋ฅด๊ณ exports
: #9771์ ์ฌ์ฉํฉ๋๋ค. ์ํ๋ ๊ฒฝ์ฐ modules
๋ฅผ ์ง์ํ๋๋ก ์์ฒด ํด์๊ธฐ๋ฅผ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค. https://jestjs.io/docs/en/configuration#resolver -string. ๋ค๋ฅธ ์ต์
( mainFields
, webpack ์ฒ๋ผ์?)์ ์ถ๊ฐํ ์๋ ์์ง๋ง ๊ตฌํ์ด ์์ ํ๋๊ณ ์๋ ค์ง์ง ์์ ๋ฏธ์ง์๊ฐ ์ค์ด๋ค๋ฉด ๋ ๋์์ง ๊ฒ์
๋๋ค.
@ahnpnl #9860
์ฑ ์ค ์ฌ๋ฌ๋ถ!
ํ ๊ฐ์ง ์ง๋ฌธ์
๋๋ค. ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ์ ๋ฐ๋ฅด๋ฉด ES6 ๋ชจ๋์ ์ ์ ์ด๋ฏ๋ก ์กฐ๋กฑํ ์ ์์ต๋๋ค. ๊ทธ๋์ ์ค์ ๋ก ES6์์ ๋ชจ๋ B๊ฐ ๊ฐ์ ธ์จ ๋ชจ๋ A๋ฅผ ์กฐ๋กฑํ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
@gabrieledarrigo ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด moduleNameMapper
๋ฅผ ์ฌ์ฉํฉ๋๋ค.
"moduleNameMapper": {
"moduleA": "<rootDir>/test/moduleA-mock.js"
},
@gabrieledarrigo ๋น์ ์ ํ ์ ์์ต๋๋ค
jest.mock('the-thing-i-want-to-mock', () => /* do whatever in here */);
let importedThing;
beforeAll(async () => {
importedThing = await import('thing-that-imports-mocked-module');
});
๋ฐ๋ผ์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋น์ ์ ์ผ๋ก ๋ง๋ค๋ฉด ์กฐ๋กฑ์ด ์๋ํฉ๋๋ค.
์์ง ESM ์ฝ๋ ๊ฒฝ๋ก์ ๋ชจ์ ํด์๋๋ฅผ ์ฐ๊ฒฐํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ง๊ธ ์๋ํ๋์ง ํ์คํ์ง ์์ต๋๋ค. ๋จธ์ง ์์ ๊ทธ๋ ๊ฒ ํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ด _์๋ง๋_ ๊ธฐ๋ณธ ESM์ ๋ํ ๋ชจ๋ ๋ชจ์ ๋ฌธ์๋ฅผ ๋ฌธ์ํํ๋ ๋ฐฉ๋ฒ์ด ๋ ๊ฒ์ ๋๋ค.
๋ธ๋ก๊ทธ ํฌํธ์์ ์ธ๊ธํ๋ฏ์ด ์ฐ๋ฆฌ๋ ์ด ํจํด์ ์ธ์ ๊ฐ๋ ๋ฌธ์ํํ ๊ฒ์ ๋๋ค.
์ฐ๋ฆฌ๊ฐ ๊ฐ์ง ํ ๊ฐ์ง ์์ด๋์ด๋ ์ต์์ ์์ค ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฐ ๋ค์ babel ํ๋ฌ๊ทธ์ธ์ผ๋ก ์ด๋ฅผ ์ํํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
@SimenB ๋จผ์ ๋ฉ์ง ์์ ๊ฐ์ฌํฉ๋๋ค :)
jest-environment-node
์์ ํ์ฅ๋ customEnvironment ๋ฅผ ์์ฑํ๋ ค๊ณ ํ ๋ ์ค์ ๋ก ๋ฌธ์ ์ ์ง๋ฉดํฉ๋๋ค. esm์ผ๋ก ์์ฑ๋ ์๋ฒ ๊ตฌํ์ ๊ฐ์ ธ์์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ํ๊ฒฝ์ cjs
๋ก ์ ์๋์ด์ผ ํฉ๋๋ค.
๋ด ์ง๋ฌธ์ ๋ด ์๋ฒ ๋ชจ๋์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ์ฌ์ฉ์ ์ง์ testEnvironment๋ฅผ esm์ผ๋ก ์ ์ํ๋ ์ต์
์ด ์์ต๋๊น? ์ด๋ค ์กฐ์ธ์ ํด์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค.
@kuka-radovan ์ด์ ๋ํ ๋ณ๋์ ๊ธฐ๋ฅ ์์ฒญ์ ์ด ์ ์์ต๋๊น?
์ ๋ฐ์ดํธ: ์ด ๋ฌธ์ ๋ ์ด์ https://github.com/facebook/jest/issues/10025 ์์ ์ถ์ ๋ฉ๋๋ค.
@SimenB ์ ์ jest.mock
์กฐ์ธ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ์ค๋์ ํ์ํ ํ์ผ ๋ช ๊ฐ๋ฅผ ๋ณํํ๊ณ ์์ต๋๋ค. ์กฐ๋กฑ๋ ๋ชจ๋์ด node_modules
ํจํค์ง์ผ ๋ ์์ ๊ฐ ์๋ํ๋์ง ํ์ธํ ์ ์์ง๋ง ๋์ผํ ํ๋ก์ ํธ์์ ๋ชจ๋์ ์กฐ๋กฑํ๋ ๋ฐ์๋ ์๋ํ์ง ์์ต๋๋ค.
๋ค์์ ๊ฐ๋จํ ์์ ๋๋ค.
// main.js
import secondary from "./secondary.js";
export default function main() {
return secondary();
}
// secondary.js
export default function secondary() {
return true;
}
// test.js
import { jest } from "@jest/globals";
jest.mock("./secondary.js");
let main;
let secondary;
beforeAll(async () => {
({ default: main } = await import("./main.js"));
({ default: secondary } = await import("./secondary.js"));
});
test("works", () => {
secondary.mockReturnValueOnce(false); // TypeError: Cannot read property 'mockReturnValueOnce' of undefined
expect(main()).toBe(false);
});
"./secondary.js"
๊ฐ ํจํค์ง ์ด๋ฆ์ธ ๊ฒฝ์ฐ ๋์ผํ ํจํด์ด ๋์ ์๋ํฉ๋๋ค. (์ค์ํ ๊ฒฝ์ฐ ๋ด๊ฐ ์๋ํ ํจํค์ง๊ฐ CommonJS๋ฅผ ๋ด๋ณด๋ธ๋ค๊ณ ์๊ฐํฉ๋๋ค.)
๋ ธ๋ 12.16.3์ด ํฌํจ๋ Jest 26.0.1
์์ด๋์ด๊ฐ ์์ต๋๊น? ์๋๋ฉด ์ ์ฒด ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ ์ถํด์ผ ํฉ๋๊น?
ํธ์ง: transform: {}
๊ตฌ์ฑ์ ์์ผ๋ฏ๋ก Babel์ด ์ ํ ์์ต๋๋ค.
ํธ์ง 2: ์ด๊ฒ๋ ์๋ํ์ง ์์ต๋๋ค.
jest.mock("./secondary.js", () => ({
default: jest.fn()
}));
์ด๊ฒ์ ๋ํ ๋๋ผ์ด ์์ .
ํ์ง๋ง ์ ๊ฐ ์๋ชปํ๊ณ ์๋ ๊ฒ์ด ์๋๋ผ๋ฉด CJS ํ
์คํธ ํ์ผ์์ import()
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์์ง ๋ถ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ต๋๋ค.
node --experimental-vm-modules node_modules/jest/bin/jest.js
Jest๋ฅผ ์คํ ์ค์ด๊ณ testEnvironment: 'node', transform: {}
์ jest.config.js
์์ต๋๋ค. ์ด๊ฒ์ ๋
ธ๋ 14.2.0์ ์์ต๋๋ค.
๊ฐ์ ธ์ค๊ธฐ ํํ์์์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]:
A dynamic import callback was not specified.
ํ์ฌ ์๋ ค์ง ์ ํ ์ฌํญ์ ๋๊น? https://github.com/nodejs/node/pull/32985 ๊ฐ ์ด์ Node 14.1.0์ ๋์ฐฉํ์ต๋๋ค.
์, ์์ง ๊ตฌํํ์ง ๋ชปํ์ต๋๋ค. ์๋ง ์ด๋ฒ ์ฃผ๋ง์ ์ฐฉ๋ฅํ ๊ฒ ๊ฐ์์.
@aldeed ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ด โโ์ ์์ต๋๊น? ๋ชจ์ ํญ๋ชฉ์ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ผ๋ถ์ธ์ง ํ์ธํ๊ณ ๊ทํ์ ์์ ๊ฐ ์ข์ ํ ์คํธ ์ฌ๋ก์ฒ๋ผ ๋ณด์ด๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ๐
@SimenB ๋น ๋ฅธ ๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค. ์ธ์ ์ฐฉ๋ฅํ ์ง ์ง์ผ๋ด์ผ๊ฒ ์ต๋๋ค.
์คํฌ๋ฆฝํธ์์ import
๊ฐ ํ๊ท๋ก ์ธํด ๋๋๋ฆด ์ ์๋ค๊ณ ๋ณด๊ณ (https://github.com/nodejs/node/issues/33166), ํด๊ฒฐ๋ ๋๊น์ง ๋ณด๋ฅํฉ์๋ค.
.mjs
ํ
์คํธ ํ์ผ์์ ์ด๊ฒ์ ์ฌ์ฉํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. __tests__/my-test.mjs
๊ฐ ์์ผ๋ฉด ๋ค์์ ์ป์ต๋๋ค.
$ yarn test
yarn run v1.22.4
$ node --experimental-vm-modules node_modules/jest/bin/jest.js
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In C:\Users\Domenic\Dropbox\Programming\WIP\remember-to-eat
1 file checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 0 matches
testPathIgnorePatterns: \\node_modules\\ - 1 match
testRegex: - 0 matches
Pattern: - 0 matches
error Command failed with exit code 1.
๋ด๊ฐ ์ถ๊ฐํ๋ฉด
"testMatch": ["**/__tests__/**/*.mjs"]
๋ด package.json์, ๋๋
$ yarn test
yarn run v1.22.4
$ node --experimental-vm-modules node_modules/jest/bin/jest.js
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In C:\Users\Domenic\Dropbox\Programming\WIP\remember-to-eat
1 file checked.
testMatch: **/__tests__/**/*.mjs - 0 matches
testPathIgnorePatterns: \\node_modules\\ - 1 match
testRegex: - 0 matches
Pattern: - 0 matches
error Command failed with exit code 1.
๊ทธ๋ฌ๋ "testMatch"
๋ฅผ ์ ๊ฑฐํ ๋ค์ ๋ด ํ์ผ์ ์ด๋ฆ์ __tests__/my-test.js
๋ก ๋ฐ๊พธ๋ฉด ์๋ํฉ๋๋ค.
๋ด ํ๋ก์ ํธ์์ .mjs ํ์ฅ์๋ฅผ ์ผ๊ด๋๊ฒ ์ฌ์ฉํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. Jest๋ก ๊ฐ๋ฅํ๊ฐ์?
@domenic ๋๋ ์ด๊ฒ์ ๋ง๋ฌ๋ค. ํด๊ฒฐ์ฑ
์ "moduleFileExtensions": ["js", "mjs"]
์ ์ถ๊ฐํ๋ ๊ฒ์
๋๋ค( "testMatch"
).
์ดํด๋ณด๋ moduleFileExtensions
๊ฐ ๊ผญ ํ์ํฉ๋๋ค.
Jest๋ ์ฌ๊ธฐ์ hasteFS.getAllFiles()
๋ฅผ ์คํํ์ฌ ํ๋ก์ ํธ์ ๋ชจ๋ ํ์ผ ๋ชฉ๋ก์ ๊ฐ์ ธ์ต๋๋ค.
hasteFS
๋ ๋ค์ extensions
๊ตฌ์ฑ์ ์ฌ์ฉํ์ฌ HasteMap
์ผ๋ถ๋ก ์์ฑ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ์ด ๊ฒฝ์ฐ moduleFileExtensions
๋ฅผ ์ง์ ํ ํ์๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฏธ .snap
๋ฅผ ๊ฐ์ ๋ก ์ฐพ์์ต๋๋ค. ์ ์๋ ค์ง JS ํ์ฅ๋ ๊ฐ์ ์คํํด์ผ ํฉ๋๊น? ๊ทธ๊ฒ๋ค์ (๋ด ๋จธ๋ฆฌ ๊ผญ๋๊ธฐ์์) js
, mjs
, cjs
, jsx
, ts
๋ฐ tsx
? ํฌ๋กค๋ง ์๋๊ฐ ๋๋ ค์ง์ง๋ง ํฐ ์ํฅ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค. ๋ด๊ฐ ํ๋ฆด ์๋ ์์ง๋ง? ๊ธฐ๋ณธ์ ์ผ๋ก cjs
๋ฐ mjs
๋ง ์ด๋ฏธ ๊ธฐ๋ณธ ํจํด์ ์ผ๋ถ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ํจ์ฌ ๋๋ ค์๋ ์ ๋์ง๋ง ์ฌ์ฉ์ ์ ์ ํจํด์ด ์๋ ์ฌ๋๋ค์ ๊ฒฝ์ฐ ์๋๊ฐ ๋๋ ค์ง ์ ์์ต๋๊น?
์, ์ ์ด๋ ES ๋ชจ๋ ๋ชจ๋์์ moduleFileExtensions๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ๊ธฐ๋ณธ testMatch๋ฅผ ์์ ํ์ง ์๊ณ .mjs๊ฐ ์๋ํ๋ฉด ์ด์์ ์ ๋๋ค.
.js ํ์ผ์ ์ ์ธํ ์ ์๋ค๋ฉด ์ข์ ๊ฒ์ ๋๋ค. ๋ด๊ฐ ๊ทธ๊ฒ์ ์๋ํ์ ๋ ๋๋
Validation Error:
moduleFileExtensions must include 'js':
but instead received:
["mjs"]
Please change your configuration to include 'js'.
๋ ธ๋ esm ํ์ผ ํ์ฅ์๋ฅผ ์ถ๊ฐํ๊ณ ์ตํธ์ธ(#9860)์ ์ํด esm์ ์ฌ์ฉํ์ฌ js๋ก ์ปดํ์ผํ๋ ๋ฐ ๋์์ด ๋๋ "ESM ๋ชจ๋"๊ฐ ์๋ ๊ฒ์ด ๋ง๋์ง ๊ถ๊ธํฉ๋๋ค.
js
์์ผ๋ฉด ์๋๋ฐ์ค ๋ด๋ถ์ ๋ก๋ํ๋ ์ผ๋ถ ํญ๋ชฉ์ด ๋ด๋ถ์ ์ผ๋ก ์ค๋จ๋ฉ๋๋ค(๋์ผํ require
๊ตฌํ ๋ฑ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์). ์ฌ์ฉ์๊ฐ ์ฐ๋ฆฌ๋ฅผ ๊นฐ ์ ์๋๋ก ์์ ํด์ผ ํ ๊ฒ์
๋๋ค.
์๋ ์ ํ์ ๊ด๋ จํ์ฌ ๋๊ท๋ชจ ํ๋ก์ ํธ์์๋ ์ด๋ฏธ ์๋นํ ๋๋ฆฌ์ง๋ง ํ์ฅ ์๊ฐ ๊ทธ๋ ๊ฒ ๋ง์ด ์ํฅ์ ๋ฏธ์น๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ํ์ง๋ง mjs์ cjs๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ถ๊ฐํด์ผ ํ๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. moduleFileExtensions: ['js']
์ง์ ํ๋ฉด ๊ธฐ๋ณธ๊ฐ์ด ๋ฌด์๋๊ณ ์๋๊ฐ ๋นจ๋ผ์ง๋๋ค. ๋ฐ๋ผ์ ์ฑ๋ฅ ์กฐ์ ์ผ๋ก ๋ฌธ์ํํ ์ ์์ต๋๋ค.
์ด ๋ชจ๋ ์์
์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค! ํ์คํ ๋๋์ต๋๋ค. ๋๋ 3 ๋จ๊ณ๋ฅผ ๋ฐ๋ผ ( "type": "module"
๋ด package.json์, "testEnvironment": "jest-environment-node"
๋ด ๋๋ด ์ค์ ๋ฐ --experimental-vm-modules
๋ CLI์)์ ๋๋ฌด ์ ์๋ ํ ๊ฒ ๊ฐ๋ค ๐
๊ทธ๋ฌ๋ ๋๋ ์ฝ๊ณ ์ฌ์ฉํ๊ธฐ ์ํด ๋
ธ๋ ฅํ๊ณ ์์ด import.meta
Node.js๋ฅผ ์๋ ํ๋ก์ธ์์ ์ค๋ช
๋๋๋ก (๊ทธ๋ฆฌ๊ณ ์ฒดํฌ ๋ฐ์ค์์ ํ๋จ ์ด๋ฏธ ๊ตฌํ ๊ฒ ๊ฐ๋ค์๋)์ ๋ง๋ค __dirname
ํ์ง๋ง ๊ฒ ๊ฐ์ import.meta
์คํจ:
console.log(import.meta);
SyntaxError: [PATH]/files.test.js: Support for the experimental syntax 'importMeta' isn't currently enabled (31:20):
Add @babel/plugin-syntax-import-meta (https://git.io/vbKK6) to the 'plugins' section of your Babel config to enable parsing.
๋๋ babel์ด ์๊ณ ์ด ์ํ์ babel์ด ๋จ๊ฒจ์ง ์ค ์์๋ค. babel์ ์ค์นํ์ง ์๊ณ ์ด๋ป๊ฒ๋ ๊ณ ์น ์ ์์ผ๋ฉด ๋ค์ ๋ณด๊ณ ํ๊ฒ ์ต๋๋ค.
Node.js v14.3.0, Jest v25.5.4
์ผ๋จ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ์์ต๋๋ค. ๋ด ํ์ผ์ด ๋ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ ๋์ผํ ๋๋ ํ ๋ฆฌ์์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํ ์ค์ด๋ฏ๋ก ๋ค์์ ์ํํ ์ ์์ต๋๋ค.
const __dirname = process.cwd();
const __filename = __dirname + "/files.test.js";
์ ๋ฐ์ดํธ๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋๋นํ์ฌ ์ด ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ํ๋ก์ฐํ๊ฒ ์ต๋๋ค. ์ด๋ ๊ฒ ํด์ฃผ์ ์ ๋ค์ ํ ๋ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
transform: {}
๋ฅผ ๊ตฌ์ฑ์ผ๋ก ์ฌ์ฉํ์ฌ Babel์ ๋ช
์์ ์ผ๋ก ์ ํ ํด์ ํด์ผ ํฉ๋๋ค.
@SimenB transform: {}
์ถ๊ฐ๊ฐ ์ ๋์๋์ง ํ์ธํ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค! ๋๋ ๊ทธ ์ ์ ์๋ํ ๋๋ก "๋ณํ์ ์ ๊ฑฐ"๊ฐ ์๋๋ผ "๋ณํ์ ์ถ๊ฐํ์ง ๋ง์ญ์์ค"๋ก ์คํดํ์ต๋๋ค.
BTW, ํ ์คํธ๋ 2.4์ด ์์ 1.3์ด๋ก ์ค์ด๋ค์๊ณ ์ง์์ ์ผ๋ก ๋ ๋น ๋ฅด๊ฒ ๋๊ปด์ง๋๋ค.
Node 12๋ ํ๋๊ทธ๊ฐ ์ง์ ๋์ง ์์ ESM์ผ๋ก ๋ฆด๋ฆฌ์ค๋์์ต๋๋ค(https://nodejs.org/en/blog/release/v12.17.0/). OP์์ ์ธ๊ธํ๋ฏ์ด Jest๊ฐ ์ฌ์ฉํ๋ API๋ ํ๋๊ทธ๊ฐ ์ง์ ๋์ง _not_
@SimenB ์ด ์ค๋ ๋๋ฅผ ์ฌ๋ฌ ๋ฒ ๊ฒํ ํ์ง๋ง ์ฌ์ ํ ๋ฉ์ท์ต๋๋ค(๋ ธ๋ 12.17 ์ฌ์ฉ).
Jest 26.0.1์ ์คํํ ๋ ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /app/tests/setup.js
require() of ES modules is not supported.
require() of /app/tests/setup.js from /app/node_modules/@jest/transform/build/ScriptTransformer.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename setup.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /app/package.json.
transform: {},
์๊ณ node --experimental-vm-modules node_modules/jest/bin/jest.js
์คํ ์ค์
๋๋ค.
๋ด๊ฐ ๋ฌด์์ ๋์น๊ณ ์์ต๋๊น?
@aldarund ํ์คํ์ง ์์ต๋๋ค. ์ต์ํ์ ์ฌ์์ฐ์ ์กฐํฉํ ์ ์์ต๋๊น?
@SimenB ์ฌ๊ธฐ์ ์ฌํํ ์ต์ ์ ์ฅ์๊ฐ ์์ต๋๋ค. yarn test
https://github.com/aledalgrande/jest-example์ ์คํ
๋ํ ๋ค๋ฅธ ์ฌ๋์ ์ธ๊ธํ์ต๋๋ค ๐
~ @simenB ๊ฐ ์๋๋ผ @aledalgrande ๋ด๊ฐ ์๋ํ ๊ฒ์์ ๋ชจ๋ ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ๊ฒ ๊ฐ์ต๋๋ค. ๋น๊ต๋ฅผ ์ํด ESM ์์ package.json
jest ๊ตฌ์ฑ).~
~๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋๋ฒ๊ทธํ๋ ค๋ฉด, ์๋ง๋ package.json
์์ 2๊ฐ์ ๊ด๋ จ ์์ฑ๋ง _only_ ๊ฐ๋๋ก jest ๊ตฌ์ฑ์ ๋จ์ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ํ์ฌ ์๋ํ๋/์๋ํ์ง ์๋ ์์ฑ์ ํ์ธํด์ผ ํ๋ ๋ค๋ฅธ ์์ฑ์ ๊ฐ๊ฐ ์ถ๊ฐํฉ๋๋ค.~
์ ๋ ๋ฒ์งธ ๋๊ธ์ globalSetup
์ธ๊ธํ๊ณ ์ผ๋ฐ ํ
์คํธ๊ฐ ์๋๋ผ ๋ด ๋๊ธ์ nvmํฉ๋๋ค. Jest์์ globalSetup
ํค๋ฅผ ์ ๊ฑฐํ๋ฉด ํด๋น ์์ ์์ ์์๋๋ก ํ
์คํธ๊ฐ ์คํ๋์ง๋ง globalSetup
ํค๋ ๋ง์ํ์ ๋๋ก ์๋ํ์ง ์์ต๋๋ค.
์, ์ ์ญ ์ค์ ๋ฐ ๋ถํด๋ฅผ ์์ด๋ฒ๋ ธ์ต๋๋ค. ๊ณ ์น ์ ์์ต๋๋ค ๐
์๋ ํ์ธ์ @SimenB ์ ๋๋ค. ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์ง์๋ฉ๋๊น? Node.js๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํจํค์ง๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ฌ์ฉํ ์ ์์ต๋๋ค.
import { customAlphabet } from "nanoid";
๊ทธ๋ฌ๋ ํ ์คํธ๋ฅผ ์ํํ๋ ค๊ณ ํ ๋ ๋์ผํ ์ฝ๋์์ ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
SyntaxError: The requested module 'nanoid' does not provide an export named 'customAlphabet'
ํ ์คํธ๋ฅผ ์ํด ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
import nanoid from "nanoid";
const { customAlphabet } = nanoid;
๊ทธ๋ฌ๋ ์ค์ ๋ก ๊ธฐ๋ณธ ์คํฌ์ธ ๊ฐ ์๊ธฐ ๋๋ฌธ์ Node.js ๋ฒ์ ์ด ์๋์ ๋ฉ์ถฅ๋๋ค(๊ทธ๋ฌ๋ ์ด๋ค ์ด์ ๋ก ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ๋ Jest์์ ์๋ํจ).
SyntaxError: The requested module 'nanoid' does not provide an export named 'default'
๊ฒ์๋(ํ์ฌ ์ ์ฅ์๊ฐ ์ ๋์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค) nanoid
์ฝ๋๋ ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ ์์ด ๋ค์๊ณผ ๊ฐ์ด ๋๋ฉ๋๋ค.
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
Jest๋ "์ฃผ์" ์ง์ ์ ๋ง ์ฌ์ฉํฉ๋๋ค. "์์ถ"์ ์์ง ๊ณ ๋ ค๋์ง ์์ต๋๋ค. ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ๋ง ์๋ commonjs ๋ฒ์ ์ ๊ฐ์ ธ์ค๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
์, package.json
์ ๋ค์์ด ํฌํจ๋ ๊ฒ ๊ฐ์ต๋๋ค.
"main": "index.cjs",
"module": "index.js",
"exports": {
"./package.json": "./package.json",
".": {
"require": "./index.cjs",
"import": "./index.js",
"browser": "./index.browser.js"
},
...
}
...
๊ทธ๋์ ์๋ง๋ Node.js๋ ๋ชจ๋ ๋ฒ์ ์ ์ฐพ๊ณ ์๋ ๋ฐ๋ฉด Jest๋ ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์๋ CommonJS ๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์์ ๊ฒ์ ๋๋ค. ๋ง์ต๋๊น?
Package Exports
๊ฐ ํ์ธ๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ํ
์คํธํ๊ฒ ์ต๋๋ค. ๋ค์ ํ ๋ฒ ์์
ํด์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค! ๊ทธ๋๊น์ง ์ด 2๊ฐ์ ๋๊ธ์ ํด๊ฒฐ๋ ๊ฒ์ผ๋ก ํ์ํฉ๋๋ค. ๋ด๊ฐ ๋งํ๋ ํ
์คํธ ๋ ์ด๊ฒ ์ด๋ค.
Jest 26.0.1 ๋ฐ ๋
ธ๋ 14.4๋ก ์
๊ทธ๋ ์ด๋๋ ์๋ ๋ฐฉ์์ ํ์ธํ๊ธฐ ์ํด ์ด๊ฒ์ ๋ค์ ๋ฐฉ๋ฌธํ๊ณ ์์ต๋๋ค. package.json ์ ๋ชจ๋ ์ ํ์ผ๋ก ์ค์ ํ๊ณ transform ์ {}
, env ๋ฅผ jest-environment-node
ํ๊ณ node --experimental-vm-modules
ํฉ๋๋ค. ์ด์ ๋ค์๊ณผ ๊ฐ์ ์๋ก์ด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
ES Modules are only supported if your test environment has the `getVmContext` function
๋๋ getVmContext
๊ฐ ์ผ๋ง ์ ์ ์ถ๊ฐ๋์๋ค๋ Jest์ ๋ณ๊ฒฝ ๋ก๊ทธ๋ฅผ ์ ์ธํ๊ณ ์ด์ ๋ํ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์์์ต๋๋ค.
์ด๋ค ์์ด๋์ด?
package.json
์ ๊ด๋ จ ๋ถ๋ถ์ @cyberwombat์ ๊ณต์ ํด ์ฃผ ์๊ฒ ์ต๋๊น? Jest์ ์ฌ์ฉ ์ค์ธ ์์ ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจํฉ๋๋ค.
์ฐธ๊ณ ๋ก ์์ ์ค์ธ ํ๋ก์ ํธ ์์ ๋๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
{
...
"type": "module",
"scripts": {
...
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
},
"jest": {
"transform": {},
"testEnvironment": "jest-environment-node"
},
...
๊ทธ๋ฐ ๋ค์ npm test
@franciscop ๊ด์ฐ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋์ผํฉ๋๋ค. ๋
ธ๋ 14.4.0. ๋๋ ๋น์ ์ ์ ์คํํ ์ ์์ต๋๋ค. ์ฐจ์ด์ ์ ํ์ธํ๊ธฐ ์ํด ํญ๋ชฉ์ ๋ฐ์ด๋ค ๊ฒ์
๋๋ค.
ํจํค์ง.json
{
"type": "module",
"devDependencies": {
"jest": "^26.0.1",
},
}
jest.config.js
export default {
testEnvironment: 'jest-environment-node',
setupFilesAfterEnv: ['./test/bootstrap.js'],
testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/config/', '/<rootDir>/src/'],
testRegex: '(\\.|/)(test|spec)\\.[jt]sx?$',
transform: {
// '^.+\\.jsx?$': 'babel-jest' // esm someday
},
transformIgnorePatterns: [],
modulePaths: [
'<rootDir>/test',
'<rootDir>/src',
'<rootDir>'
]
}
์คํฌ๋ฆฝํธ:
node --experimental-vm-modules node_modules/jest/bin/jest.js
ํ์คํ์ง ์์ง๋ง ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ์์
ํ๋ ค๊ณ ํฉ๋๋ค. transform: {}
๋ฐ testEnvironment: 'jest-environment-node'
์ ์ธํ ๋ชจ๋ ์ต์
์ ์ ๊ฑฐํ๊ณ ์ด์ ์ค๋ฅ๋ฅผ ์ ๋ฐํ๋ ์ต์
์ด ํ์๋ ๋๊น์ง ๊ฐ ์ต์
์ ์ถ๊ฐํ๊ธฐ ์์ํฉ๋๋ค. ๋๋ ํนํ transformIgnorePatterns
_might_ ๊ฐ transform
์ ์ถฉ๋ํ๋ค๊ณ ์๊ฐํ์ง๋ง jest ์ต์
์ ์ต์ํ์ง ์์ต๋๋ค.
์ฌ๋ฌ๋ถ, ์๋ ํ์ธ์! Jest๋ฅผ ์ฌ์ฉํ์ฌ Express ์ ํ๋ฆฌ์ผ์ด์ ์ ํ ์คํธํ๋ ๋์ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ . ์ฌ๊ธฐ์์ ์ํ/์ถ์ ํ๋ ์์ ์ ์ ์ฉํ์ง ํ์คํ์ง ์์ต๋๋ค.roll_eyes:
@ x80486 ์ด์ ์ ํํ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ด ์ดํด์์ ๋ ๊ธด ์ค๋ช ์ผ๋ก StackOverflow์ ๋ต๋ณํ์ต๋๋ค .
ํธ์ง: ๊ด๋ จ์ฑ์ด ์์ ์ ์๊ธฐ ๋๋ฌธ์ ์ด์ ์๊ฒฌ์ ์จ๊น ํด์ ํ์ต๋๋ค. ์ด "exports"
๋ ์ธ๊ธฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ํ์ด๋ธ๋ฆฌ๋ ํจํค์ง์ ๋ํ ์ด ๊ธฐ์ฌ์ ๊ฐ๋ฅ์ฑ
exports
๋ #9771์์ ์ถ์ ๋ฉ๋๋ค.
@franciscop ๋ฌธ์ ํด๊ฒฐ๋จ - ํจํค์ง์ ์ถฉ๋์ด ์๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค. - ES Modules are only supported if your test environment has the
getVmContext function
์ค๋ฅ๋ฅผ ์ผ์ผํค๋ serverless-bundle
์ค์นํ์ต๋๋ค. ์ด์ ๋ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ค์นํ๋ฉด Jest์ ์ถฉ๋์ด ๋ฐ์ํ์ง ์์ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํ์ง๋ง ๋ถ๋ช
ํ ๊ทธ๋ ์ต๋๋ค.
@franciscop pkg.exports
๊ด๋ จ ๋ฌธ์ ๊ฐ ์ง๊ธ ํ๋ฉดํ๋๊ธฐ ์์ํ๋ ์ด์ ๋ ํด๋น ๊ธฐ๋ฅ์ด Node.js 14.x
์์ ํ๋๊ทธ๊ฐ ์ง์ ๋์ง ์์๊ณ ์ผ๋ถ ํจํค์ง ์ ์ง ๊ด๋ฆฌ์( uuid
)๊ฐ ์์๋์๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. pkg.exports
ํ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค. ๋ฐ๋ผ์ Node.js 12.x
์์ ํด๋น ๊ธฐ๋ฅ์ ํ์ฑํํ๊ธฐ ์ํด ๋ช
๋ น์ค ํ๋๊ทธ๊ฐ ํ์ํ์ง๋ง ์ด์ ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋น ๋์์ ์ป๊ฒ ๋ฉ๋๋ค.
์ ์ฒด ์ํ๊ณ๊ฐ ์ ์ํ๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ฏ๋ก ํด๋น ์ฃผ์ ์ ๊ด๋ จ๋ ๋ฌธ์ ๋ฅผ ๋ณด๊ณ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
exports
์ ๋ํด ๊ฒ์ํ๋ ๊ฒฝ์ฐ ์ด ๋ฌธ์ ์ ๊ธด ์ค๋ ๋์์ ์์ค๋ ๊ฒฝ์ฐ ์ด์ ๋ํ ๋ด ๋ซํ ๋ฌธ์ (https://github.com/facebook/jest/issues/9565)์ ์๊ฐ ์์ต๋๋ค. moduleNameMapper
ํด๊ฒฐ ๋ฐฉ๋ฒ ์ค ํ๋์
๋๋ค.
5์์ ๋ณด๊ณ ๋ globalSetup
๋ฌธ์ ๊ฐ ์ฌ์ ํ ์์ ์ ์์ต๋๊น(Jest 26.1.0)? ์์ repo @aledalgrande ์์์ ๋์ผํ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ๋ค์์ด ์ ๊ณต๋ฉ๋๋ค.
$ git clone [email protected]:aledalgrande/jest-example.git
$ cd jest-example
$ npm test
> @ test /Users/asko/Temp/jest-example
> node --experimental-vm-modules node_modules/jest/bin/jest.js --config=./jest.config.js
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/asko/Temp/jest-example/tests/setup.js
require() of ES modules is not supported.
require() of /Users/asko/Temp/jest-example/tests/setup.js from /Users/asko/Temp/jest-example/node_modules/@jest/transform/build/ScriptTransformer.js
์๋๋ฅด์ง ๋ง. CHANGELOG
๋ฅผ ํ์ธํ์ง๋ง ES6์์ globalSetup/globalTeardown์ ๋ํ ์์ ์ฌํญ์ ์ธ๊ธํ์ง ์์์ต๋๋ค.
Node.js 14.4.0, ์ ์คํธ 26.1.0
์ ๋ฐ์ดํธ(8์ 13์ผ-8์ 20์ผ):
์ฌ์ ํ ๋ถ๊ฐ๋ฅ, Node.js 14.7.0, Jest 26.4.0
๋ถ์ ์ ํ์ง๋ง ์ด ๋ฌธ์ ๋ ํ์ฌ ๋๋ด์ ์ด์ ์ด๊ธฐ ๋๋ฌธ์ ๊ณ ์ ๋ ๋ฌธ์ ์ฌ์ผ ํฉ๋๊น?
ES ๋ชจ๋๋ก ์์ฑ๋ ํ
์คํธ ๋ฆฌํฌํฐ๋ฅผ ์๋นํ๊ธฐ ์ํด ์ํํด์ผ ํ ์์
์ ๋ํ ์๊ฐ์ด ์์ต๋๊น?...
์ต์ jest ๋ฒ์ ์์ testScheduler๊ฐ commonjs ํ์์ ์ฌ์ฉ์ ์ง์ ๋ฆฌํฌํฐ๋ฅผ ๊ธฐ๋ํ๋ค๊ณ ๋ณธ์ง์ ์ผ๋ก ๋งํ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.์ค๋ฅ๋ฅผ ๋ณด๋ ค๋ฉด
~/projects/esw-ts/lib/dist/test/testReporter.js:1
'os'์์ os๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
^^^^^^
SyntaxError: ๋ชจ๋ ์ธ๋ถ์์ import ๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
wrapSafe์์(internal/modules/cjs/loader.js:1116:16)
Module._compile์์ (internal/modules/cjs/loader.js:1164:27)
Object.Module._extensions..js์์ (internal/modules/cjs/loader.js:1220:10)
Module.load์์ (internal/modules/cjs/loader.js:1049:32)
Function.Module._load์์ (internal/modules/cjs/loader.js:937:14)
Module.require์์(internal/modules/cjs/loader.js:1089:19)
ํ์ ์(internal/modules/cjs/helpers.js:73:18)
/Users/manish.gowardipe/Desktop/projects/esw-ts/lib/node_modules/@jest/core/build/TestScheduler.js:418:65์์
Array.forEach์์ (
TestScheduler._addCustomReporters์์ (/Users/manish.gowardipe/Desktop/projects/esw-ts/lib/node_modules/@jest/core/build/TestScheduler.js:411:15)
์๋ ํ์ธ์, ์ ๋ ์ ์์ ํ๋ก์ ํธ์์ ES ๋ชจ๋์ ๋ํ ๊ธฐ๋ณธ ์ง์์ ํ ์คํธํ๊ณ ์ถ์ง๋ง NodeJS๋ฅผ ์ฒ์ ์ฌ์ฉํ๊ณ ์ด ๋ฌธ์ ์์ ๊ธธ์ ์์์ต๋๋ค. ๋ช ๊ฐ์ง ์ง์นจ์ ์ํฉ๋๋ค.
node --version
: v14.5.0yarn jest --version
: 26.1.0ํจํค์ง.json
{
"jest": {
"transform": {},
"testEnvironment": "jest-environment-node"
}
}
markov.test.js
const fs = require("fs");
const Markov = require("./markov.mjs");
// import fs from "fs";
// import Markov from "./markov.mjs";
const file = fs.readFileSync("text.txt", "utf8");
const markov = new Markov(file.toString());
test("Generates sentence with especified words", () => {
expect(markov.makeSentence(8).length).toBe(8);
});
yarn jest .
์คํํ๋๋ฐ ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
node node_modules/jest/bin/jest.js .
์๋ํ๋๋ฐ ๋์ผํ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
@pepetorres1998 ์ด ์ค๋ ๋๋ ํน์ ํ๋๊ทธ/์ต์ ์ผ๋ก ์์ ์ ์คํํ๋ ๊ฒ๊ณผ ๊ด๋ จ๋ ๊ธฐ๋ณธ esm ๋ชจ๋๋ก Jest๋ฅผ ์คํํ๋ ๊ฒ์ ๊ดํ ๊ฒ์ ๋๋ค. ์ํํ ์์ ์ ๋ํด์๋ ์์
์ด ์ค์ ์ผ๋ก ํ
์คํธ ํ์ผ์์ jest.setTimeout(...)
์ ๊ฐ์ ์์
์ ์๋ํ ๋ ๋ค๋ฅธ ์ฌ๋์ด ReferenceError: jest is not defined
๋ฐ๊ณ ์์ต๋๊น? ์ด๊ฒ์ด es ๋ชจ๋ ํ๊ฒฝ, ๋
ธ๋ ๋ฒ์ , jest ๋ฒ์ ๋๋ ์ด๋ฌํ ๊ฒ๋ค์ ์กฐํฉ๊ณผ ๊ด๋ จ์ด ์๋์ง ์์๋ด๋ ค๊ณ ํฉ๋๋ค. (ํ์ฌ ๋
ธ๋ v14.5.0, jest 26.1.0, ํ๊ฒฝ jest-environment-node ์ฌ์ฉ)
ํธ์งํ๋ค
์ด์ jest 'global' ์์ฑ์ ๋ํ ๋ฌธ์ ์ค๋ช
์์ ์ ํ๋์ง ์์ ํ์ธ๋์ด ํ์๋ฉ๋๋ค. ๐
@bdentino ๋ช
์์ ์ผ๋ก ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์๋ํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. import {jest} from '@jest/globals';
25.4.0์ด ์ฒซ ๋ฒ์งธ ์ง์๊ณผ ํจ๊ป ๋ฆด๋ฆฌ์ค๋์์ต๋๋ค. ์์์ ์ธ๊ธํ #9772 ์ธ์๋ #9842๋ ํฌํจํ์ต๋๋ค. _์ด๋ก ์ ์ผ๋ก_ CJS์ ESM์ ํผํฉํ๋ฉด ์ด์ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํฉ๋๋ค(๐ค).
ํ ๊ฐ์ง ์ฃผ์ ๋๋ฝ ๊ธฐ๋ฅ์
jest
๊ฐ์ฒด๋ฅผ ์ง์ํ๋ ๊ฒ์ ๋๋ค.import.meta
ํ ์ง ์๋๋ฉดimport {jest} from '@jest/globals'
ํตํด ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์๊ตฌํ ์ง ๊ฒฐ์ ํ์ง ์์์ต๋๋ค. ํผ๋๋ฐฑ ๊ฐ์ฌํฉ๋๋ค!์์ง ์ด์ ๋ํ ๋ฌธ์๋ฅผ ์์ฑํ์ง ์์์ง๋ง ํ์ฑํํ๋ ค๋ฉด 3๊ฐ์ง ์์ ์ ์ํํด์ผ ํฉ๋๋ค.
- transform away
import
๋ฌธ์ ์คํํ์ง ์์๋์ง ํ์ธํ์ญ์์ค(config์์transform: {}
๋ฅผ ์ค์ ํ๊ฑฐ๋babel
๋ฅผ ํผํ๋ ๊ฒ๊ณผ ๊ฐ์ดmodules
์ฌ์ ์ค์ ํ๊ฒฝ์ ๋ํ ์ต์ )--experimental-vm-modules
ํ๋๊ทธ๋กnode@^12.16.0 || >=13.2.0
์คํjest-environment-node
๋๋jest-environment-jsdom-sixteen
ํ ์คํธ ์คํ์ฌ์ฉํด๋ณด๊ณ ํผ๋๋ฐฑ์ ์ฃผ์ธ์! ๋ฒ๊ทธ๋ฅผ ๋ณด๊ณ ํ๋ ๊ฒฝ์ฐ Node.js์์ ๋์ผํ ์ฝ๋(ํ ์คํธ๋ณ ์ฝ๋ ์ ์ธ)๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ๋ ํฌํจํ ์ ์๋ค๋ฉด ์ ๋ง ์ข์ ๊ฒ์ ๋๋ค. ์ง๋ ๋ช ์ฃผ ๋์ https://nodejs.org/api/esm.html _๋ง์ด_ ์ฝ์์ง๋ง ์๋ง๋ ๋ญ๊ฐ๋ฅผ ๋์ณค์ ๊ฒ์ ๋๋ค.
@์๋ฉ๋น
์ด ์ฐ๋ ๋๋ ์์ฒญ๋ฌ๊ณ , ๋๋ด์ผ๋ก ์์ํ๊ณ / ES ๋ชจ๋์ ์ฌ์ฉํ๋ ค๋ ์ฌ๋๋ค์ ์์ํ๊ธฐ ์ํ ๊ธฐ๋ณธ ์ง์นจ์ ์ฐพ๊ณ ์ดํดํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋ฌธ์์ ES ๋ชจ๋ ํ๋ก์ ํธ(๋๋ ์ผ๋ถ '๋น ๋ฅธ ์์')์ ๋๋ด์ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํ ๊ณต์์ ์ธ ์ค๋ช
์ด ์์ต๋๊น?
@aldeed ๋์ผํ ํ๋ก์ ํธ์ ๋ชจ๋์ ์กฐ๋กฑํ๋ ๋ฌธ์ ์ ๊ด๋ จํ์ฌ ์์ ์ฌํญ์ ์ฐพ์์ต๋๊น? ๋๋ ๋๊ฐ์ ๋ฌธ์ ๊ฐ ์๋ค
(Btw, ์ฐ๋ฆฌ๋ ๋ฆฌ์ก์ ์ปค๋จธ์ค๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ๊ฑด๋ฐฐ ํํ)
@guilhermetelles ์๋์, ํ์ฌ https://github.com/facebook/jest/issues/10025 ์์ ์ถ์ ์ค์ ๋๋ค.
Jest 26.1.0, node
๋ฒ์ 14.6.0 with --experimental-vm-modules
ํ๊ณ ์์ง๋ง CommonJS ๋ด๋ถ์์ import()
์ฌ์ฉํ ๋ ์ฌ์ ํ ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING
๋ฉ๋๋ค. . ์ต์ํ์ ์ฌํ์ ์๋ํ๊ณ ์ ๋ฌธ์ ๋ฅผ ์ด์ด์ผ ํฉ๋๊น?
์ ์ณ๋๊ณ , Jest๊ฐ yarn berry๋ฅผ ์ฌ์ฉํ๋ ์ง๊ธ jest
ํจํค์ง์ ๋ณต์ฌ๋ณธ์ yarn link
ํ๋ ์ฌ์ด ๋ฐฉ๋ฒ์ด ์์ต๋๊น? ์ด๊ฒ์ด ์์ง ์ถ์๋์ง ์์ ์ ์ํด ๊ตฌํ๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ์ต์ master
๋ฅผ ์๋ํ๊ณ ์ถ์์ต๋๋ค. path/to/facebook/jest/.yarn/releases/yarn-sources.cjs link --all path/to/jest
์ ๊ฐ์ ์์
์ ์๋ํ์ง๋ง ์คํจํ์ต๋๋ค. cd node_modules; for p in jest*; do if [[ -d path/to/jest/packages/$p ]]; then rm -rf $p; ln -s path/to/jest/packages/$p; fi; done
์ ๊ฐ์ ๊ฒ์ ์๋์ผ๋ก ์คํํ๋ ๊ฒ๋ ์๋ํ์ง ์์ต๋๋ค. ์ด์ ๋ฅผ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
CJS์ @vvanpo import()
๊ฐ Node์์ ๋๋๋ ค์ก์ต๋๋ค. https://github.com/nodejs/node/issues/31860์ ํ๋ก์ฐํ ์ ์์ต๋๋ค.
๋ก์ปฌ ์คํ์ ๊ดํด์๋ ์ผ๋ฐ์ ์ผ๋ก ํ
์คํธํ๋ ค๋ ํ๋ก์ ํธ์์ jest
์ ๊ฑฐํ๊ณ ../jest/jest
ํฉ๋๋ค. ์ ์ฌ์ ์ผ๋ก nose ../jest/packages/jest/bin/jest.js
. yarn
๋ฐ yarn build:js
๋จผ์ ์คํํด์ผ ํฉ๋๋ค. ์ด ์ง์นจ์ด ์๋ํ์ง ์๋ ๊ฒฝ์ฐ(๋นํ๊ธฐ์์ ํด๋์ ํ๋ก ๋ฉ๋ชจ๋ฅผ ์์ฑ ์ค์
๋๋ค) ๋ฌธ์ (๋๋ PR)๋ฅผ ์ด์ด CONTRIBUTING.md
ํ์ผ์ ์ฌ๋ฐ๋ฅด๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
์ํ ์์ ์ ์ง์ํ ๊ณํ์ ๋๊น?
์๋ก๋ง ๊ฐ์ ธ์ค๋ ๋ ํ์ผ ์ค ํ๋๋ง ๊ฐ์ ธ์ค๋ ๋๋ฏธ ํ
์คํธ ํ์ผ์ด ์๋ ๊ฒฝ์ฐ RangeError: Maximum call stack size exceeded
๋ฉ๋๋ค. ๊ฐ์ ธ์ค๊ธฐ ์ค ํ๋๋ฅผ ์ ๊ฑฐํ๋ฉด ํ
์คํธ๊ฐ ํต๊ณผํฉ๋๋ค. ๋ฌธ์ ๋ฅผ ์ฌํํ๋ Repo .
์ผ! ๋๋ ์ด๊ฒ์ ๋น ๋ ธ๋ ํ๋ก์ ํธ์์ ์ค์ ํ๊ณ ์ ๋ง ์ ์๋ํ์ง๋ง ์ฐ๋ฆฌ์ ํ๋ก๋์ ์ค์ ์์ ํ ์คํธ๋ฅผ ์คํํ๋ ค๊ณ ํ ๋ ๋ค์ ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ํ๋ฉ๋๋ค.
ES Modules are only supported if your test environment has the 'getVmContext' function
๋๋ ๋ค๋ฅธ ์ฌ๋์ด @cyberwombat ์ ์ด์ ๋ต๋ณ์์ ๋ฌธ์ ๋ฅผ ๊ฒช๊ณ ์๋ ๊ฒ์ package.json
ํ์ผ์ ์์ต๋๋ค. ๋ฌธ์ ๋ฅผ ์ผ์ผํค๋ ํจํค์ง(๋๋ ์ค์ )๋ฅผ ์ถ๋ก ํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์
๋๊น? ์ด ์์
์ ์ํํ๋ ๋ฐ ํ์ํ์ง ์์ ๋ชจ๋ ๋๋ด ์ค์ ์ ์ฒด๊ณ์ ์ผ๋ก ์ ๊ฑฐํ๋ ค๊ณ ์๋ํ์ง๋ง ์ฑ๊ณตํ์ง ๋ชปํ์ต๋๋ค.
์
๋ฐ์ดํธ : jest-runtime
์ฝ๊ฐ ๋ณ๊ฒฝํ์ฌ ์งํ์ ํ์ต๋๋ค. VM ์ปจํ
์คํธ์ ์ก์ธ์คํ๋ ค๊ณ ํ๋ ๋ผ์ธ์์ ๋๋ฒ๊ฑฐ๋ฅผ ์ค์งํ๊ณ ํจ์๊ฐ ์ค์ ๋ก ์กด์ฌํ์ง ์๋ ๋์ this.context
(๋ฐํํด์ผ ํจ)๋ ์กด์ฌํ๋ฏ๋ก ํด๋น ๋ผ์ธ์ ์์ฑ์ ์ง์ ์ก์ธ์คํ๋๋ก ๋ณ๊ฒฝํ์ต๋๋ค. ์ด๊ฒ์ด ์๋ง๋ ์ด์์ ์ด์ง ์๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง @SimenB ์ด๊ฒ์ด ๋ฌด์์ด ์๋ชป๋๊ณ ์๋์ง์ ๋ํ ์์ด๋์ด๋ฅผ ์ค ์ ์์ต๋๊น?
๋์์ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
์ํ ์์ ์ ์ง์ํ ๊ณํ์ ๋๊น?
๋ถ๋ช ํ! ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ด โโ์ ์์ต๋๊น?
@zsombro ๋ ์ด์ ๋ฒ์ ์ ํ
์คํธ ํ๊ฒฝ์ ์คํํ๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋น์ ์ด ์คํํ๋ ๊ฒฝ์ฐ jest --show-config
, ๋ฌด์์ผ๋ก ํ์๋ฉ๋๋ค testEnvironment
?
ํ ์คํธ ํ๊ฒฝ์ ์ด์ ๋ฒ์ ์ ์คํ ์ค์ธ ๊ฒ ๊ฐ์ต๋๋ค. ๋น์ ์ด ์คํํ๋ ๊ฒฝ์ฐ
jest --show-config
, ๋ฌด์์ผ๋ก ํ์๋ฉ๋๋คtestEnvironment
?
@SimenB ๋ค์๊ณผ ๊ฐ์ด ๋งํฉ๋๋ค.
"testEnvironment": "/Users/zberki/git/project-name/node_modules/jest-environment-node/build/index.js",
"testEnvironmentOptions": {},
๊ทํ์ ์ง์์ ๋ฐ๋ผ jest-environment-node
์ค์ ํ์ต๋๋ค.
์ด ํ๋ก์ธ์ค๋ฅผ ์์ํ๊ธฐ ์ ์ yarn add jest@latest
์ฌ์ฉํ์ฌ jest๋ฅผ ์
๊ทธ๋ ์ด๋ํ์ต๋๋ค. ํ๊ฒฝ์ ๋ณ๋๋ก ์
๊ทธ๋ ์ด๋ํด์ผ ํฉ๋๊น?
์
๋ฐ์ดํธ: ํด์ผ ํ๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค. ์๋ก ์ค์นํ๊ธฐ ์ํด node_modules
๋ฐ yarn.lock
๋ฅผ ์ญ์ ํ์ง๋ง ์ฌ์ ํ ์๋ํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ yarn add -D jest-environment-node
๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ์ถ๊ฐํ๋ฉด ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๊ฒ์ ๊ด๋ฆฌํ๋ ๋ ์ข์ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? ์ฐ๋ฆฌ ์ฝ๋๋ฒ ์ด์ค์์ ์ด ์์
์ ์ํํ๊ธฐ ์ ์ ์ต์ํ์ ํ
์คํธ ํ๋ก์ ํธ๋ฅผ ์ํํ์ผ๋ฉฐ ์ด ์์
์ ์ํํ ํ์๊ฐ ์์์ต๋๋ค.
yarn list jest-environemnt-node
(๋๋ npm list jest-environemnt-node
)๋ ์๋ง๋ ์ฌ๋ฌ ๊ฐ๋ฅผ ๋์ดํ ๊ฒ์
๋๋ค. ์ ์ถ์ธก์ผ๋ก๋
โโ [email protected]
โ โโ [email protected]
โโ [email protected]
26.2.0
๋ฒ์ ์ ์ ์ด๋์ ๋ฐ๋ผ (๋ด๊ฐ ์๋์ผ๋ก ์ค์น ๋ฌด์ ์๋ง package.json
์ฆ, jest-config
๋ถ๋ช
ํ ์ค๋๋๋๋ ๋ฒ์ ์ ์ค์น ํ?
jest-config
( react-scripts
์๋ง๋ ( create-react-app
)?)์ ์ด์ ๋ฒ์ ์ ๊ฐ์ ธ์ค๋ ๋ค๋ฅธ ๊ฒ์ด ์์ต๋๋ค. ์ด ๋ฌธ์ ๋ ํ ๋ก ํ ๊ณณ์ด ์๋๋๋ค.
๋ด globalSetup
์์ ES ๋ชจ๋์ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ด ์ํ๊ธฐ ์์ํ์ต๋๋ค.
๋ ๊ฐ์ง ์ :
๋:
"testEnvironment": "jest-environment-node",
์ถ๊ฐ๋จimport { jest } from '@jest/globals';
์ถ๊ฐ๋จNODE_OPTIONS='--experimental-vm-modules' yarn jest
์ ํจ๊ป ์คํํ์ฌ ํ
์คํธ ๋ช
๋ น ์ค์ --experimental-vm-modules
์คํ๊ทธ๋ฆฌ๊ณ ๋ค์ ์ฝ๋์์ ์ถฉ๋ํฉ๋๋ค.
jest.mock('../../some/other/path', () => ({
someOtherMethod: jest.fn().mockImplementation(โฆ),
}));
๋ค์ ์ค๋ฅ์ ํจ๊ป(์ค์ - "ํ์ฉ๋ ๊ฐ์ฒด" ์ฐธ๊ณ !):
ReferenceError: src/foo/bar.spec.js: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: jest
Allowed objects: Array, โฆ, jest, โฆ, unescape.
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` (case insensitive) are permitted.
Babel ์์ด Node 14์์ ์คํํ๋๋ก ์์ ํ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ถ์ ์ ํ๊ฒ ๊ตฌ๋ฌธ ๋ถ์ํ๊ธฐ ๋๋ฌธ์ Babel์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
-import { map } from 'lodash';
+import lodash from 'lodash';
+const { map } = lodash;
๋ถํํ๋ @babel/preset-env
์ํด ๋ถ์ ์ ํ๊ฒ ๊ตฌ๋ฌธ ๋ถ์ ๋์ด TypeError: Cannot destructure property 'map' of '_lodash.default' as it is undefined.
๋ฉ๋๋ค.
๋๊ตฐ๊ฐ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ๋์์ ์ค ์ ์์ต๋๊น?
ํธ์ง: ์ด ์ ๋์ ์ผ๋ก ์ญ๊ฒจ์ด ์์ ์ ์ํํ์ฌ CommonJS ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ดํฐ๋ธ ES ๋ชจ๋ ํธํ ์ฝ๋์์ Jest+Babel์ _ํ ์ ์๋_ ๊ฒ ๊ฐ์ต๋๋ค.
jest.mock('common-js-module', () => ({
__esModule: false,
...jest.requireActual('common-js-module'),
}));
์ด ๋ฐฉ๋ฒ,
import lodash from 'lodash';
const { map } = lodash;
Node 14์์ ์๋ฒฝํ๊ฒ ์๋น๋๊ณ Jest+Babel์ ์คํํ์ฌ ์์ฑ๋ ์ฝ๋,
var _lodash = _interopRequireDefault(require("lodash"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const {
map
} = _lodash.default;
๋ ์คํํฉ๋๋ค.
์ฐ๋ฆฌ๋ ES6 ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ณ ๊ฐ์ ธ์ค๊ธฐ ์ํด ๋ชจ๋ jest ํ
์คํธ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๋ณํํ์ง๋ง puppeteer
๋ฐ uuid
์ ๊ฐ์ ๋ช ๊ฐ์ง ํจํค์ง์์ ๋ฉ์ท์ต๋๋ค.
์ฑ์ ๊ฐ์ฒด(์ import uuid from 'uuid'
)๋ก ๊ฐ์ ธ์ฌ ๋๋ง ์๋ํ์ง๋ง ํ
์คํธ๋ ์ด๋ฐ ์์ผ๋ก ์คํ๋์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ถํด ๊ตฌ๋ฌธ(์: import { v4 } from 'uuid'
)์ผ๋ก ๋ฐ๊พธ๋ฉด ๊ทธ ๋ฐ๋์
๋๋ค. ํ
์คํธ๋ ์๋ํ์ง๋ง ์ฑ์์ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
์๋ ์ฐ๋ฆฌ๋ ๊ฐ์ด๋์ ๋ฐ๋ผ ๋ชจ๋ ๋ณํ์ ํด์ ํ์ง๋ง ์ต์ํ์ ๋ ธ๋ ๊ตฌ์ฑ์ผ๋ก babel์ ์ค์นํ yarn ์์ ๊ณต๊ฐ์ ๋ง๋ค๋ ค๊ณ ์๋ํ์ง๋ง ์ด ํน์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ(๋๋ ์ ํ)๋์ง ์์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ํด์ฒด ๊ตฌ๋ฌธ(์: import { v4 } from 'uuid')์ผ๋ก ๋ฐ๊พธ๋ฉด ๊ทธ ๋ฐ๋์ ๋๋ค. ํ ์คํธ๋ ์๋ํ์ง๋ง ์ฑ์์ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ฑ์ด CommonJS๋ก ์ปดํ์ผ๋๊ณ ์ค์ ๋ก ๋ชจ๋์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. "์ค์ " ESM์์ import uuid from 'uuid'
๋ ์๋ํ์ง ์์์ผ ํฉ๋๋ค. uuid
์๋ ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์๊ณ node ์ ๋ํ ESM ๋น๋๊ฐ ๋
ธ์ถ ๋๊ธฐ ๋๋ฌธ์
๋๋ค.
@SimenB๋ , ์ด์ ๋ํ ์๋น ๋ฌธ์๊ฐ ์ข์ ์๊ฐ์ด๋ผ๊ณ ์๊ฐํ์ญ๋๊น?
@grantcarthew ํ์คํ! ์ด ์์ ์ ๋ ๋ง์ ์๊ฐ์ ํ ์ ํ๊ณ Jest 27์ฉ์ผ๋ก ์์ ํํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋์ง๋ง ๊ทธ๋ ๊ฒ ํ ์ ์์์ง๋ ์๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ํ์ฌ ์๋ ๊ฒ(๊ทธ๋ฆฌ๊ณ ์คํ์ ์)์ ๋ํ ๋ฌธ์ ํ์ด์ง๋ฅผ ์์ฑํ๋ ๊ฒ์ ์ข์ ์๊ฐ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค.
@SimenB ๋ฌธ์ ์ ํ์ฌ ์ํ๊ฐ ๋ฌด์์ธ์ง ๊ทธ๋ฆฌ๊ณ Jest๊ฐ ์ด๋ฏธ ๋ด ์ฌ๋ก์ ํจ๊ป ์๋ํด์ผ ํ๋์ง ์ฌ๋ถ๋ฅผ ๋ชจ๋ฅด์ง๋ง ์ด๋ป๊ฒ๋ ๋์์ด ๋ ์ ์์ต๋๋ค.
esm ์ ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ค๊ณ ํฉ๋๋ค(ํ์ฅ์๋ cjs์ด์ง๋ง ์ ํ์ ๋ชจ๋์ด๊ณ ๋ ธ๋๋ ๊ด์ฐฎ์ ๊ฒ ๊ฐ์ต๋๋ค). ๊ทธ๋ฌ๋ Jest๋ ์ค๋ฅ์ ํจ๊ป ์ ๋๋ก ๋ก๋ํ์ง ๋ชปํฉ๋๋ค.
C:\dev\codemirror-next-repro-cra\test-in-jest-esm\node_modules\style-mod\dist\style-mod.cjs:15
export var StyleModule = function StyleModule(spec, options) {
์ฌ๊ธฐ์ ๋ด๊ฐ ์๋ https://github.com/codemirror/codemirror.next/issues/310์ ์ด์๋ ๋ฌธ์ ๊ฐ https://github.com/dubzzz/codemirror-next-repro-cra/tree/main/test-in-jest-esm์ผ๋ก ์คํจํ Jest + ESM์ ๋ํ ์ฌํ
@dubzzz cjs
ํ์ผ์๋ ESM์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋
ธ๋๋ ์คํจ
$ node node_modules/style-mod/dist/style-mod.cjs
(node:48829) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/simen/repos/codemirror-next-repro-cra/test-in-jest-esm/node_modules/style-mod/dist/style-mod.cjs:15
export var StyleModule = function StyleModule(spec, options) {
^^^^^^
SyntaxError: Unexpected token 'export'
at wrapSafe (internal/modules/cjs/loader.js:1172:16)
at Module._compile (internal/modules/cjs/loader.js:1220:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
at Module.load (internal/modules/cjs/loader.js:1105:32)
at Function.Module._load (internal/modules/cjs/loader.js:967:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47
์ฃ์กํฉ๋๋ค. ๋
ธ๋ ์ธก์์ ๋๋ฌด ๋นจ๋ฆฌ ์๋ํ์ต๋๋ค. @nicolo-ribaudo๋ ์ด๋ฏธ ์ด ๋ฌธ์ ์ ๋ํด lib ์์ฑ์์๊ฒ ์๋ ธ์ต๋๋ค.
๋น ๋ฅธ ๋ต๋ณ ์ ๋ง ๊ฐ์ฌํฉ๋๋ค.
์ฌ๊ธฐ์์ ์ผ๋ถ (๊ฑฐ์ ์คํ ) ๋ฌธ์์ ๋ํ PR์ ์ด์์ต๋๋ค. #10611. ์ ๋ ๋๋ฝ๋ ๊ธฐ๋ฅ/๋ฒ๊ทธ๋ฅผ ์ด๊ฑฐํ๋ ๊ฒ์ ๊ท์ฐฎ๊ฒ ์๊ฐํ์ง ์์์ต๋๋ค. ํ์ค๊ณผ ๋๊ธฐํ๋ฅผ ์ ์งํ๊ธฐ ์ด๋ ค์ธ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๊ณ github ๋ฌธ์ ๋ฅผ ๋ณด๋ ๊ฒ์ด (๋ฐ๋ผ๊ฑด๋...) ์ต์ ์ํ์ด๋ฏ๋ก ๋ ๋์ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค.
@Pomax ์ ๊ฐ ์ผ๋ก ๋ถํ๋๋ฆฝ๋๋ค ๐
๋ฐฉ๊ธ CJS์์ import()
๋ํ ์ง์์ ์ถ๊ฐํ๋ #10620์ ์ด์์ต๋๋ค. ๋ช ๋ฒ ์์ฒญํ ๊ฒ์ https://github.com/facebook/jest/issues/9430#issuecomment -626054595์ ๊ฐ์ต๋๋ค.
์ฌ๋ณด์ธ์. ๋
ธ๋/์ ์คํธ์์ ESM ์ด๋ฉด์ ์ ์ฒด ์ด์ผ๊ธฐ๋ฅผ ๋น ๋ฅด๊ฒ ์์ฉํ๋ ๊ฒ์ ๋งค์ฐ ์ด๋ ต์ต๋๋ค. ๊ทธ๋์ ์๋ง๋ ๋ช
๋ฐฑํ๊ฑฐ๋ ์ด๋ฏธ ๋ต๋ณ๋ ๊ฒ์ ๋ฌป๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ค์ ์ผ์ด์ค๋ ์์ง ์ง์ํ์ง ์๋ ๊ฒ์ผ๋ก ์ ํํ ์ดํดํ๊ณ ์์ต๋๊น? ์๋๋ฉด, ๋ด๊ฐ ์ฌ๋ฐ๋ฅธ ๋ฐฉ์์ด ์๋ ์ผ์ ํ๊ณ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. import x from 'x'
์๋ํ๋ ๊ฒ์ฒ๋ผ ๊ฒฝํํ์ง๋ง import { sub } from 'x'
๋ ์๋ํ์ง ์์ต๋๋ค.
ํจํค์ง.json:
{
"name": "jest-uuid",
"version": "1.0.0",
"type": "module",
"scripts": {
"test": "node --experimental-vm-modules node_modules/.bin/jest"
},
"devDependencies": {
"jest": "26.5.2"
},
"dependencies": {
"uuid": "8.3.1"
}
}
f.spec.js
import { v4 } from 'uuid';
test('', () => {});
npm ํ ์คํธ
> npm test
> [email protected] test /Users/igoro/p/tmp/jest-uuid
> node --experimental-vm-modules node_modules/.bin/jest
FAIL ./f.spec.js
โ Test suite failed to run
SyntaxError: The requested module 'uuid' does not provide an export named 'v4'
at jasmine2 (node_modules/jest-jasmine2/build/index.js:228:5)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.879 s
Ran all test suites.
(node:94492) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
npm ERR! Test failed. See above for more details.
#9771์ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค. ๊ทธ ์ ์๋ Jest๊ฐ uuid
๋ฅผ ESM์ผ๋ก ๋ก๋ํ๋ ๊ฒ์ด ์์ ํ๋ค๋ ๊ฒ์ ์์ง ๋ชปํฉ๋๋ค.
์ด๊ฒ์ CJS๊ฐ ๋ค์์คํ์ด์ค๋ก๋ง ๋ก๋๋ ์ ์๋ Node์ ๊ณ ์ ํ ๊ท์น์ ๋ฐ๋ฅผ ๊ฒ์
๋๊น, ์๋๋ฉด ์ค์ ๋ก Node ์์ฒด์์ ์๋ํ์ง ์๋ ๊ตฌ๋ฌธ์ ํ์ฉํ์ฌ ์ด๋ฅผ "๊ฐ์ "ํ ๊ฒ์
๋๊น? (์๋ฅผ ๋ค์ด, ๋
ธ๋๋ ํ์ฉํ์ง ์์ต๋๋ค import { readdirSync } from "fs-extra"
๊ทธ๊ฐ CJS ํจํค์ง์ด๊ธฐ ๋๋ฌธ์,ํ์ง๋ง ํ์ฉํ์ง import fs from "fs-extra";
๋ค์ ์ฌ์ฉํ์ฌ ์์ถ ํด์ ํ ์ ์์ต๋๋ค const { readdirSync } = fs
).
(์: ๋ ธ๋๋ CJS ํจํค์ง์ด๊ธฐ ๋๋ฌธ์ "child_process"์์ import { spawn }์ ํ์ฉํ์ง ์์ง๋ง "child_process"์์ import child_process๋ฅผ ํ์ฉํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ const { spawn } = child_process;๋ฅผ ์ฌ์ฉํ์ฌ ์์ถ์ ํ ์ ์์ต๋๋ค.)
์ด๊ฒ์ ๋ ธ๋๊ฐ "child_process"๋ฅผ "๊ธฐ๋ณธ ์ ๊ณต"(CJS๊ฐ ์๋) ๋ชจ๋๋ก ๊ฐ์ฃผํ๋ฏ๋ก ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์๋ํ๊ธฐ ๋๋ฌธ์ ๋ถํํ ์์ ๋๋ค. ์ต์ nodejs๋ ๋ํ ํด๋ฆฌ์คํฑ์ ์ฌ์ฉํ์ฌ CJS ๋ชจ๋์ ๋ํด ๋ง์ ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์๋ํ๋๋ก ํฉ๋๋ค. ๊ฐ์ฅ ํ๋ด๋ด๊ธฐ ํ๋ ๋ถ๋ถ์ผ ๊ฒ์ ๋๋ค.
๋์ fs-extra
๋ฅผ ์ฌ์ฉํ๋๋ก ์์ ๊ฐ ์
๋ฐ์ดํธ๋์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ช
๋ช
๋ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์ด ๋๋ ๋ค์ ๋ฉ์ด์ ๋ฅผ ์ฐฉ๋ฅํ๊ธฐ ์ํ Node์ ๋ก๋๋งต์ ์๋ค๋ฉด Jest๊ฐ ์ ์ ํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์
๋๋ค.
์ด๋ฏธ ๊ตฌํ๋์ด ์์ด์ผ ํฉ๋๋ค. ๋ ธ๋ ์ฝ์ด ๋ชจ๋์ ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ๋ ธ์ถํ์ง๋ง "์ผ๋ฐ" CJS๋ โโ๊ทธ๋ ์ง ์์ต๋๋ค.
์ต์ nodejs๋ ๋ํ ํด๋ฆฌ์คํฑ์ ์ฌ์ฉํ์ฌ CJS ๋ชจ๋์ ๋ํด ๋ง์ ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์๋ํ๋๋ก ํฉ๋๋ค. ๊ฐ์ฅ ํ๋ด๋ด๊ธฐ ํ๋ ๋ถ๋ถ์ผ ๊ฒ์ ๋๋ค.
๊ทธ๊ฒ์ ๊ตฌํํ๋ PR์ ๋ํ ๋งํฌ๊ฐ ์์ต๋๊น? ์ฐ๋ฆฌ๋ ์ ์ด๋ ๊ทธ๊ฒ์ ๋ชจ๋ฐฉํ๋ ค๊ณ ๋ ธ๋ ฅํด์ผํฉ๋๋ค ๐
PR์ ์ฌ๊ธฐ: https://github.com/nodejs/node/pull/35249
๊ทธ ๋ฐฐํ์ ํด๋ฆฌ์คํฑ์ cjs-module-lexer
(https://github.com/guybedford/cjs-module-lexer)๋ก ๊ฒ์ ๋์ง๋ง
๋ฐฉ๊ธ ์ด๊ฒ์ ๋ณด์๊ณ fs-extra
๊ฐ ๋ค์๊ณผ ๊ฐ์ ๋ด๋ณด๋ด๊ธฐ ํจํด์ ์ฌ์ฉํ๋ ๊ฒ์ฒ๋ผ ๋ณด์
๋๋ค.
module.exports = {
// Export promiseified graceful-fs:
...require('./fs'),
// Export extra methods:
...require('./copy-sync'),
...require('./copy'),
...require('./empty'),
...require('./ensure'),
...require('./json'),
...require('./mkdirs'),
...require('./move-sync'),
...require('./move'),
...require('./output'),
...require('./path-exists'),
...require('./remove')
}
์ด๊ฒ์ ํ์ฌ ์ฐ๋ฆฌ๊ฐ ๊ฐ์งํ ์ฌ์์ถ ๋ถ์ ์ฌ๋ก๊ฐ ์๋์ง๋ง ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ ๊ฐ์ง๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ ์ฉํ ๊ฒฝ์ฐ๋ผ๋ฉด cjs-module-lexer์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
@jkrems & @guybedford ๊ฐ์ฌํฉ๋๋ค! ์ด์ ํด๋น ๋ชจ๋์ ์ฌ์ฉํ์ฌ PR์ ์ด์์ต๋๋ค. #10673
https://github.com/facebook/jest/issues/9430#issuecomment -713204282์ ์ค๋ช ๋ ์ ํํ fs-extra ์ง์์ด ์ด์ [email protected] ์์ ๊ตฌํ๋๊ณ https://github ์์ ์ ์คํธ๋ฆผ ์ถ์ ์ด ์ด๋ฃจ์ด
_์ ๋ฐ์ดํธ: ์ด ๋น๋๋ฅผ ํ ์คํธํ๋ฉด ๋ชจ๋ fs-extra ํจ์๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ๊ฐ์งํ์ง๋ง ๋ถํํ๋ Node.js ๊ธฐ๋ณธ ํจ์๋ for ๋ฃจํ์ ์ํด ์ฑ์์ง๊ธฐ ๋๋ฌธ์ ์ ์ ์ผ๋ก ๋ถ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฐ์งํ์ง ๋ชปํฉ๋๋ค._
์์ : ๋ช ๋ช ๋ ESM ๊ฐ์ ธ์ค๊ธฐ #10673์ผ๋ก CJS์ ๋ช ๋ช ๋ ๋ด๋ณด๋ด๊ธฐ ์ง์
๋ค์ดํฐ๋ธ ESM์ CommonJS ๋ชจ๋์ exports
๋ฅผ default
๊ฐ์ ธ์ค๊ธฐ๋ง ์ง์ํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
@trusktr์ ๋ ์ด์ ์์ต๋๋ค: https://github.com/nodejs/node/pull/35249
์ฌ๋ณด์ธ์. ๋ ธ๋/์ ์คํธ์์ ESM ์ด๋ฉด์ ์ ์ฒด ์ด์ผ๊ธฐ๋ฅผ ๋น ๋ฅด๊ฒ ์์ฉํ๋ ๊ฒ์ ๋งค์ฐ ์ด๋ ต์ต๋๋ค. ๊ทธ๋์ ์๋ง๋ ๋ช ๋ฐฑํ๊ฑฐ๋ ์ด๋ฏธ ๋ต๋ณ๋ ๊ฒ์ ๋ฌป๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ค์ ์ผ์ด์ค๋ ์์ง ์ง์ํ์ง ์๋ ๊ฒ์ผ๋ก ์ ํํ ์ดํดํ๊ณ ์์ต๋๊น? ์๋๋ฉด, ๋ด๊ฐ ์ฌ๋ฐ๋ฅธ ๋ฐฉ์์ด ์๋ ์ผ์ ํ๊ณ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
import x from 'x'
์๋ํ๋ ๊ฒ์ฒ๋ผ ๊ฒฝํํ์ง๋งimport { sub } from 'x'
๋ ์๋ํ์ง ์์ต๋๋ค....
'uuid'์์ { v4 } ๊ฐ์ ธ์ค๊ธฐ;
ESM ๋ชจ๋์ ๊ตฌ๋ฌธ์ด ์ง์ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ๊ตฌ์กฐ ๋ถํด ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ง์ํ์ง ์์ต๋๋ค. ์ด๊ฒ์ด ์๋ํ๋ ค๋ฉด 'v4 ๋ด๋ณด๋ด๊ธฐ'๊ฐ ํ์ํฉ๋๋ค. '๋ด๋ณด๋ด๊ธฐ ๊ธฐ๋ณธ๊ฐ'์ด ์ผ์นํ์ง ์์ต๋๋ค.
https://kentcdodds.com/blog/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution
@sdwlig uuid
๋ ๋ช
๋ช
๋ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ์ ๊ณตํ๋ฉฐ ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ๊ฐ ์์ต๋๋ค. ์๋ํด์ผ ํ์ง๋ง "๋ด๋ณด๋ด๊ธฐ" ํ๋๊ฐ ์๋ ํจํค์ง์์ esm์ ๋ก๋ํ๋ ๊ฒ์ ์์ง jest์์ ์ง์๋์ง ์์ต๋๋ค. ๋์ ๊ธฐ๋ณธ ๋ด๋ณด๋ด๊ธฐ๋ฅผ ํตํด์๋ง ์ฌ์ฉํ ์ ์๋ Commonjs๊ฐ ๋ก๋๋ฉ๋๋ค.
https://github.com/uuidjs/uuid/blob/master/src/index.js
์ฌ๊ธฐ์ ํจํค์ง ์์ฒด ์ฐธ์กฐ ์ง์(#10883)์ ์ถ๊ฐํ ์ ์์ต๋๊น?
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
#9772๋ก ๋งค์ฐ ๊ธฐ๋ณธ์ ์ธ ์ง์์ ๋ฐ์์ต๋๋ค. ๊ฐ์ฅ ๋จ์ํ ๊ฒฝ์ฐ๋ง ํ ์คํธํ์ผ๋ฉฐ ์๋ ค์ง ์ ํ ์ฌํญ์ด ๋ง์ด ์์ต๋๋ค(ํนํ CJS์ ESM์ ํผํฉํ ๋
jest
๊ฐ์ฒด ์ง์ ๋ฐ ๊นจ์ง ์๋ฏธ ์ฒด๊ณ ์์). ๊ทธ๋ฌ๋ ์ ์ด๋ _๋ฌด์ธ๊ฐ_์ ๋๋ค. Jest์ ๋ค์ ๋ฆด๋ฆฌ์ค์์ ๋์ฌ ์์ ์ ๋๋ค(๊ณง #9806์ผ๋ก ์ฐจ๋จ๋จ)