Es6 全局变量在 class 中不可用

Es6 global variable not available in class

我尝试让我的 window 变量在我导入的 class 中可用。在导入的 class 中,它说 window 未定义。

我使用 mocha 和 chai 来测试我的 javascript 代码。还有 es6 部分的 babeljs。

这是我的 test.js:

import { jsdom } from 'jsdom';
import { assert } from 'chai';
import sinon from 'sinon';
import Pixels from './../src/pixels.es6';

let document, window, pixels;

describe('Pixels', () => {

    beforeEach(function () {
        let el;

        document = jsdom('<html><body></body></html>');
        window = document.defaultView;

        el = document.createElement('div');
        el.setAttribute('data-flow-id', Date.now());
        pixels = new Pixels(el);
    });

    describe('spawn()', function () {

        beforeEach(function () {
            window.dataLayer = {
                push: sinon.spy()
            };

            pixels.spawn();
        });

        afterEach(function () {
            window.dataLayer = {};
        });

        it('should push to dataLayer', function () {
            assert.isTrue(window.dataLayer.push.called);
        });

    });

});

这是导入的 class,其中 window 不可用:

import { URL } from './config.es6';
import Parse from './parse.es6';
import fetch from 'safe-fetch';

export default class Pixels {
    constructor (el) {
        console.log(window);
        this.el = el;
        this.fetch = fetch || window.fetch;
    }

    spawn () {
        this.fetch(URL, {
            reportChildRequestId: false,
            method: 'get'
        }).then(resp => {
            return resp.text();
        }).then(html => {
            // ... do stuff with html variable
        });
    }
}

mocha 调用是:mocha --require babel-core/register

有没有办法让 window 变量在 Pixels 中可用,除了在构造函数中传递它?

这是一种奇怪的行为。 我唯一能想到的可能是 let 的行为范围问题?我知道它的权限范围略有不同,但我认为因为它在全局范围内,所以这不是问题。您是否尝试过使用 var document, window, pixels; 而不是 let document, window, pixels;?除此之外,我看不出有什么问题。我希望这能有所帮助。如果你弄明白了请告诉我,其实我很好奇,谢谢!

没有理由它应该工作。 test.js 中的 window 变量在该文件的顶部范围内声明。 这不是全局的。此外,jsdom不会污染全局space。所以你不能指望它创建一个全局 window

您可以通过分配给 global.window 来让某些东西正常工作,但我不会这样做。如果您想在浏览器中测试 运行 的代码,您应该 jsdom 加载它 。这意味着将引用您的脚本的真实 HTML 页面传递给它。

我找到了 mocha-jsdom npm 包。有了这个包,我不需要创建 windowdocument,因为它会为我做这件事,而且一切都按预期工作。

更新代码:

import { jsdom } from 'mocha-jsdom';
import { assert } from 'chai';
import sinon from 'sinon';
import Pixels from './../src/pixels.es6';

let pixels;

describe('Pixels', () => {

    jsdom();

    beforeEach(function () {
        let el;

        el = document.createElement('div');
        el.setAttribute('data-flow-id', Date.now());
        pixels = new Pixels(el);
    });

    describe('spawn()', function () {

        beforeEach(function () {
            window.dataLayer = {
                push: sinon.spy()
            };

            pixels.spawn();
        });

        afterEach(function () {
            window.dataLayer = {};
        });

        it('should push to dataLayer', function () {
            assert.isTrue(window.dataLayer.push.called);
        });

    });

});