我无法运行测试。
当我为我的应用程序运行“纱线测试”时,我得到了可怕的错误: 笑话遇到了意外的令牌。 SyntaxError:意外令牌'。'
图片:开玩笑的错误
从logon.tsx导入.scss失败:import styles from './_logon.scss';
我已经尝试过使用带有“ identity-object-proxy”或带有样式模拟的moduleNameMapper之类的解决方案:
Syntax Error when test component with SASS file imported
我在做什么错?我尝试从create-react-app复制一些有趣的配置,因为它在那里工作。我把它放在jest.config.js而不是package.json中。这是正确的吗?
jest.config.js:
module.exports = {
collectCoverage: true,
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.spec.{ts,tsx}', '!src/**/*.node.{ts,tsx}', '!src/typings/**/*'],
coverageDirectory: 'build/coverage',
projects: [
{
setupFiles: ['./jestSetup.js'],
displayName: 'dom',
testEnvironment: 'jsdom',
testMatch: ['**/__tests__/**/*.spec.ts?(x)'],
},
{
coverageDirectory: 'build/coverage',
setupFiles: ['./jestSetup.js'],
displayName: 'node',
testEnvironment: 'node',
testMatch: ['**/__tests__/**/*.node.ts?(x)'],
},
],
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
'^.+\\.(css|scss|sass)$': '<rootDir>/jest/cssTransform.js',
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '<rootDir>/jest/fileTransform.js',
},
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$', '^.+\\.(css|sass|scss)$'],
modulePaths: [],
moduleNameMapper: {
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
},
};
_logon.scss
.logon-page {
align-items: center;
display: flex;
height: 100%;
justify-content: center;
width: 100%;
}
.logon-container {
background-color: $ui-01;
color: $text-02;
padding: 16px;
width: 450px;
:global {
.bx--inline-notification__text-wrapper {
width: 300px;
}
.bx--inline-notification {
margin-bottom: 0;
margin-top: 0;
}
.bx--inline-notification__details {
margin-bottom: auto;
margin-top: auto;
}
}
}
.logon-container__button {
float: right;
font-size: 1.3rem;
height: 60px;
max-width: 100%;
width: 50%;
}
.logon-container__input {
background-color: $field-02;
}
.logon-container__hr {
border-bottom: 1px solid $ui-03;
margin-top: 0;
}
.logon-container__gap {
height: 68px;
padding-bottom: 10px;
padding-top: 10px;
}
package.json
{
"name": "graphui",
"private": true,
"scripts": {
"build": "cross-env NODE_ENV=production npm-run-all clean --parallel build:frontend build:server",
"build:server": "webpack --config webpack/webpack.server.babel.js",
"build:frontend": "cross-env IS_BROWSER=true webpack --config webpack/webpack.frontend.babel.js",
"clean": "npm-run-all -s clean:remove clean:recreate",
"clean:remove": "rimraf dist",
"clean:recreate": "mkdirp dist/web/static",
"commit": "cz",
"dev": "cross-env NODE_ENV=development npm-run-all clean --parallel dev:frontend dev:server",
"dev:server": "webpack -w --config webpack/webpack.server.babel.js",
"dev:frontend": "cross-env IS_BROWSER=true webpack-dev-server -d -w --config webpack/webpack.dev.babel.js",
"lint": "npm-run-all --parallel lint:js lint:css lint:commits lint:bundlesize",
"lint:js": "eslint --ext ts,tsx src ",
"lint:css": "stylelint src/**/*",
"lint:commits": "commitlint -e ./.git/COMMIT_EDITMSG",
"lint:bundlesize": "bundlesize",
"test": "jest",
"validate": "npm-run-all --parallel validate:lint validate:gbvalidator",
"validate:lint": "lint-staged --allow-empty",
"validate:gbvalidator": "gbvalidator --pattern \"^(feat|fix|release|refactor|test|docs|build|ci|perf|styles)/([a-z0-9_#-./]){3,40}\\$\" --message \"See CONTRIBUTING.md for examples of valid branch names\"",
"validated:translation": "node missingTranslations.js"
},
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "yarn run validate",
"post-merge": "node postMerge.js"
}
},
"lint-staged": {
"src/**/*.{ts,tsx}": [
"eslint --fix",
"jest --bail --ci --silent --findRelatedTests"
],
"src/**/*.{css,scss}": [
"stylelint --fix"
]
},
"dependencies": {
"@carbon/grid": "^10.15.0",
"@carbon/icons-react": "^10.19.0",
"@carbon/themes": "^10.21.0",
"@carbon/type": "^10.16.0",
"@egjs/hammerjs": "^2.0.17",
"@emotion/cache": "^10.0.29",
"@emotion/core": "^10.0.35",
"@emotion/styled": "^10.0.27",
"@loadable/component": "^5.13.2",
"@loadable/server": "^5.13.2",
"@reduxjs/toolkit": "^1.4.0",
"blueimp-md5": "^2.18.0",
"body-parser": "^1.19.0",
"carbon-components": "^10.22.0",
"carbon-components-react": "^7.22.0",
"carbon-icons": "^7.0.7",
"chokidar": "^3.4.3",
"classnames": "^2.2.6",
"compression": "^1.7.4",
"cookie-parser": "^1.4.5",
"create-emotion-server": "^10.0.27",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-async-errors": "^3.1.1",
"express-winston": "^4.0.5",
"gremlin": "^3.4.8",
"helmet": "^4.1.1",
"i18next": "^19.8.2",
"i18next-browser-languagedetector": "^6.0.1",
"i18next-fs-backend": "^1.0.7",
"i18next-http-backend": "^1.0.21",
"i18next-http-middleware": "^3.0.6",
"ibm_db": "^2.7.1",
"identity-obj-proxy": "^3.0.0",
"immer": "^7.0.9",
"java.io": "^2.4.0",
"js-yaml": "^3.14.0",
"jsonwebtoken": "^8.5.1",
"keycharm": "^0.4.0",
"lodash": "^4.17.20",
"passport": "^0.4.1",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"prop-types": "^15.7.2",
"react": "^16.14.0",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dom": "^16.14.0",
"react-error-boundary": "^3.0.2",
"react-hook-form": "^6.9.2",
"react-i18next": "^11.7.3",
"react-redux": "^7.2.1",
"react-router-dom": "^5.2.0",
"react-window": "^1.8.5",
"reactour": "^1.18.0",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"remove": "^0.1.5",
"serialize-javascript": "^5.0.1",
"serve-static": "^1.14.1",
"styled-components": "^5.2.0",
"uuid": "^8.3.1",
"vis-data": "^7.1.0",
"vis-network": "^8.4.0",
"vis-util": "^4.3.4",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^4.5.0"
},
"devDependencies": {
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.1",
"@babel/node": "^7.12.1",
"@babel/plugin-proposal-class-properties": "^7.12.1",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
"@babel/plugin-proposal-private-methods": "^7.12.1",
"@babel/preset-env": "^7.12.1",
"@babel/preset-react": "^7.12.1",
"@babel/preset-typescript": "^7.12.1",
"@commitlint/cli": "^11.0.0",
"@commitlint/config-conventional": "^11.0.0",
"@hookform/devtools": "^2.2.1",
"@lcluber/gitbranchvalidator": "^1.3.0",
"@loadable/babel-plugin": "^5.13.2",
"@loadable/webpack-plugin": "^5.13.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.2",
"@testing-library/dom": "^7.26.0",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.8",
"@types/blueimp-md5": "^2.7.0",
"@types/body-parser": "^1.19.0",
"@types/carbon-components": "^10.15.0",
"@types/carbon-components-react": "^7.10.10",
"@types/carbon__icons-react": "^10.17.1",
"@types/carbon__type": "^0.0.1",
"@types/classnames": "^2",
"@types/compression": "^1.7.0",
"@types/cookie-parser": "^1.4.2",
"@types/copy-webpack-plugin": "^6.0.0",
"@types/eslint": "^7.2.4",
"@types/eslint-plugin-prettier": "^3.1.0",
"@types/express": "^4.17.8",
"@types/gremlin": "^3.4.6",
"@types/i18next-fs-backend": "^1.0.0",
"@types/ibm_db": "^2.0.6",
"@types/jest": "^26.0.14",
"@types/js-yaml": "^3.12.5",
"@types/jsonwebtoken": "^8.5.0",
"@types/loadable__component": "^5.13.1",
"@types/loadable__server": "^5.12.3",
"@types/loadable__webpack-plugin": "^5.7.1",
"@types/lodash": "^4",
"@types/mini-css-extract-plugin": "^1.0.0",
"@types/mkdirp": "^1.0.1",
"@types/node": "^14.11.8",
"@types/node-sass": "^4.11.1",
"@types/optimize-css-assets-webpack-plugin": "^5.0.1",
"@types/passport": "^1.0.4",
"@types/passport-jwt": "^3.0.3",
"@types/passport-local": "^1.0.33",
"@types/prettier": "^2.1.2",
"@types/prop-types": "^15.7.3",
"@types/react": "^16.9.52",
"@types/react-dom": "^16.9.8",
"@types/react-redux": "^7.1.9",
"@types/react-router-dom": "^5.1.6",
"@types/react-window": "^1.8.2",
"@types/reactour": "^1.17.1",
"@types/rimraf": "^3.0.0",
"@types/serialize-javascript": "^4.0.0",
"@types/serve-static": "^1.13.5",
"@types/styled-components": "^5.1.4",
"@types/supertest": "^2.0.10",
"@types/terser-webpack-plugin": "^4",
"@types/testing-library__jest-dom": "^5.9.4",
"@types/uuid": "^8.3.0",
"@types/webpack": "^4.41.22",
"@types/webpack-dev-server": "^3.11.0",
"@types/webpack-env": "^1.15.3",
"@types/webpack-node-externals": "^2.5.0",
"@types/workbox-webpack-plugin": "^5.1.5",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.5.2",
"babel-loader": "^8.1.0",
"babel-plugin-emotion": "^10.0.33",
"babel-plugin-module-resolver": "^4.0.0",
"bundlesize": "^0.18.0",
"chalk": "^4.1.0",
"commitizen": "^4.2.1",
"commitlint": "^11.0.0",
"copy-webpack-plugin": "^6.2.1",
"cross-env": "^7.0.2",
"css-loader": "^5.0.0",
"cz-conventional-changelog": "^3.3.0",
"dotenv": "^8.2.0",
"eslint": "^7.11.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-airbnb-typescript": "^11.0.0",
"eslint-config-prettier": "^6.12.0",
"eslint-config-react": "^1.1.7",
"eslint-import-resolver-babel-module": "^5.1.2",
"eslint-import-resolver-node": "^0.3.4",
"eslint-plugin-generic-intl": "^1.0.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.1.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.21.4",
"eslint-plugin-react-hooks": "^4.1.2",
"husky": "^4.3.0",
"jest": "^26.5.3",
"jest-environment-jsdom-fourteen": "^1.0.1",
"jest-transform-css": "^2.1.0",
"lint-staged": "^10.4.0",
"mini-css-extract-plugin": "^1.0.0",
"mkdirp": "^1.0.4",
"msw": "^0.21.2",
"node-sass": "^4.14.1",
"nodemon": "^2.0.5",
"nodemon-webpack-plugin": "^4.3.2",
"npm-run-all": "^4.1.5",
"open": "^7.3.0",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss": "^8.1.1",
"postcss-loader": "^4.0.4",
"postcss-preset-env": "^6.7.0",
"preload-webpack-plugin": "^2.3.0",
"prettier": "^2.1.2",
"prettier-eslint": "^11.0.0",
"react-refresh": "^0.8.3",
"rimraf": "^3.0.2",
"sass-loader": "^10.0.3",
"style-loader": "^2.0.0",
"stylelint": "^13.7.2",
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-sass-guidelines": "^7.1.0",
"stylelint-config-standard": "^20.0.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-prettier": "^1.1.2",
"supertest": "^5.0.0",
"terser-webpack-plugin": "^4.2.3",
"typescript": "^4.0.3",
"typescript-plugin-css-modules": "^2.7.0",
"unicoderegexp": "^0.4.1",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-node-externals": "^2.5.2",
"workbox-webpack-plugin": "^5.1.4"
}
}
babel.config.js
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const browsers = ['last 2 Chrome versions', 'last 2 Safari versions', 'last 2 Edge versions', 'Firefox ESR'];
const { env } = process;
const plugins = [
'emotion',
'@loadable/babel-plugin',
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-proposal-nullish-coalescing-operator',
['@babel/plugin-proposal-class-properties', { loose: true }],
['@babel/plugin-proposal-private-methods', { loose: true }],
[
'babel-plugin-module-resolver',
{
alias: {
'@frontend': path.resolve(process.cwd(), path.join('src', 'frontend')),
'@server': path.resolve(process.cwd(), path.join('src', 'server')),
'@shared': path.resolve(process.cwd(), path.join('src', 'shared')),
'@typings': path.resolve(process.cwd(), path.join('src', 'typings')),
'@testhelpers': path.resolve(process.cwd(), path.join('src', 'testhelpers')),
},
extensions: ['.ts', '.tsx', '.json'],
},
],
];
const targets = {
browsers,
node: 'current',
};
if (env.IS_BROWSER) {
delete targets.node;
} else {
delete targets.browser;
}
const presets = [
[
'@babel/preset-react',
{
runtime: 'automatic',
},
],
[
'@babel/preset-env',
{
shippedProposals: true,
targets,
},
],
'@babel/preset-typescript',
];
if (env.NODE_ENV !== 'production' && env.IS_BROWSER) {
plugins.unshift(['react-refresh/babel', { skipEnvCheck: true }]);
}
const config = {
plugins,
presets,
env: {
debug: {
sourceMaps: 'inline',
retainLines: true,
},
development: {
compact: false,
},
},
};
module.exports = config;
webpack.base.js
import 'dotenv/config';
import path from 'path';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
const {
env: { NODE_ENV },
} = process;
const IS_PROD = NODE_ENV === 'production';
const rootDirectory = path.join(__dirname, '..');
const nodeModules = path.join(rootDirectory, 'node_modules');
const config = {
mode: IS_PROD ? 'production' : 'development',
performance: { hints: false },
devtool: IS_PROD ? 'cheap-module-source-map' : 'inline-source-map',
module: {
rules: [
{
test: /\.(s?)css$/,
sideEffects: true,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: !IS_PROD,
},
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]--[hash:base64:5]',
exportLocalsConvention: 'dashesOnly',
},
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
additionalData: `
$feature-flags: (
enable-css-custom-properties: true,
grid-columns-16: true,
ui-shell: true,
);
@import 'carbon-components/scss/globals/scss/vars';
@import '@carbon/type/scss/styles';
`,
},
},
],
},
{
test: /node_modules\/vis-.*\.js$/,
use: [
{
loader: 'babel-loader',
},
],
},
{
exclude: {
test: /node_modules/,
exclude: [
path.resolve(__dirname, 'node_modules', 'vis-network'),
path.resolve(__dirname, 'node_modules', 'vis-data'),
path.resolve(__dirname, 'node_modules', 'vis-utils'),
],
},
test: /\.(t|j)sx?$/,
use: [
{
loader: 'babel-loader',
},
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: NODE_ENV !== 'production' ? '[name].css' : '[name].[contenthash].css',
chunkFilename: NODE_ENV !== 'production' ? '[name].[id].css' : '[name].[id].[contenthash].css',
}),
],
resolve: {
extensions: ['.js', '.tsx', '.ts', '.json', '.css', '.scss'],
modules: [path.resolve(nodeModules), path.resolve(rootDirectory)],
},
stats: {
cached: false,
colors: true,
entrypoints: false,
children: false,
},
};
export default config;