Web Worker - Jest - 无法在模块外使用“import.meta”
Posted
技术标签:
【中文标题】Web Worker - Jest - 无法在模块外使用“import.meta”【英文标题】:Web Worker - Jest - Cannot use 'import.meta' outside a module 【发布时间】:2021-08-18 23:56:19 【问题描述】:我正在开发一个nextjs 10.1.3
内置网络应用程序。我们实施了一个 web worker 来提高其中一个页面的性能,并且计划继续添加更多的 worker;此外,所有代码都经过了适当的单元测试,并且在之前的 webpack 版本(第 4 版及更低版本)中使用 worker-loader
我们能够对其进行测试。
使用新的 webpack 5 版本,不再需要 worker-loader
插件;相反,使用新版本加载 Web Worker 的方式是new Worker(new URL("@/workers/task.worker.js", import.meta.url));
。
这样做,我的代码与npm build && npm start
一样正常工作;但是,当我尝试添加相应的单元测试时,我收到了以下错误:Cannot use 'import.meta' outside a module
一切都发生了,因为 import.meta.url
用于在浏览器中添加工作人员的位置。
我在网上阅读了很多关于 babel
的帖子,但我想摆脱那个选项。有没有其他选项可以用玩笑来模拟import.meta.url
?
非常欢迎任何帮助。这是当前配置。
package.json
...
"@babel/core": "^7.8.6",
"next": "^10.1.3",
"react": "^16.13.0",
"webpack": "^5.37.1"
"devDependencies":
...
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"jest": "^24.9.0",
"jest-cli": "^25.1.0",
...
...
next.config.js
const
...
= process.env;
const basePath = "";
const COMMIT_SHA = [];
const parsed: localEnv = require("dotenv").config();
const webpack = require("webpack");
const withBundleAnalyzer = require("@next/bundle-analyzer")(
enabled: process.env.ANALYZE === "true",
);
const nextConfig =
env:
NEXT_PUBLIC_COMMIT_SHA: COMMIT_SHA,
,
images:
domains: [
"...",
],
,
future:
webpack5: true,
,
productionBrowserSourceMaps: true,
trailingSlash: true,
reactStrictMode: true,
webpack: (config, options) =>
if (localEnv)
config.plugins.push(new webpack.EnvironmentPlugin(localEnv));
else
config.plugins.push(new webpack.EnvironmentPlugin(process.env));
config.module.rules.push(
test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
use:
loader: "url-loader",
options:
limit: 100000,
name: "[name].[ext]",
,
,
);
config.output =
...config.output,
chunkFilename: options.isServer
? `$options.dev ? "[name]" : "[name].[fullhash]".js`
: `static/chunks/$options.dev ? "[name]" : "[name].[fullhash]".js`,
publicPath: `/_next/`,
globalObject: `(typeof self !== 'undefined' ? self : this)`,
;
config.plugins.push(new webpack.IgnorePlugin(/pages.*\/__tests__.*/));
config.plugins.push(
new options.webpack.DefinePlugin(
"process.env.NEXT_IS_SERVER": JSON.stringify(
options.isServer.toString()
),
)
);
return config;
,
;
module.exports = withBundleAnalyzer(nextConfig);
useEffect
工人
useEffect(() =>
if (pageData.data?.length)
workerRef.current = new Worker(new URL("@/workers/task.worker.js", import.meta.url));
workerRef.current.addEventListener("message", result =>
if (result.error)
setWorkerError();
else
updateData(result.data);
);
const ids = pageData.data.map(store => store.id);
workerRef.current.postMessage(ids);
else
setNoDataFound();
return () =>
workerRef.current && workerRef.current.terminate();
;
, []);
jest.config.js
module.exports =
moduleDirectories: ["node_modules", "src", "static", "store"],
modulePathIgnorePatterns: [
"<rootDir>/node_modules/prismjs/plugins/line-numbers",
],
testPathIgnorePatterns: [
"<rootDir>/src/components/component-library",
"<rootDir>/.next",
"jest.config.js",
"next.config.js",
],
collectCoverageFrom: [
"**/src/**",
"**/store/**",
"**/pages/**",
"!**/__tests__/**",
"!**/node_modules/**",
"!**/component-library/**",
],
testEnvironment: "node",
collectCoverage: true,
verbose: false,
automock: false,
setupFiles: ["./setupTests.js"],
moduleNameMapper:
"@/components/(.*)$": "<rootDir>/src/components/$1",
"@/functions/(.*)$": "<rootDir>/src/components/functions/$1",
"@/services/(.*)$": "<rootDir>/src/components/services/$1",
"@/workers/(.*)$": "<rootDir>/src/components/workers/$1",
"@/scripts(.*)$": "<rootDir>/src/scripts/$1",
"@/src(.*)$": "<rootDir>/src/$1",
"@/__mocks__(.*)$": "<rootDir>/__mocks__/$1",
"@/pages(.*)$": "<rootDir>/pages/$1",
"@/store(.*)$": "<rootDir>/store/$1",
"\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
,
coveragePathIgnorePatterns: ["/node_modules/"],
coverageThreshold:
global:
branches: 67,
functions: 66,
lines: 73,
statements: 72,
,
,
runner: "groups",
extraGlobals: [],
testTimeout: 10000,
;
【问题讨论】:
很确定你遇到了这个Jest ESM issue。 Jest 还不完全支持 ES 模块,import.meta
是 ESM 标准。
谢谢@MattCarlotta 我很高兴这个功能很快就会推出!
那么如何模拟这个
有什么更新吗?我仍然遇到这个问题。 SyntaxError 是否有任何解决方法:无法在模块外使用“import.meta”`
【参考方案1】:
在我的设置(typescript + ts-jest)中,我预先添加了以下节点选项以使其工作:
NODE_OPTIONS=--experimental-vm-modules
参考可以在这里找到:https://jestjs.io/docs/ecmascript-modules
【讨论】:
以上是关于Web Worker - Jest - 无法在模块外使用“import.meta”的主要内容,如果未能解决你的问题,请参考以下文章
SyntaxError:无法在模块外使用 import 语句:运行 Jest-expo 测试时
测试套件无法运行在 vue3 中使用 jest 时找不到模块'vue-template-compiler