μ¬λ μ μ€νΈ? μ°λ¦¬ μ§λ¨ μ§μμ κ³ λ €νμμμ€: π https://opencollective.com/jest/donate
React μ±μμ Jestλ‘ ν
μ€νΈλ₯Ό μ€ννλ €κ³ νλ©΄ Jest encountered an unexpected token
μ€λ₯κ° λ°μν©λλ€. Link
κ΅¬μ± μμλ₯Ό 볡μ¬νκ³ here μμ μ§μ ν
μ€νΈ
FAIL src/components/Link.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:
SyntaxError: C:\workspace\react\testapp\src\components\Link.test.js: Unexpected token (8:4)
6 | test('Link changes the class when hovered', () => {
7 | const component = renderer.create(
> 8 | <Link page="http://www.facebook.com">Facebook</Link>,
| ^
9 | );
10 | let tree = component.toJSON();
11 | expect(tree).toMatchSnapshot();
at Parser.raise (node_modules/@babel/parser/lib/index.js:3938:15)
at Parser.unexpected (node_modules/@babel/parser/lib/index.js:5247:16)
at Parser.parseExprAtom (node_modules/@babel/parser/lib/index.js:6327:20)
at Parser.parseExprSubscripts (node_modules/@babel/parser/lib/index.js:5923:21)
at Parser.parseMaybeUnary (node_modules/@babel/parser/lib/index.js:5902:21)
at Parser.parseExprOps (node_modules/@babel/parser/lib/index.js:5811:21)
at Parser.parseMaybeConditional (node_modules/@babel/parser/lib/index.js:5783:21)
at Parser.parseMaybeAssign (node_modules/@babel/parser/lib/index.js:5730:21)
at Parser.parseExprListItem (node_modules/@babel/parser/lib/index.js:6994:18)
at Parser.parseCallExpressionArguments (node_modules/@babel/parser/lib/index.js:6123:22)
μ¬κΈ° λ΄ package.json
{
"name": "testapp",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --config ./config/webpack.config.development.js",
"build": "webpack -p --config ./config/webpack.config.production.js",
"test": "jest"
},
"dependencies": {
"axios": "^0.18.0",
"moment": "^2.22.2",
"polished": "^2.0.3",
"prop-types": "^15.6.2",
"react": "^16.4.2",
"react-delay-render": "^0.1.2",
"react-dom": "^16.4.2",
"react-imported-component": "^4.6.2",
"react-router-dom": "^4.3.1",
"simple-grid": "^1.0.1",
"styled-components": "^3.4.5",
"uuid": "^3.3.2",
"validator": "^10.7.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^23.4.2",
"babel-loader": "^8.0.0",
"babel-plugin-styled-components": "^1.6.0",
"css-loader": "^1.0.0",
"html-webpack-plugin": "^3.2.0",
"jest": "^23.5.0",
"mini-css-extract-plugin": "^0.4.2",
"react-test-renderer": "^16.4.2",
"regenerator-runtime": "^0.12.1",
"style-loader": "^0.23.0",
"webpack": "^4.17.1",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.7"
}
}
μ¬κΈ° λ΄ .babelrc
νμΌμ΄ μμ΅λλ€(λ£¨νΈ λλ ν 리μ μμ).
{
"plugins": [
"@babel/plugin-proposal-class-properties",
"babel-plugin-styled-components",
"@babel/plugin-syntax-dynamic-import"
],
"presets": ["@babel/preset-env", "@babel/preset-react"],
"env": {
"development": {
"plugins": [
"@babel/plugin-proposal-class-properties",
["babel-plugin-styled-components", { "displayName": true }],
"@babel/plugin-syntax-dynamic-import"
],
"presets": ["@babel/preset-env", "@babel/preset-react"]
},
"test": {
"plugins": [
"@babel/plugin-proposal-class-properties",
["babel-plugin-styled-components", { "displayName": true }],
"@babel/plugin-syntax-dynamic-import"
],
"presets": ["@babel/preset-env", "@babel/preset-react"]
},
"production": {
"plugins": [
"@babel/plugin-proposal-class-properties",
"babel-plugin-styled-components",
"@babel/plugin-syntax-dynamic-import"
],
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
}
}
λμμ μ¬ννλ λ¨κ³:
yarn add --dev babel-jest babel-core@^7.0.0-0 @babel/core
Jest μ€μΉyarn test
npx envinfo --preset jest
μ¬κΈ°μ κ²°κ³Όλ₯Ό λΆμ¬λ£μ΅λλ€.
OS: Windows 10
CPU: x64 Intel(R) Xeon(R) CPU E3-1505M v6 @ 3.00GHz
Binaries:
Yarn: 1.5.1 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 5.6.0 - C:\Program Files\nodejs\npm.CMD
λλ κ°μ λ¬Έμ κ° μμ΅λλ€.
λμΌν λ¬Έμ κ° μμ΅λλ€.
λμΌν λ¬Έμ κ° μ¬κΈ°μ μμ΅λλ€. monorepoλ‘ μμ ν λ μ½κ° λ 볡μ‘ν©λλ€.
@fabioSalimbeni @hoaiduyit @mikedloss λ΄ React λ° React Native ν
μ€νΈ( Jest
λ° enzyme
)λ₯Ό Babel 7μ μ¬μ©νμ¬ Lerna λͺ¨λ
Έλ ν¬μμ ν΅κ³ΌμμΌ°μ΅λλ€.
λͺ¨λ
Έλ ν¬μμ μμ
νλ κ²½μ° babel.config.js
μ ν¨κ» μ Babel ꡬμ±μ μ¬μ©ν΄μΌ ν©λλ€: https://babeljs.io/docs/en/v7-migration.
μ΄κ²μ monorepoμ 루νΈμ λν λ΄ babel.config.js
μ
λλ€.
module.exports = {
overrides: [
{
test: 'platforms/webApp1',
extends: 'platforms/webApp1/babel.config.js'
},
{
test: 'platforms/webApp2',
extends: 'platforms/webApp2/babel.config.js'
}
]
};
μ΄κ²μ΄ webApp1
λν λ΄ babel.config.js
λͺ¨μ΅μ
λλ€. monorepo μ± μ€ νλ:
module.exports = {
env: {
test: {
presets: [
[
'@babel/preset-env',
{
modules: 'commonjs',
debug: false
}
],
'@babel/preset-flow',
'@babel/preset-react'
],
plugins: [
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-proposal-class-properties'
]
},
production: {
presets: [
['@babel/preset-env', { modules: false }],
'@babel/preset-flow',
'@babel/preset-react'
],
plugins: [
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-proposal-class-properties'
]
},
development: {
presets: [
['@babel/preset-env', { modules: false }],
'@babel/preset-flow',
'@babel/preset-react'
],
plugins: [
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-proposal-class-properties'
]
}
}
};
κ·Έλ¦¬κ³ μ΄κ²μ Jest ꡬμ±μ λλ€.
"jest": {
"verbose": true,
"clearMocks": true,
"collectCoverage": true,
"setupTestFrameworkScriptFile": "<rootDir>/config/setupTest.js",
"transform": {
"^.+\\.js$": "babel-jest"
},
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|scss)$": "<rootDir>/__mocks__/styleMock.js"
}
}
setupTest.js
λ λ€μκ³Ό κ°μ΅λλ€.
const Enzyme = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');
Enzyme.configure({ adapter: new Adapter() });
fileMocks.js
λ λ€μκ³Ό κ°μ΅λλ€.
module.exports = 'i-am-a-stubbed-file';
styleMocks.js
λ λ€μκ³Ό κ°μ΅λλ€.
module.exports = {};
λν μΌλΆ Babel νλ¬κ·ΈμΈκ³Ό babel-core
λ²μ μ κ° μ±μ package.json
μ devDependencies
λ‘ μΆκ°ν΄μΌ ν©λλ€.
...
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "^9.0.0",
"babel-jest": "^23.4.2",
"babel-loader": "^8.0.2",
...
"jest": "^23.5.0",
"jest-cli": "^23.5.0",
...
3μΌ νμ μ΄ λ¬Έμ μ λν ν΄κ²°μ±
μ μ°Ύμμ΅λλ€.
μ΄λ₯Ό μν 2κ°μ§ μ루μ
μ΄ μμ΅λλ€.
νμΌ μ΄λ¦μ .babelrc
μμ babel.config.js
λ³κ²½ν μ μμ΅λλ€. μ΄λ κ² νλ©΄ λ©λλ€.
## μ루μ
2:
μ΄ λ°©λ²μ μ¬μ©νκ³ μμ΅λλ€.
λ€μκ³Ό κ°μ λ³ν νμΌμ λ§λλλ€(λ΄ νμΌμ jest-transforme.js
μ).
const config = {
babelrc: false,
presets: [
[
"@babel/env",
{
modules: false
}
],
"@babel/react"
],
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-proposal-class-properties", { loose: true }],
"transform-es2015-modules-commonjs"
]
};
module.exports = require("babel-jest").createTransformer(config);
λ΄ jest.config.js
λ€μκ³Ό κ°μ΅λλ€.
module.exports = {
collectCoverageFrom: ["src/**/*.{js,jsx,mjs}"],
testMatch: ["<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}", "<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"],
transform: {
"^.+\\.(js|jsx|mjs)$": "<rootDir>/config/jest/jest-transformer.js"
},
transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"]
};
κ·Έλ¦¬κ³ μμ§ λ΄ .babelrc
```
const νκ²½ = require("./env-config.js");
module.exports = {
μ¬μ μ€μ : [
[
"λ€μ/λ°λ²¨",
{
"μ¬μ μ€μ νκ²½": {
useBuiltIns: "νλͺ©"
}
}
]
],
νλ¬κ·ΈμΈ: [
["μ€νμΌ κ΅¬μ± μμ", { ssr: true, displayName: true, μ μ²λ¦¬: false }],
[
"λͺ¨λ ν΄κ²°μ¬",
{
루νΈ: ["./"]
}
]
],
νκ²½: {
κ°λ°μ: {
νλ¬κ·ΈμΈ: [
["λ³ν μ μ", νκ²½],
["λͺ¨λ ν΄μκΈ°", { 루νΈ: ["./"] }],
"λ³ν-λ°μ½λ μ΄ν°-λ κ±°μ",
"λ³ν ν΄λμ€ μμ±"
]
},
μ§λ€: {
νλ¬κ·ΈμΈ: [
["λ³ν μ μ", νκ²½],
["λͺ¨λ ν΄μκΈ°", { 루νΈ: ["./"] }],
"λ³ν-λ°μ½λ μ΄ν°-λ κ±°μ",
"λ³ν ν΄λμ€ μμ±"
]
},
μμ°: {
μ¬μ μ€μ : [
[
"minify", // μ μ¬κΈ°μ minifyλ₯Ό μΆκ°ν©λκΉ? μ 체 μ½λ λ²λ€μ λν΄ uglifyλ₯Ό μ€νν©λλ€.
{
λ§ΉκΈ: κ±°μ§,
νκ°: κ±°μ§
}
]
],
νλ¬κ·ΈμΈ: [
["λ³ν μ μ", νκ²½],
["@babel/plugin-proposal-decorators", { λ κ±°μ: true }],
["@babel/plugin-proposal-class-properties", { λμ¨ν: true }],
["λͺ¨λ ν΄μκΈ°", { 루νΈ: ["./"] }]
],
λκΈ: κ±°μ§,
μ»΄ν©νΈ: μ¬μ€,
μΆμ: μ¬μ€
}
}
};
````
μ΄κ²μ΄ μ¬λ¬λΆμ΄ μ΄ λ¬Έμ λ₯Ό ν΅κ³Όν μ μκΈ°λ₯Ό λ°λλλ€. ννΈ.
@GeorgianSorinMaxim λ¬Έμ λ λ΄ λλ΄ μμ© νλ‘κ·Έλ¨ λ¬΄μμ
λλ€ .babelrc
νμΌμ, κ·Έλ¦¬κ³ λ‘ λ³κ²½ babel.config.js
λ¬Έμ λ₯Ό ν΄κ²°νμ§λ§, μ΄μ¨λ κ·Έκ²μ ν΄κ²°, λ΄ λλ΅μ΄ λκΈμ μ΄μμ
λλ€.
@GeorgianSorinMaxim @hoaiduyit λλΆμ κ²°κ΅ babel-
Babel 7μ΄ μ λλ‘ μλνλ €λ©΄ babel.config.js
κ° νμν κ² κ°μ΅λλ€. babelrc λμ μ¬μ©νμμμ€.
babel-jest
μ¬μ ν Babel 6μ babel-core
μμ‘΄ν©λλ€. Babel 7 μ μ¬μ©νλ €λ©΄ μ¬μ©ν μ μμ΅λλ€.
μ΄ λ³μκΈ° babel7-jest
babel-jest
λ babel 7μμ μ μλνλ©° μ¬μ©μ μ μ λ³νκΈ°κ° νμνμ§ μμ΅λλ€.
@SimenB λ΄ .babelrc
μ babel.config.js
νμ§λ§ μ¬μ ν μκΈ°μΉ μμ ν ν°κ³Ό ν¨κ» ν΄λΉ μ€λ₯κ° νμλ©λλ€. νμ§λ§ babel7-pre.42μ ν¨κ» μλν©λλ€. λ€λ₯Έ μΌλ°μ μΌλ‘ λμΉλ κ²λ€μ΄ μμ΅λκΉ? :) κ°μ¬ ν΄μ.
@alexindigo babel.config.js
μ°λ λ°©λ²μ νμΈνμΈμ
μ, yarn upgrade --latest
μ€ννλ©΄ λ¬Έμ κ° ν΄κ²°λμμ΅λλ€. :)
@alexindigo @hoaiduyit babel.config.js
λν΄ μ΄λ»κ² μμ λ λμ? κ°μ λ¬Έμ μ μ¨λ¦νκ³ λΉμ μ ν΄κ²°μ±
μ μ°Ύλ λμ, λλ μμΌλ‘ μκ°νκ³ μμμ΅λλ€... _"ν , μ΄κ²μ΄ μλν λ°©λ²μ μμ§λ§ μ΄μ¨λ μλν κ²μ
λλ€."_ νμ§λ§ μΆ©λΆν lulzνμ΅λλ€. κ°μ¬ ν΄μ
Jest λ° ν¨μ κ΅¬μ± : package.jsonμ λ€μ μ½λ μΆκ°
"jest": {
"testEnvironment": "jsdom",
"moduleDirectories": [
"src",
"node_modules"
],
"moduleNameMapper": {
"\\.(css|scss)$": "<rootDir>/__mocks__/styleMock.js",
"\\.(jpg|gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
},
"transform": {
"^.+\\.(js|jsx)$": "babel-jest",
".+\\.(css|styl|less|sass|scss)$": "<rootDir>/node_modules/jest-css-modules-transform"
},
"setupTestFrameworkScriptFile": "<rootDir>/setupTests.js",
"setupFiles": [
"<rootDir>setup.js"
],
"moduleFileExtensions": [
"css",
"scss",
"js",
"json",
"jsx"
],
"testRegex": "\/test\/spec\/.*\\.js$",
"transformIgnorePatterns": [
"/node_modules/(?!test-component).+\\.js$"
]
}
Enzyme => setup.js μ€μ μ©
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
setupTestFrameworkScriptFileμ κ²½μ°: setupTests.js global.fetch = require('jest-fetch-mock')
const { JSDOM } = require('jsdom')
const jsdom = new JSDOM('<!doctype html><html><body></body></html>')
const { window } = jsdom
const exposedProperties = ['window', 'navigator', 'document']
const { document } = new JSDOM('').window
global.document = document
global.window = document.defaultView
global.HTMLElement = window.HTMLElement
global.HTMLAnchorElement = window.HTMLAnchorElement
Object.keys(document.defaultView).forEach(property => {
if (typeof global[property] === 'undefined') {
exposedProperties.push(property)
global[property] = document.defaultView[property]
}
})
global.navigator = {
userAgent: 'node.js',
}
.tsx νμΌλ§ λμΌν λ¬Έμ μ μ§λ©΄ν©λκΉ?
λ°©κΈ λ΄μ€λ₯Ό νΌλ¨λ¦¬λ©΄μ Jest v24λ λ΄λΆμ μΌλ‘ Babel 7μ μ¬μ©νλλ‘ μ
λ°μ΄νΈλμμ΅λλ€. babel bridge
λλ babel7-jest
νλ©΄ λ μ΄μ νμνμ§ μμ΅λλ€.
https://twitter.com/i/web/status/1088904207653105664
.babelrc
μ babel.config.js
λ‘ λ³κ²½νκ³ Babel7λ‘ μ
κ·Έλ μ΄λνλλ° μ¬μ ν μ΄μ κ³Ό λμΌν μ€λ₯κ° λ°μν©λλ€. λ΄ babel.config.js
νμΌ:
module.exports = function (api) {
api.cache(true);
const presets = ["@babel/preset-env"];
return {
presets
};
}
@babel/preset-react
νκ³ babel.config.js
νμΌμ μΆκ°νμ΅λλ€. μ€λ₯λ₯Ό μμ νμ΅λλ€.
λ΄ babel.config.js
νμΌμ __test__
λλ ν 리μ λ£μκΈ° λλ¬Έμ babel-jest
μν΄ κ°μ§λμ§ μμμ΅λλ€. package.json
κ° μλ μ΅μμ λλ ν λ¦¬λ‘ μ΄λνκ³ λͺ¨λ κ²μ΄ μλνμ΅λλ€.
λ€μμ μννμ¬ λΉμ·ν λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
1- ν¨μ μ€μ νμΌμ μΆκ°νκ³ λ€μμ μμ±νμμμ€.
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
2- λ€μκ³Ό κ°μ΄ package.jsonμ jest ꡬμ±μ μΆκ°ν©λλ€.
"jest": {
"setupFilesAfterEnv": [
"./path to your setup file/setupEnzyme.js"
]
}
3- λ£¨νΈ κ²½λ‘μ .babelrc νμΌμ μΆκ°νκ³ λ€μμ μμ±νμμμ€.
{
"env": {
"test": {
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
}
}
4 - λΉμ μ΄ μ€λ₯κ° λ°λ‘ μ€ν ν
μ€νΈμμ ν€μλλ₯Ό "κΈ°λ"κ°μ§κ³ μλ κ²½μ° npm install -D chai
μ κ°μ ν
μ€νΈ μ½λμμμ΄ κΈ°λ₯μ κΈ°λ μμ
import { expect } from 'chai';
μ¬μ ν μ€λ₯κ° λ°μνλ©΄ npm install -D @babel/core @babel/preset-env @babel/preset-react
μ κ°μ babel μ’
μμ±μ μ€μΉνμμμ€.
λμμ΄ λμκΈ°λ₯Ό λ°λλλ€.
3μΌ νμ μ΄ λ¬Έμ μ λν ν΄κ²°μ± μ μ°Ύμμ΅λλ€.
μ΄λ₯Ό μν 2κ°μ§ μ루μ μ΄ μμ΅λλ€.μ루μ 1:
νμΌ μ΄λ¦μ
.babelrc
μμbabel.config.js
λ³κ²½ν μ μμ΅λλ€. μ΄λ κ² νλ©΄ λ©λλ€.
μ λ .babelrc νμΌμ΄ μμκΈ° λλ¬Έμ κ·Έ λ°λλ‘ νλ κ²λ ν¨κ³Όκ° μλ€κ³ μκ°νκ³ λμ babel.config.jsμ μ¬μ μ€μ μ 보λ₯Ό μ¬μ©νμ¬ .babelrc νμΌμ λ§λ€μμ΅λλ€. (μΆκ° νμΌμ λ§λ€μκ³ μλ³Έ μ΄λ¦μ λ°κΎΈμ§ μμμ΅λλ€)
ν
μ€νΈλ₯Ό λ€μ μ€ννλ©΄ Requires Babel "^7.0.0-0", but was loaded with "6.26.3"
λΌλ μλ‘μ΄ μ€λ₯κ° λ°μνμ΅λλ€.
λλ κ·Έ μ€λ₯λ₯Ό ꡬκΈλ§νκ³ κ·Έκ²μ λλ₯Ό μ¬κΈ°λ‘ μ΄λμλ€. μ§μΉ¨( npm install [email protected]
)μ λ°λκ³ μ΄μ ν
μ€νΈκ° μ€νλκ³ ν΅κ³Όν©λλ€.
λ°©κΈ λ΄μ€λ₯Ό νΌλ¨λ¦¬λ©΄μ Jest v24λ λ΄λΆμ μΌλ‘ Babel 7μ μ¬μ©νλλ‘ μ λ°μ΄νΈλμμ΅λλ€.
babel bridge
λλbabel7-jest
νλ©΄ λ μ΄μ νμνμ§ μμ΅λλ€.
https://twitter.com/i/web/status/1088904207653105664
Jest v24λ‘ μ κ·Έλ μ΄λνλ©΄ μ΄ λ¬Έμ κ° ν΄κ²°λμμ΅λλ€. :)
unexpected token
μ€λ₯ λ°μ
> 10 | const browser;
(λμ μΈλ―Έμ½λ‘ )
λ΄ ν¨ν€μ§.json
"dependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.3.4",
"@babel/register": "^7.0.0",
"assert": "^1.4.1",
"chai": "^4.2.0",
"jest-puppeteer": "^4.0.0",
"screen-info": "^1.0.1",
"screenres": "^2.0.1"
},
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.2.0",
"@babel/preset-env": "^7.3.4",
"babel-jest": "^24.5.0",
"babel-preset-env": "^1.7.0",
"babel-preset-jest": "^24.3.0",
"jest": "^24.5.0",
"jest-cli": "^24.5.0",
"puppeteer": "^1.13.0"
},
"jest": {
"transformIgnorePatterns": [
"/node_modules/(?!@babel).+\\.js$"
],
"transform": {
"^.+\\.js?$": "babel-jest"
}
},
babel.config.js
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current'
},
},
'jest'
]
],
env: {
test: {
plugins: ['@babel/plugin-transform-modules-commonjs']
}
}
}
ν
μ€νΈλ hoaiduyit μ루μ
. μλν©λλ€. babel.config.jsλ₯Ό μΆκ°νκ³ jest.config.jsμ babel-jest
transform/transpile jestλ₯Ό μ€μΉνλ©΄ λ©λλ€.
3μΌ νμ μ΄ λ¬Έμ μ λν ν΄κ²°μ± μ μ°Ύμμ΅λλ€.
μ΄λ₯Ό μν 2κ°μ§ μ루μ μ΄ μμ΅λλ€.μ루μ 1:
νμΌ μ΄λ¦μ
.babelrc
μμbabel.config.js
λ³κ²½ν μ μμ΅λλ€. μ΄λ κ² νλ©΄ λ©λλ€.μ루μ 2:
μ΄ λ°©λ²μ μ¬μ©νκ³ μμ΅λλ€.
λ€μκ³Ό κ°μ λ³ν νμΌμ λ§λλλ€(λ΄ νμΌμjest-transforme.js
μ).const config = { babelrc: false, presets: [ [ "@babel/env", { modules: false } ], "@babel/react" ], plugins: [ ["@babel/plugin-proposal-decorators", { legacy: true }], ["@babel/plugin-proposal-class-properties", { loose: true }], "transform-es2015-modules-commonjs" ] }; module.exports = require("babel-jest").createTransformer(config);
λ΄
jest.config.js
λ€μκ³Ό κ°μ΅λλ€.module.exports = { collectCoverageFrom: ["src/**/*.{js,jsx,mjs}"], testMatch: ["<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}", "<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"], transform: { "^.+\\.(js|jsx|mjs)$": "<rootDir>/config/jest/jest-transformer.js" }, transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"] };
κ·Έλ¦¬κ³ μμ§ λ΄
.babelrc
const enviroments = require("./env-config.js"); module.exports = { presets: [ [ "next/babel", { "preset-env": { useBuiltIns: "entry" } } ] ], plugins: [ ["styled-components", { ssr: true, displayName: true, preprocess: false }], [ "module-resolver", { root: ["./"] } ] ], env: { dev: { plugins: [ ["transform-define", enviroments], ["module-resolver", { root: ["./"] }], "transform-decorators-legacy", "transform-class-properties" ] }, build: { plugins: [ ["transform-define", enviroments], ["module-resolver", { root: ["./"] }], "transform-decorators-legacy", "transform-class-properties" ] }, production: { presets: [ [ "minify", // why add minify here, we run uglify over the whole code bundles { mangle: false, evaluate: false } ] ], plugins: [ ["transform-define", enviroments], ["@babel/plugin-proposal-decorators", { legacy: true }], ["@babel/plugin-proposal-class-properties", { loose: true }], ["module-resolver", { root: ["./"] }] ], comments: false, compact: true, minified: true } } };
μ΄κ²μ΄ μ¬λ¬λΆμ΄ μ΄ λ¬Έμ λ₯Ό ν΅κ³Όν μ μκΈ°λ₯Ό λ°λλλ€. ννΈ.
κ·νμ λ°©λ²μ λν tks ~μ΄ λ°©λ²μ λ΄ λ¬Έμ λ₯Ό μ¬λ°λ₯΄κ² ν΄κ²°ν μ μμ΅λλ€!
μλ νμΈμ - μ΄ μ€λ λμμ μ¬λ¬ κ°μ§λ₯Ό μλνμ§λ§ μ무 κ²λ μλνμ§ μλ κ² κ°μ΅λλ€. μ£Όμ μ€λ₯λ μ΄μν©λλ€. b/cλ μλ―Έκ° μλ μ€ λ²νΈλ₯Ό κ°λ¦¬ν€λ κ² κ°μ΅λλ€. λ§μΉ μμ€ μ½λμ μ€ννλ €λ μ€μ μ½λκ° μΌμΉνμ§ μλ κ²κ³Ό κ°μ΅λλ€.
Jestκ° μκΈ°μΉ μμ ν ν°μ λ°κ²¬νλ€λ μ΄ μ€λ₯κ° λ¨μ μμ΅λλ€. μ λ Jest > 24, no type scriptμ μμ΅λλ€. μ΅κ·Όμ(6κ°μ μ ~) μ κ±°λ react-create-appμ λλ€. μΊμλ₯Ό μ§μ°κ³ node_modulesλ₯Ό μ κ±°ν΄λ λμμ΄ λμ§ μμμ΅λλ€. μλ§λ λκ΅°κ° jestκ° μ¬λ°λ₯΄κ² λ³ννκ³ μ€ννκΈ° μν΄ νμν ꡬμ±κ³Ό μ νν μ€λ₯κ° μ 곡νλ ννΈλ₯Ό μ νν μ€λͺ ν μ μμ΅λλ€.
FAIL __e2e__/chat/sms.spec.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/ben/dev/app/webui/node_modules/babel-preset-react-app/node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:17
export default function _asyncToGenerator(fn) {
^^^^^^
SyntaxError: Unexpected token export
5 | afterEach(async () => {
6 | await logout();
> 7 |
| ^
8 | await page.evaluate(() => {
9 | localStorage.clear();
10 | });
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:471:17)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25)
at Object.<anonymous> (__e2e__/chat/sms.spec.js:7:49)
λ€λ€ κ°μ¬ ν΄μ,
μ΄ λ¬Έμ λ‘ μΈν΄ Jenkinsκ° μ€ν¨ν©λλ€. μλνλ μ루μ μ΄ μμ΅λκΉ?
Create-React-Appμ μ¬μ©νλ μ¬λμ κ²½μ° CRAλ₯Ό μ¬μ©ν λ package.jsonμμ νΉμ jest ꡬμ±λ§ λ³κ²½ν μ μμΌλ―λ‘ package.jsonμ transformignorepatterns
λ₯Ό μΆκ°ν΄λ λ¬Έμ κ° ν΄κ²°λμ§ μμ΅λλ€.
Jestκ° λ΄λΆ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ ννλ λ° λ¬Έμ κ° μμμ΅λλ€. Jestλ μ΄ λΌμ΄λΈλ¬λ¦¬μμ κ°μ Έμ€κΈ°λ₯Ό ν λλ§λ€ 'μκΈ°μΉ μμ ν ν°' μ€λ₯λ₯Ό νμν©λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ ν
μ€νΈ μ€ν¬λ¦½νΈλ₯Ό μλμ κ°μ΄ λ³κ²½ν μ μμ΅λλ€.
"test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(<your-package-goes-here>)/)'",
μλ νμΈμ, μ λ JetSetμ΄λΌκ³ νκ³ React Nativeλ‘ μμ±λ μμ νλ‘μ νΈλ‘ λ¨μ ν μ€νΈλ₯Ό μννλ λ° μ΄λ €μμ κ²ͺκ³ μμμ΅λλ€. μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ 2μΌ λμ κ²μνκ³ babel.config.jsμ κ°μ κ²μ νΈμ§νκ³ ν΄λΉ νμΌμ μμ ν λ€μ .babel νμΌμ μμ±(κ·Έλ¦¬κ³ μ½κ°μ μΆκ°)νλ €κ³ νμ΅λλ€.
_λ²κ·Έ μ κ³ :_
D:\jetset\JetSetApp>jest SaveData.test.js
μ€ν¨ __test__/SaveData.test.js
β ν
μ€νΈ μ€μνΈ μ€ν μ€ν¨
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:
D:\jetset\JetSetApp\node_modules\expo-file-system\build\index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import * as FileSystem from './FileSystem';
^
SyntaxError: Unexpected token *
1 | import React, { Component } from 'react'
2 | import { View, Text, TouchableOpacity, TextInput, StyleSheet } from 'react-native'
> 3 | import { documentDirectory, getInfoAsync, readDirectoryAsync, readAsStringAsync, writeAsStringAsync, deleteAsync } from 'expo-file-system';
| ^
4 |
5 | /**
6 | * This class primarily serves to handle files within the phone system so that results can be stored
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (app/resources/SaveData/SaveData.js:3:1)
ν
μ€νΈ μ€μνΈ: 1κ° μ€ν¨, μ΄ 1κ°
ν
μ€νΈ: μ΄ 0κ°
μ€λ
μ·: μ΄ 0κ°
μκ°: 3.509μ΄
/SaveData.test.js/iμ μΌμΉνλ λͺ¨λ ν
μ€νΈ μ€μνΈλ₯Ό μ€ννμ΅λλ€.
_ babel.config.js _
module.exports = ν¨μ(api) {
api.cache(μ°Έ);
λ°ν {
μ¬μ μ€μ : ['babel-preset-expo'],
};
};
_ ν¨ν€μ§.json _
{
"λ©μΈ": "node_modules/expo/AppEntry.js",
"μ€ν¬λ¦½νΈ": {
"μμ": "μμ€ν¬ μμ",
"μλλ‘μ΄λ": "μμ€ν¬ μμ --android",
"ios": "μμ€ν¬ μμ --ios",
"μΉ": "μμ€ν¬ μμ --μΉ",
"κΊΌλ΄κΈ°": "μμ€ν¬ κΊΌλ΄κΈ°",
"ν
μ€νΈ": "λλ΄"
},
"λλ΄": {
"μ¬μ μ€μ ": "λ°μ λ€μ΄ν°λΈ"
},
"μ’
μμ±": {
"μμ€ν¬": "^34.0.1",
"μμ€ν¬ νμΌ μμ€ν
": "^6.0.2",
"expo-mail-composer": "^6.0.0",
"μκ°": "^2.24.0",
"λ°μ": "16.8.3",
"react-dom": "^16.8.6",
"λ°μ λ€μ΄ν°λΈ": " https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz ",
"λ°μ λ€μ΄ν°λΈ μ μ€μ² μ²λ¦¬κΈ°": "^1.3.0",
"λ°μ λ€μ΄ν°λΈ μ ν κ·Έλ£Ή": "^1.1.2",
"λ°μ λ€μ΄ν°λΈ μΉ": "^0.11.4"
},
"devDependencies": {
"@babel/core": "^7.6.2",
"@babel/preset-env": "^7.6.2",
"λ°λ²¨ λλ΄": "^24.9.0",
"babel-preset-expo": "^6.0.0",
"λλ΄": "^24.9.0",
"μν μ ν": "^15.7.2",
"react-native-dismiss-keyboard": "^1.0.0",
"react-native-modal-datetime-picker": "^7.5.0",
"λ°μ νμ": "^3.12.1"
},
"λΉκ³΅κ°": μ¬μ€
}
μ°Έκ³ λ‘ μ λ NODE_ENV="test"κ° μ€μ λμ§ μμ κ²½μ° μ 체 λΉλ μμ€ν μ΄ μ λλ‘ μλνμ§ μλ κ²μ²λΌ μ΄κ²μ λν μ λ§ μ΄λ¦¬μμ ν΄κ²°μ± μ μ°Ύμ κ² κ°μ΅λλ€.
μ΅μ λ²μ μ React Jestλ package.jsonμ λ΄μ₯λμ΄ μμΌλ―λ‘ ν
μ€νΈ μ€ν¬λ¦½νΈλ λ€μκ³Ό κ°μμΌ ν©λλ€.
"test": "react-scripts test"
λμ μ
"test": "jest"
μ΅μ λ²μ μ React Jestλ package.jsonμ λ΄μ₯λμ΄ μμΌλ―λ‘ ν μ€νΈ μ€ν¬λ¦½νΈλ λ€μκ³Ό κ°μμΌ ν©λλ€.
"test": "react-scripts test"
λμ μ
"test": "jest"
λλΆμ λ¬Έμ κ° ν΄κ²°λμμ΅λλ€!
λ§μ΄ μλν ν λ¬Έμ λ λ€μκ³Ό κ°μ΅λλ€.
.babelrc νμΌμ "transform-es2015-modules-commonjs",
λλ½
{
"presets": ["next/babel"],
"plugins": [
["styled-components", { "ssr": true, "displayName": true, "preprocess": false } ],
"transform-flow-strip-types",
"jsx-control-statements",
"import-glob",
"transform-es2015-modules-commonjs",
[
"import",
{
"libraryName": "antd",
"style": "css"
}
]
]
}
"λλ΄": "^24.9.0",
"λ°λ²¨ λλ΄": "23.6.0",
λλ΄κ³Ό babel-jestλ₯Ό μ λ°μ΄νΈνλ €κ³ μλνμμμ€.
.babelrc
μbabel.config.js
λ‘ λ³κ²½νκ³ Babel7λ‘ μ κ·Έλ μ΄λνλλ° μ¬μ ν μ΄μ κ³Ό λμΌν μ€λ₯κ° λ°μν©λλ€. λ΄babel.config.js
νμΌ:module.exports = function (api) { api.cache(true); const presets = ["@babel/preset-env"]; return { presets }; }
@babel/preset-react
νκ³babel.config.js
νμΌμ μΆκ°νμ΅λλ€. μ€λ₯λ₯Ό μμ νμ΅λλ€.
μ΄κ²μ λ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€. @babel/preset-envλ₯Ό μ€μΉνκ³ babel.config.jsμ μΆκ°νκ³ μμ νμ΅λλ€.
@jmayergit κ°μ¬
babel.rc νμΌμ babel.config.js νμΌλ‘ λ³κ²½νμ§λ§ μλνμ§ μμμ΅λλ€. κ·Έλ° λ€μμ΄ λ΅λ³μ 보μμ΅λλ€. https://stackoverflow.com/questions/58470062/test-jest-with-babel-plugin-import
κ°μ Έμ€κΈ° νλ¬κ·ΈμΈμ΄ μλ κ²½μ° ν
μ€νΈ, κ°λ° λ° νλ‘λμ
νκ²½μ© νλ¬κ·ΈμΈμ λΆλ¦¬ν©λλ€.
λ΄ babel.config.js νμΌμ μ΄μ λ€μκ³Ό κ°μ΄ μλν©λλ€.
module.exports = {
presets: [
[
'next/babel',
],
],
env: {
test: {
},
dev: {
plugins: [
['import', { libraryName: 'antd', style: 'css' }],
],
},
production: {
plugins: [
['import', { libraryName: 'antd', style: 'css' }],
],
},
},
};
λλ λν 5 μΌλΆν°μ΄ μ€λ₯λ‘ μ΄λ €μμ κ²ͺκ³ μμ΅λλ€.
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:
SyntaxError: C:\Users\SK-PC\Desktop\React-Course\expansify\src\test\components\MyNavbar.test.js: Unexpected token (5:28)
3 | import { MyNavbar } from '../../components/MyNavbar'
4 | test("Should return MyNavbar component", () => {
> 5 | const wrapper = shallow(<MyNavbar />)
| ^
6 | expect(wrapper.find('.navbar-brand').find('kbd').text()).toBe("Expensify")
7 | // const renderer = new ReactShallowRenderer()
8 | // renderer.render(<MyNavbar />)
at Parser._raise (node_modules/@babel/parser/src/parser/location.js:241:45)
at Parser.raiseWithData (node_modules/@babel/parser/src/parser/location.js:236:17)
at Parser.raise (node_modules/@babel/parser/src/parser/location.js:220:17)
at Parser.unexpected (node_modules/@babel/parser/src/parser/util.js:149:16)
at Parser.parseExprAtom (node_modules/@babel/parser/src/parser/expression.js:1144:20)
at Parser.parseExprSubscripts (node_modules/@babel/parser/src/parser/expression.js:539:23)
at Parser.parseMaybeUnary (node_modules/@babel/parser/src/parser/expression.js:519:21)
at Parser.parseExprOps (node_modules/@babel/parser/src/parser/expression.js:311:23)
at Parser.parseMaybeConditional (node_modules/@babel/parser/src/parser/expression.js:263:23)
at Parser.parseMaybeAssign (node_modules/@babel/parser/src/parser/expression.js:211:21)
PASS src/test/reducers/filters.test.js
Test Suites: 1 failed, 5 passed, 6 total
Tests: 29 passed, 29 total
Snapshots: 0 total
Time: 12.144s
Ran all test suites.
@fullstacksk
μ΅μ λ²μ μ React Jestλ package.jsonμ λ΄μ₯λμ΄ μμΌλ―λ‘ ν μ€νΈ μ€ν¬λ¦½νΈλ λ€μκ³Ό κ°μμΌ ν©λλ€.
"test": "react-scripts test"
λμ μ
"test": "jest"
λ€μ μμΉμμ λ¬Έμλ₯Ό μ½μ μ μμ΅λλ€.
https://jestjs.io/docs/en/tutorial-react
https://create-react-app.dev/docs/running-tests/#docsNav
@catmans1
create-react-app λλ react-scriptsμ κ°μ μ’
μμ±μ μ€μΉνμ§ μμμ΅λλ€.
μλν κΉμ?
"test": "react-scripts test"
λμ μ
"test": "jest"
μ΄μ env λ° reactλ‘ μ΅μ μ ν μ€νΈνκΈ° μν΄ babel-preset-jestλ₯Ό μ¬μ©ν λ μλν©λλ€. λλ babel-jeastλ₯Ό μ κ±°νμ΅λλ€.
μ λ₯Ό μν΄ μΌνμ΅λλ€: babel.config.js
"@babel/preset-react"λ₯Ό ν¬ν¨
https://medium.com/@audreyhal/how -to-solve-jest-error-with-create-react-app-part-1-80f33aa1661a
μ΄λ¦¬μμ μ€μλ₯Ό νκ³ .tsx
νμ₯μκ° μλ .ts
첫 λ²μ§Έ ν
μ€νΈ νμΌμ μμ±ν ν μ΄ μ€λ₯λ₯Ό 보μμ΅λλ€. μλ λ¬Έμ μλ κ±°λ¦¬κ° λ©μ§ λ§ λκ΅°κ°μκ² λμμ΄ λ μ μμ΅λλ€ π
κ°μ₯ μ μ©ν λκΈ
3μΌ νμ μ΄ λ¬Έμ μ λν ν΄κ²°μ± μ μ°Ύμμ΅λλ€.
μ΄λ₯Ό μν 2κ°μ§ μ루μ μ΄ μμ΅λλ€.
μ루μ 1:
νμΌ μ΄λ¦μ
.babelrc
μμbabel.config.js
λ³κ²½ν μ μμ΅λλ€. μ΄λ κ² νλ©΄ λ©λλ€.## μ루μ 2:
μ΄ λ°©λ²μ μ¬μ©νκ³ μμ΅λλ€.
λ€μκ³Ό κ°μ λ³ν νμΌμ λ§λλλ€(λ΄ νμΌμ
jest-transforme.js
μ).λ΄
jest.config.js
λ€μκ³Ό κ°μ΅λλ€.κ·Έλ¦¬κ³ μμ§ λ΄
.babelrc
```
const νκ²½ = require("./env-config.js");
module.exports = {
μ¬μ μ€μ : [
[
"λ€μ/λ°λ²¨",
{
"μ¬μ μ€μ νκ²½": {
useBuiltIns: "νλͺ©"
}
}
]
],
νλ¬κ·ΈμΈ: [
["μ€νμΌ κ΅¬μ± μμ", { ssr: true, displayName: true, μ μ²λ¦¬: false }],
[
"λͺ¨λ ν΄κ²°μ¬",
{
루νΈ: ["./"]
}
]
],
νκ²½: {
κ°λ°μ: {
νλ¬κ·ΈμΈ: [
["λ³ν μ μ", νκ²½],
["λͺ¨λ ν΄μκΈ°", { 루νΈ: ["./"] }],
"λ³ν-λ°μ½λ μ΄ν°-λ κ±°μ",
"λ³ν ν΄λμ€ μμ±"
]
},
μ§λ€: {
νλ¬κ·ΈμΈ: [
["λ³ν μ μ", νκ²½],
["λͺ¨λ ν΄μκΈ°", { 루νΈ: ["./"] }],
"λ³ν-λ°μ½λ μ΄ν°-λ κ±°μ",
"λ³ν ν΄λμ€ μμ±"
]
},
μμ°: {
μ¬μ μ€μ : [
[
"minify", // μ μ¬κΈ°μ minifyλ₯Ό μΆκ°ν©λκΉ? μ 체 μ½λ λ²λ€μ λν΄ uglifyλ₯Ό μ€νν©λλ€.
{
λ§ΉκΈ: κ±°μ§,
νκ°: κ±°μ§
}
]
],
νλ¬κ·ΈμΈ: [
["λ³ν μ μ", νκ²½],
["@babel/plugin-proposal-decorators", { λ κ±°μ: true }],
["@babel/plugin-proposal-class-properties", { λμ¨ν: true }],
["λͺ¨λ ν΄μκΈ°", { 루νΈ: ["./"] }]
],
λκΈ: κ±°μ§,
μ»΄ν©νΈ: μ¬μ€,
μΆμ: μ¬μ€
}
}
};
````
μ΄κ²μ΄ μ¬λ¬λΆμ΄ μ΄ λ¬Έμ λ₯Ό ν΅κ³Όν μ μκΈ°λ₯Ό λ°λλλ€. ννΈ.