我是一个初学者reactjs
开发者,在我的react typescript中使用monaco-editor
库构建代码编辑器。我已经在我的项目中集成了monaco
编辑器和web worker。我已经使用CRA
和webpack 5
创建了项目。
我试图使用jest库编写一个测试用例,但我遇到了以下错误:"SyntaxError: Cannot use import statement outside a module"
个
我试着在jest.js.js和babel.js.js中添加一些配置。jest.config.js
个
module.exports = {
transform: {
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",
"node_modules/monaco-editor/esm/vs/language/css/css.worker": "babel-jest",
},
globals: {
"ts-jest": {
tsconfig: "./tsconfig.json",
useESM: true
},
},
moduleNameMapper: {
// Use the mock for Worker creation
// 'worker-loader!.*': 'src/__mocks__/workerMock.js',
"monaco-editor/esm/vs/language/(.*)/(.*).worker":
`<rootDir>/src/__mocks__/moanco-editor-mock.ts`,
},
// setupFiles: [`${__dirname}/jest.setup.js`],
testEnvironment: "node",
modulePaths: ['<rootDir>/node_modules'],
moduleDirectories: ['node_modules'],
};
字符串babel.config.js
个
module.exports = {
presets: ["@babel/preset-env", "@babel/preset-typescript"],
plugins: ["transform-import-meta"],
};
型
该错误与monaco编辑器导入有关,该导入发生在我的MonacoEditor.tsx
组件中。该组件在useEffect中创建编辑器并调用MonacoEnvironment.tsx
可能有一些错误,在我的实施,我将感谢任何解决方案,我的实施。
我的MonacoEditor.tsx
import React, { useEffect, useRef } from "react";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
// import * as ts from "monaco-editor/esm/vs/language/typescript/ts.worker.js";
import "../../../styles/MonacoEditor.css";
import MonacoEnvironment from "./editor.worker";
const MonacoEditor: React.FC = () => {
const editorContainer = useRef<HTMLDivElement | null>(null);
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
useEffect(() => {
const createEditor = async () => {
if (editorContainer.current) {
const editor = monaco.editor.create(editorContainer.current, {
value: "",
language: "typescript",
theme: "vs-dark",
minimap: { enabled: true },
automaticLayout: true,
});
editorRef.current = editor;
MonacoEnvironment();
window.addEventListener("resize", () => {
// Trigger Monaco Editor's automatic layout adjustment on window resize
editor.layout();
});
return () =>
window.removeEventListener("resize", () => editor.layout());
}
};
createEditor();
// Cleanup function
return () => {
if (editorRef.current) {
editorRef.current.dispose();
}
};
}, []);
return (
<div className="Monaco_Editor_Outer_Wrapper">
<div ref={editorContainer} className="Monaco_Editor_Main_Container1" />
</div>
);
};
export default MonacoEditor;
型
这是我的MonacoEnviroment.tsx,它在useEffect中被调用,并创建了一个网页工作程序来冻结UI。MonacoEnviroment.tsx
个
import React from "react";
const MonacoEnvironment = () => {
console.log("MonacoEnvironment");
window.MonacoEnvironment = {
getWorker(moduleId: string, label: string) {
switch (label) {
case "css":
case "less":
case "scss":
return new Worker(
new URL(
"monaco-editor/esm/vs/language/css/css.worker",
import.meta.url
)
);
case "editorWorkerService":
return new Worker(
new URL(
"monaco-editor/esm/vs/editor/editor.worker",
import.meta.url
)
);
case "handlebars":
case "html":
// return new Worker(new URL("monaco-editor/esm/vs/language/html/html.worker" , import.meta.url) )
case "razor":
return new Worker(
new URL(
"monaco-editor/esm/vs/language/html/html.worker",
import.meta.url
)
);
case "json":
return new Worker(
new URL(
"monaco-editor/esm/vs/language/json/json.worker",
import.meta.url
)
);
case "javascript":
case "typescript":
return new Worker(
new URL(
"monaco-editor/esm/vs/language/typescript/ts.worker",
import.meta.url
)
);
default:
throw new Error(`Unknown label ${label}`);
}
},
};
};
export default MonacoEnvironment;
型
我为MonacoEditor.tsx编写的测试用例用于测试组件。MonacoEditor.test.tsx
个
// MonacoEditor.test.tsx
import React from 'react';
import { render } from '@testing-library/react';
import MonacoEditor from '../components/middleComponent/monacoEditor/MonacoEditor';
// Mock MonacoEnvironment module
jest.mock('../components/middleComponent/monacoEditor/editor.worker', () => ({
__esModule: true,
default: jest.fn(),
}));
describe('MonacoEditor', () => {
it('renders successfully', async () => {
// Render the MonacoEditor component
render(<MonacoEditor />);
// Your test code goes here
// For example, you can assert that MonacoEnvironment was called
expect(require('../components/middleComponent/monacoEditor/editor.worker').default).toHaveBeenCalled();
});
});
型
我在npm run test
运行此测试用例时遇到的错误
src/tests/MonacoEditor.test.tsx
● Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• 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/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
C:\Users\HP\OneDrive\Desktop\prometheus_UI\prometheus_dev_codesimple-frontend\node_modules\monaco-editor\esm\vs\editor\editor.api.js:5
import { EditorOptions } from './common/config/editorOptions.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
1 | import React, { useEffect, useRef } from "react";
> 2 | import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
| ^
3 | // import * as ts from "monaco-editor/esm/vs/language/typescript/ts.worker.js";
4 | import "../../../styles/MonacoEditor.css";
5 | import MonacoEnvironment from "./editor.worker";
at Runtime.createScriptFromCode (node_modules/react-scripts/node_modules/jest-runtime/build/index.js:1728:14)
at Object.<anonymous> (src/components/middleComponent/monacoEditor/MonacoEditor.tsx:2:1)
at Object.<anonymous> (src/tests/MonacoEditor.test.tsx:4:1)
型
我试图更改webpack和jest的配置以支持错误,但无法解决它。
我的webpack.config.js
const path = require("path");
const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
module.exports = {
mode: process.env.NODE_ENV,
entry: {
app: "./src/index.tsx",
"editor.worker": "monaco-editor/esm/vs/editor/editor.worker.js",
"json.worker": "monaco-editor/esm/vs/language/json/json.worker",
"css.worker": "monaco-editor/esm/vs/language/css/css.worker",
"html.worker": "monaco-editor/esm/vs/language/html/html.worker",
"ts.worker": "monaco-editor/esm/vs/language/typescript/ts.worker",
},
// output: {
// path: path.resolve(__dirname, "dist"),
// filename: "bundle.js",
// },
output: {
globalObject: "self",
filename: (chunkData) => {
switch (chunkData.chunk.name) {
case "editor.worker":
return "editor.worker.js";
default:
return "bundle.[hash].js";
}
},
path: path.resolve(__dirname, "dist"),
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.ttf$/,
use: ["file-loader"],
},
{
test: /\.tsx$/,
use: "ts-loader",
exclude: /node_modules/,
},
{
test: /\.worker\.tsx$/,
use: { loader: "worker-loader" },
},
],
},
devServer: {
hot: true,
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MonacoWebpackPlugin({
languages: ["javascript", "typescript", "css"],
}),
"babel-plugin-transform-import-meta",
{ module: "ES6" },
],
};
型
还安装了一些依赖项,如"babel-plugin-named-exports-order": "^0.0.2", "babel-plugin-transform-import-meta": "^2.2.1",
有关更多信息,请查看我的package.json
{
"name": "codesimple-frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.14.18",
"@mui/material": "^5.14.18",
"@react-spring/web": "^9.7.3",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/node": "^16.18.61",
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"monaco-editor-webpack-plugin": "^7.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.12.0",
"react-router-dom": "^6.20.1",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"author": "Ian McFarland",
"email": "[email protected]",
"repository": "[email protected]:logomancy/prometheus_dev_codesimple-frontend.git",
"bugs": {
"url": "[email protected]:logomancy/prometheus_dev_codesimple-frontend.git/issues",
"email": "[email protected]"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest",
"plugin:storybook/recommended"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.23.7",
"@babel/preset-env": "^7.23.7",
"@babel/preset-typescript": "^7.23.3",
"@jest/globals": "^29.7.0",
"@storybook/addon-essentials": "^7.5.3",
"@storybook/addon-interactions": "^7.5.3",
"@storybook/addon-links": "^7.5.3",
"@storybook/addon-onboarding": "^1.0.8",
"@storybook/blocks": "^7.5.3",
"@storybook/preset-create-react-app": "^7.5.3",
"@storybook/react": "^7.5.3",
"@storybook/react-webpack5": "^7.5.3",
"@storybook/testing-library": "^0.2.2",
"@types/jest": "^29.5.10",
"@types/react-icons": "^3.0.0",
"@types/react-router-dom": "^5.3.3",
"@types/react-test-renderer": "^18.0.7",
"babel-jest": "^29.7.0",
"babel-plugin-named-exports-order": "^0.0.2",
"babel-plugin-transform-import-meta": "^2.2.1",
"eslint-plugin-storybook": "^0.6.15",
"prop-types": "^15.8.1",
"react-test-renderer": "^18.2.0",
"storybook": "^7.5.3",
"ts-jest": "^29.1.1",
"ts-loader": "^9.5.1",
"webpack": "^5.89.0",
"worker-loader": "^3.0.8"
}
}
型
1条答案
按热度按时间t8e9dugd1#
AFAIK Jest仍然使用CommonJS模块化系统(
const X = require('X')
)。您的错误消息看起来像是您提供了EcmaScript模块(
import X from 'X'
)当你使用ts-jest来测试你的TypeScript测试时,也发布你的
tsconfig.json
会很有帮助,这样我就可以进一步分析它。从其余的,我可以得到的信息是:
字符串
告诉我们,该文件没有正确转换为CommonJS作为
By default "node_modules" folder is ignored by transformers.
Jest已经告诉我们如果我们想做什么:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
我现在没有一个例子,但我总是这样做:
/(?!monaco-editor)
。基本上只是告诉Jest忽略除了monaco-editor
之外的所有node_modules的转换。适用于基本的Regex和negative-lookaheads如果错误消息再次出现,使用不同的模块,只需将新模块添加到正则表达式中,如
/(?!(monaco-editor|<new-module>))
也许正则表达式的语法有点不同。
希望这对你有帮助,Mika