dwj*_*ton 7 transpiler jestjs babel-jest es6-modules
在这个问我这个问题:
如果从另一个模块调用该模块,为什么变异模块会更新引用,但如果从自身调用则不会更新?
我在询问模块变异的本质.
然而事实证明,ES6模块实际上不能被变异 - 它们的所有属性都被视为常量.(见这个答案)
但不知何故 - 当Jest测试模块时 - 它们可以被改变,这就是Jest允许进行模拟的方式.
这是怎么回事?
我想这是一个正在运行的babel插件 - 将模块转换为CommonJS模块?有没有关于此的文件?
有没有办法查看转换后的代码?
ES6模块实际上不能被变异 - 它们的所有属性都被视为常量.
有趣.你是对的,即使是这样简单的东西:
import * as lib from "./lib"; // import an ES6 module
const spy = jest.spyOn(lib, 'someFunc'); // spy on someFunc
Run Code Online (Sandbox Code Playgroud)
...技术上不应该被允许,因为jest.spyOn 用间谍替换对象上的方法,并且lib.someFunc应该是someFuncES6模块中的绑定.
但不知何故 - 当Jest测试模块时 - 它们可以被改变,这就是Jest允许进行模拟的方式.
这是怎么回事?
它们只能进行变异,因为Jest实际上并没有使用ES6模块.
(我想完整性可能可以Jest通过使用ES6模块Node的实验性支持来运行实际的ES6模块,但我还没试过).
我想这是一个正在运行的babel插件 - 转换模块......有没有关于此的文档?
" babel-jest在安装Jest时自动安装,如果项目中存在babel配置,它将自动转换文件.为避免这种情况,您可以显式重置transform配置选项".
所以默认情况下Jest会使用babel-jest它来转换源代码babel(并做一些其他事情,如提升调用jest.mock).
请注意,Jest也可以使用transform哪些映射将"正则表达式映射到变换器的路径".
有没有办法查看转换后的代码?
是.变换是做jest-runtime 在这里和输出保存到缓存这里.
查看已转换代码的最简单方法是查看缓存.
您可以通过运行选项来执行此操作,Jest该--showConfig选项将config在运行时输出使用的选项Jest.通过查看"cacheDirectory"的值可以找到缓存位置.
然后运行Jest与--clearCache选项,以清除高速缓存.
最后,Jest正常运行,缓存目录将包含项目的已转换代码.
例
最新的Jest(v24)将转换此代码:
// lib.js
export const someFunc = () => 1;
// code.js
import { someFunc } from './lib';
export const func = () => someFunc() + 1;
// code.test.js
import { func } from './code';
import * as lib from './lib';
test('func', () => {
const spy = jest.spyOn(lib, 'someFunc');
func();
expect(spy).toHaveBeenCalled(); // SUCCESS
});
Run Code Online (Sandbox Code Playgroud)
......对此:
// lib.js
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.someFunc = void 0;
const someFunc = () => 1;
exports.someFunc = someFunc;
// code.js
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.func = void 0;
var _lib = require("./lib");
const func = () => (0, _lib.someFunc)() + 1;
exports.func = func;
// code.test.js
"use strict";
var _code = require("./code");
var lib = _interopRequireWildcard(require("./lib"));
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
test('func', () => {
const spy = jest.spyOn(lib, 'someFunc');
(0, _code.func)();
expect(spy).toHaveBeenCalled(); // SUCCESS
});
Run Code Online (Sandbox Code Playgroud)
该import * as lib from 'lib';线路由引擎罩下的_interopRequireWildcard使用处理require.
每次调用require "将获得完全相同的对象返回,如果它将解析为同一个文件",所以code.js并code.test.js从中获取相同的对象require('./lib').
someFunc导出exports.someFunc,允许重新分配.
所以,是的,你是完全正确的.像这样进行间谍(或嘲弄)只会起作用,因为ES6模块正以一种允许它们变异的方式被babel转换成Node模块.
| 归档时间: |
|
| 查看次数: |
273 次 |
| 最近记录: |