我以编程方式使用 webpack,结合 typescript、ESM 和 jest。在一个玩笑测试中,我.js在导入 ES 模块时因不包含文件扩展名而收到错误。例如:
Module not found: Error: Can't resolve 'modulename' in '/path/components'
Did you mean 'modulename.js'?
BREAKING CHANGE: The request 'modulename' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add …Run Code Online (Sandbox Code Playgroud) 使用 Jest(ESM 和 ts-jest)导入 CJS 模块时遇到一些问题。最小复制回购。
例如,按照其文档@apollo/client中所述从模块导入:
import {
ApolloClient,
InMemoryCache,
ApolloProvider,
useQuery,
gql
} from '@apollo/client';
Run Code Online (Sandbox Code Playgroud)
每个导入都会给出类似的错误SyntaxError: The requested module '@apollo/client' does not provide an export named 'ApolloProvider'。查看 的@apollo/clientpackage.json ,"main"key设置为"./main.cjs",这是用cjs风格重新导出东西:
var core = require('./core');
var react = require('./react');
for (var k in core) {
if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = core[k];
}
for (var k in react) {
if (k !== 'default' && !exports.hasOwnProperty(k)) …Run Code Online (Sandbox Code Playgroud) 已经成功设置了 jest/esm,但是偶尔会发布一个模块,该main模块module在其package.json. 这会导致玩笑错误,例如使用uuid 模块:
/repo/path/node_modules/uuid/dist/esm-browser/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { default as v1 } from './v1.js';
^^^^^^
SyntaxError: Unexpected token 'export'
Run Code Online (Sandbox Code Playgroud)
我可以看到这是由 中的键dist/esm-browser/index.js指定的文件。modulepackage.json
如何配置 Jest w/ESM 来处理这些情况,其中 node_modules 中的内容是 ESM?
笑话配置:
{
"resetMocks": true,
"testEnvironment": "jsdom",
"testMatch": [
"**/src/**/*.(spec|test).[tj]s?(x)"
],
"preset": "ts-jest/presets/default-esm",
"extensionsToTreatAsEsm": [
".ts",
".tsx"
],
"globals": {
"ts-jest": {
"useESM": true
}
},
"globalSetup": "<rootDir>/jest/setup.cjs",
"globalTeardown": "<rootDir>/jest/teardown.cjs",
"watchPathIgnorePatterns": [
"<rootDir>/.tmp"
],
"moduleNameMapper": {
"^~/(.*)$": "<rootDir>/src/$1",
"^~components/(.*)$": "<rootDir>/src/components/$1",
"^~util/(.*)$": "<rootDir>/src/util/$1", …Run Code Online (Sandbox Code Playgroud) 我试图在运行时动态创建 Typeorm 实体,然后在创建连接时将它们显式添加到连接中。我在弄清楚如何使用属性装饰器时遇到了一些麻烦。
作为控件,以声明方式创建实体效果很好:
@Entity('table_name')
export class NewEntity extends BaseEntity {
@PrimaryGeneratedColumn()
public id: number;
}
Run Code Online (Sandbox Code Playgroud)
然后类装饰器可以像常规函数一样正常工作:
class NewEntity {
@PrimaryGeneratedColumn()
public id: number;
}
Entity('table_name')(NewEntity);
Run Code Online (Sandbox Code Playgroud)
但PrimaryGeneratedColumn()作为常规函数使用:
class NewEntity {
public id: number;
}
PrimaryGeneratedColumn()(NewEntity, 'id');
Entity('table_name')(NewEntity);
Run Code Online (Sandbox Code Playgroud)
给出:Entity "NewEntity" does not have a primary column. Primary column is required to have in all your entities. Use @PrimaryColumn decorator to add a primary column to your entity.创建 typeorm 连接时。
我知道这是一个奇怪的用例!但如果有人知道如何做到这一点,将不胜感激!:)
我在将它们添加到一些现有项目时遇到了一些麻烦。例如,我在我开发的模块中有一个类:
export default class ClassName {
// Class members
}
Run Code Online (Sandbox Code Playgroud)
现在我将它导入到另一个项目中:
import ClassName from 'modulename';
const object = new ClassName();
Run Code Online (Sandbox Code Playgroud)
我在这条线上收到 2 个错误。
在object中const object:
error Unsafe assignment of an any value @typescript-eslint/no-unsafe-assignment
Run Code Online (Sandbox Code Playgroud)
在new中new ClassName:
error Unsafe construction of an any type value @typescript-eslint/no-unsafe-call
Run Code Online (Sandbox Code Playgroud)
我怎样才能避免这些错误?!我真的很希望能够遵守这些规则,因为我认为它们非常有用!
谢谢。
这是另一个例子:
error Unsafe assignment of an any value @typescript-eslint/no-unsafe-assignment
Run Code Online (Sandbox Code Playgroud)
在这里,我得到no-unsafe-assignment的错误testEnv的const testEnv和no-unsafe-call错误的readJsonSync第二行调用。
我可以用这个代码摆脱第一个:
error Unsafe construction of …Run Code Online (Sandbox Code Playgroud) 我正在尝试为 ios/android 应用程序中的每个屏幕使用相同的背景,而不会在屏幕转换时移动。在 React Navigation 4 中有这个解决方案:How to set background image with react native 和 react navigation?:
const AppNavigator = createAppContainer(
createStackNavigator(
{
Home: {screen: Home},
Vocabulary: {screen: Vocabulary},
AddWord: {screen: AddWord},
},
{
initialRouteName: 'Home',
headerMode: 'none',
cardStyle: {backgroundColor: 'transparent', shadowColor:'transparent'},
transparentCard: true,
transitionConfig: () => ({
containerStyle: {
backgroundColor: 'transparent',
},
}),
},
),
);
Run Code Online (Sandbox Code Playgroud)
但是现在在第 5 版中,事情发生了变化!你可以这样做:
<Stack.Screen
name="Screen2"
component={Screen2}
options={{
cardStyle: {
backgroundColor: 'transparent',
},
cardStyleInterpolator: CardStyleInterpolators.forVerticalIOS
}}
/>
Run Code Online (Sandbox Code Playgroud)
您必须在每个屏幕上都这样做(这很好,虽然很尴尬),但是当您导航到一个新屏幕时,前一个屏幕只会移动到下方约 25% 的位置,因此它仍然可见,尽管它位于侧面少量。看起来真的很尴尬:

然后我考虑使用一个cardStyleInterpolator …
使用 TS,可以使用语法导入 CJS 模块的导出,就好像它们被命名为 ES 模块导出一样,例如:
import { sync } from 'glob';
Run Code Online (Sandbox Code Playgroud)
但是,对于 Jest 和 ES 模块,当这种导入方式位于测试文件或测试文件的依赖项中时,它会显示SyntaxError: The requested module 'glob' does not provide an export named 'sync'.
逐一检查所有内容并将它们更改为import glob from 'glob';然后调用glob.sync()似乎可行,但是当将一些遗留内容从另一个测试运行程序迁移到 Jest 时,这可能不是一个选择,因为代码库中有很多这样的导入。
转载于此: https: //github.com/themaskedavenger/tsjestcjerepro
运行 jest:(如https://jestjs.io/docs/ecmascript-modulesnode --experimental-vm-modules node_modules/jest/bin/jest.js中所述),并使用 Jest 配置:
resetMocks: true,
testEnvironment: "node",
testMatch: [
"**/src/**/*.(spec|test).[tj]s?(x)"
],
preset: 'ts-jest/presets/default-esm',
transform: {},
'extensionsToTreatAsEsm': [".ts", ".tsx"],
globals: {
'ts-jest': {
useESM: true,
tsconfig: {
allowSyntheticDefaultImports: true,
declaration: true,
esModuleInterop: …Run Code Online (Sandbox Code Playgroud) jestjs ×4
es6-modules ×3
javascript ×3
ts-jest ×3
typescript ×3
node.js ×2
apollo ×1
babel-jest ×1
decorator ×1
eslint ×1
react-native ×1
reactjs ×1
typeorm ×1
webpack ×1