SyntaxError: Cannot use import statement outside a module
Monorepo ๊ตฌ์กฐ์ ํ๋ก์ ํธ์์ Jest๋ฅผ ๋์ ํ๋ ์ด๊ธฐ ๊ณผ์ ์์ ์ด๋ฐ ์๋ฌ๊ฐ ๋ฌ๋ค.
์ด๋ ๊ฒ import ํ ๋๋ถํฐ ์๋ฌ๊ฐ ๋๋ค๋ฉด Babel์ด ํธ๋์คํ์ผ๋ง์ ๋ชปํ๊ณ ์๋ ๊ฒ์ด๋ค. ๊ทธ๋ฐ๋ฐ Webpack ์๋ฒ๋ฅผ ์คํํ๊ฑฐ๋ ๋น๋ํ ๋ ๋ฌธ์ ๊ฐ ์์๋๋ฐ ์ Jest๋ฅผ ์คํํ ๋ ์ด๋ฐ ์๋ฌ๊ฐ ๋๋ ๊ฑธ๊น? ๋จผ์ Monorepo์์์ Babel ์ค์ ์ ๋ํด ์ดํดํ ํ์๊ฐ ์๋ค.
Monorepo์์ Babel ์ค์ ํ๊ธฐ
Monorepo์์๋ ๋ ํ์งํ ๋ฆฌ์ ๋ฃจํธ์ babel.config.json
ํ์ผ์ ์์ฑํด์ ํต์ฌ ์ค์ ์ ์ง์ ํด์ผ ํ๋ค. .babelrc.json
ํ์ผ์ ํตํด ๊ฐ ํ์ ํจํค์ง์์ ๊ฐ๋ณ ์ค์ ์ ํ ์๋ ์์ง๋ง, ์ด ๋๋ ๋ฃจํธ ๋ ๋ฒจ์ ์ต์
์ ๋จผ์ ์ค์ ํ๋ค overrides
์ต์
์ ์ฌ์ฉํด ์ค๋ฒ๋ผ์ด๋ํ๋ ๊ฒ์ด ์ข๋ค. Babel 7๋ถํฐ ์ด๋ฐ ๋ฃจํธ ๋๋ ํฐ๋ฆฌ์ ๊ฐ๋
์ด ์ฌ์ฉ๋๊ณ ์์ผ๋ฉฐ, Babel์ ์ด ๋ฃจํธ ๋๋ ํฐ๋ฆฌ์์ babel.config.json
ํ์ผ(.js
, .cjs
, .mjs
ํ์ฅ์ ์ง์)์ ์๋์ผ๋ก ๊ฒ์ํด ์ ์ฉํ๋ค.
์ฌ๊ธฐ์ ์ฃผ์ํด์ผ ํ ์ ์ Monorepo์์์ Babel์ ๋ ํ์งํ ๋ฆฌ์ ๋ฃจํธ๊ฐ ์๋, Babel์ด ์คํ๋๋ ์์
๋๋ ํฐ๋ฆฌ๋ฅผ ๋
ผ๋ฆฌ์ ์ธ ๋ฃจํธ๋ก์ ์ทจ๊ธํ๋ค๋ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ ํ์ ํจํค์ง์์ Babel ํ๋ก์ธ์ค๋ฅผ ์คํํ๋ ค๋ ๊ฒฝ์ฐ, ํด๋น ํจํค์ง๊ฐ ๋ฃจํธ๋ก ์ทจ๊ธ๋์ด ๋ ํ์งํ ๋ฆฌ์ ๋ฃจํธ๊ฐ ์๋ ํจํค์ง ๋ด์์ babel.config.json
ํ์ผ์ ์ฐพ๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ SyntaxError๊ฐ ๋ฐ์ํ ์ ์๋ค.
์ด ๋๋ Babel์๊ฒ ์ด๋์ ์ค์ ํ์ผ์ ์ฐพ์์ผํ๋์ง ์๋ ค์ค์ผ ํ๋ค. ๊ณต์๋ฌธ์์์ ์ถ์ฒํ๋ ๋ฐฉ๋ฒ์ rootMode
์ต์
์ upward
๋ก ์ค์ ํ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฉด Babel์ด ์์
๋๋ ํฐ๋ฆฌ์์๋ถํฐ ๋ ํ์งํ ๋ฆฌ ๋ฃจํธ ๋ฐฉํฅ์ผ๋ก babel.config.json
ํ์ผ์ ์ฐพ๊ณ , ํ์ผ์ ์ฐพ์ ๊ทธ ์์น๋ฅผ root ๊ฐ์ผ๋ก ์ฌ์ฉํ๊ฒ ๋๋ค.
Webpack์์ Babel Config ํ์ผ ๋ถ๋ฆฌํ๊ธฐ
๋ด Monorepo์ ๊ตฌ์กฐ๋ ์๋์ ๊ฐ๋ค. ๋ฒ๋ค๋ฌ๋ก ์ฌ์ฉํ๊ณ ์๋ Webpack์ ๊ณตํต ์ค์ ์ ๋ ํ์งํ ๋ฆฌ ๋ฃจํธ์ webpack.base.js
์ ์ ์ํ๊ณ ,
๊ฐ ํ์ ํจํค์ง์ webpack.config.js
์์ ๋จธ์งํ ๋ค ํจํค์ง๋ง๋ค ๋
๋ฆฝ์ ์ผ๋ก Webpack ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ค.
webpack.base.js
packages/
app1/
src/index.js
webpack.config.js
package.json
app2/
src/index.js
webpack.config.js
package.json
์ด ๋ Babel ์ค์ ์ ๋ฐ๋ก ๋ถ๋ฆฌํ์ง ์๊ณ Webpack์ ์ค์ ์ ํจ๊ป ์ ์๋ฅผ ํ์๋๋ฐ Jest๊ฐ ์ด ๋๋ฌธ์ Babel ์ค์ ์ ์ ๋๋ก ์ฐพ์ง ๋ชปํ๋ค๋ ์์ฌ์ด ๋ค์๋ค. ๊ทธ๋์ Webpack ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ๋ ๋ฌธ์ ๊ฐ ์์์ง๋ง Jest ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ๋ ๋ฌธ์ ๊ฐ ๋๋ ๊ฒ ์๋๊น ์๊ฐํ๋ค. ๋ฐ๋ผ์ Babel ์ค์ ์ ๋ณ๋์ babel.config.js
ํ์ผ๋ก ๋ถ๋ฆฌํ๊ธฐ๋ก ํ๋ค.
์ด๋ ๊ฒ babel-loader
์ options ํ๋กํผํฐ์ ์ ์ํ๋ Babel ์ค์ ์
// webpack.base.js
module: {
rules: [
{
test: /\.[jt]sx?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: [ ... ],
plugins: [ ... ],
},
},
],
},
]
}
์๋์ฒ๋ผ ๋ถ๋ฆฌํด์คฌ๋ค. ์ด ๋ ์ฝ๋์์์ development mode์ผ ๋ ๋ณ๋ ์ฒ๋ฆฌ๊ฐ ํ์ํด์ .json
์ด ์๋๋ผ.js
ํ์ผ๋ก ์์ฑํ๋ค.
// babel.config.js
const isDevelopment = process.env.NODE_ENV === 'development'
const config = (api) => {
api.cache(true)
const presets = [ ... ]
const plugins = [
'some plugin',
isDevelopment && 'other plugin',
].filter(Boolean)
return {
presets,
plugins,
}
}
module.exports = config
๊ทธ๋ฐ ๋ค Webpack์ babel-loader
์๊ฒ ๋ฃจํธ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ ํ์งํ ๋ฆฌ ๋ฃจํธ๋ก ๋ณ๊ฒฝํ๋ผ๊ณ ์๋ ค์ฃผ๋ฉด ๋๋ค.
// webpack.base.js
module: {
rules: [
{
test: /\.[jt]sx?$/,
use: [
{
loader: 'babel-loader',
options: {
rootMode: 'upward', // ์ด ์ต์
์ด ์์ผ๋ฉด ๋ฃจํธ์ babel.config.js ํ์ผ์ ์ฐพ์ง ๋ชปํ๋ค
},
},
],
},
]
}
๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ ๋์ด ์๋๋ค! Jest๋ babel์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํ ์คํธ๋ฅผ ์คํํ๋ ์์น์ ๋ฐ๋ผ์ ๋ณ๋์ ์ค์ ์ด ํ์ํ ์ ์๋ค. ๋ ์ด ๋ถ๋ถ์์ ์ฝ์ง์ ๊ฒ๋ ํ๋ค.
Jest๋ babel-jest๋ฅผ ์ฌ์ฉํด ํธ๋์คํ์ผ๋งํ๋ค
Jest๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์ฝ๋๋ฅผ ์คํํ๊ธฐ ๋๋ฌธ์ JSX, TypeScript์ ๊ฐ์ ์ฝ๋๋ JS๋ก ํธ๋์คํ์ผ๋ง์ด ํ์ํ๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก jest
๋ฅผ ์ค์นํ๋ฉด babel-jest
๊ฐ ์ค์น๋๋ฉฐ, ์๋์ ์ผ๋ก ์ด๋ฅผ transformer๋ก ์ฌ์ฉํด ํ๋ก์ ํธ์ ์กด์ฌํ๋ Babel ์ค์ ์ ์ฐพ์ .js
, .jsx
, .ts
, .tsx
ํ์ผ์ ํธ๋์คํ์ผ๋งํ๋ค.
๋ฐ๋ผ์ Jest ์ค์ ์ transform
์ต์
์ ๊ธฐ๋ณธ๊ฐ์ {"\\.[jt]sx?$": "babel-jest"}
์ด๋ฉฐ transformer์ ๋ณ๋์ ์ต์
์ด ํ์ํ๋ค๋ฉด {"\\.[jt]sx?$": ["babel-jest", {options}]}
์ ๊ฐ์ด ํํ ํํ๋ก ๋ ๋ฒ์งธ ์ธ์์ ์ต์
์ ์ค์ ํ ์ ์๋ค.
โญ๏ธ babel-jest์ rootMode ์ต์
Jest๋ฅผ Monorepo์ ๋ฃจํธ์ ์ค์นํ๊ณ ์คํํ๋ฉด ๋ณ๋์ ์ค์ ์์ด๋ ์ ๋ ๊ฑฐ๋ผ๊ณ ํ๋ค. ํ์ง๋ง ๋์ฒ๋ผ ํ์ ํจํค์ง์ Jest๋ฅผ ์ค์นํ๊ณ ์คํํ๋ ๊ฒฝ์ฐ์๋ babel-loader
์๊ฒ rootMode
์ต์
์ ์ค์ ํด์คฌ๋ ๊ฒ์ฒ๋ผ babel-jest
ํํ
๋ ๋์ผํ ์ต์
์ ์ค์ ํด์ค์ผ ํ๋ค!
babel.config.json
webpack.base.js
packages/
app1/
src/index.js
jest.config.js #app1 ํจํค์ง์์๋ง jest๋ฅผ ์ค์นํ๊ณ ์คํํ๋ ๊ตฌ์กฐ
webpack.base.js
package.json
์๋๋ฉด ํ์ ํจํค์ง์์ babel-jest
๋ก ์ธํด Babel ํ๋ก์ธ์ค๊ฐ ์คํ๋ ๊ฑฐ๊ณ , Babel ํน์ฑ์ ๋ ํ์งํ ๋ฆฌ ๋ฃจํธ๊ฐ ์๋ ํด๋น ํจํค์ง๋ฅผ ๋ฃจํธ๋ก ์ทจ๊ธํ๊ณ babel.config.json
์ ์ฐพ์ผ๋ ค๊ณ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋์ babel-jest
์๊ฒ๋ ์ค์ ํ์ผ์ ์ฐพ์์ผํ๋ ์์น๋ฅผ ์๋ ค์ค์ผ ํ๋ค! ์์ง ๋ง์!!
// jest.config.js
transform: {
'^.+\\.[jt]sx?$': ['babel-jest', { rootMode: 'upward' }],
},
'๐ป๐ > ๊ฐ๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JS] ๊ณ ์ฐจ ํจ์(Higher-Order Function) (0) | 2022.07.31 |
---|---|
[Monorepo] ์ฌ๋ฌ ํจํค์ง์์ React Context Instance ๊ณต์ ํ๊ธฐ(feat. Module Federation) (1) | 2022.07.31 |
highcharts์ y-axis label์ ์ฒ ๋จ์ ์ฝค๋ง ์ถ๊ฐํ๊ธฐ(in React) (0) | 2022.01.05 |
[JS] JavaScript์์ CSS ๋ณ์ ๊ฐ ์ฌ์ฉํ๊ธฐ (0) | 2021.10.24 |
ํด๋ฆฌํ(Polyfill)์ด๋ (0) | 2021.09.26 |