Jsdom: ๋ชจ์˜ ์บ”๋ฒ„์Šค

์— ๋งŒ๋“  2017๋…„ 03์›” 22์ผ  ยท  25์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jsdom/jsdom

์‹ค์ œ ๊ตฌํ˜„ ์—†์ด ์บ”๋ฒ„์Šค๋ฅผ ๋ชจ์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ( canvas / canvas-prebuilt )?

์บ”๋ฒ„์Šค ๊ธฐ๋Šฅ์ด ๋‚˜์—๊ฒŒ ์‹ค์ œ๋กœ ์ค‘์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‹ค์Œ์€ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•ด๋‚ธ ์บ”๋ฒ„์Šค๋ฅผ ์กฐ๋กฑํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

//
// Mock Canvas / Context2D calls
//
function mockCanvas (window) {
    window.HTMLCanvasElement.prototype.getContext = function () {
        return {
            fillRect: function() {},
            clearRect: function(){},
            getImageData: function(x, y, w, h) {
                return  {
                    data: new Array(w*h*4)
                };
            },
            putImageData: function() {},
            createImageData: function(){ return []},
            setTransform: function(){},
            drawImage: function(){},
            save: function(){},
            fillText: function(){},
            restore: function(){},
            beginPath: function(){},
            moveTo: function(){},
            lineTo: function(){},
            closePath: function(){},
            stroke: function(){},
            translate: function(){},
            scale: function(){},
            rotate: function(){},
            arc: function(){},
            fill: function(){},
            measureText: function(){
                return { width: 0 };
            },
            transform: function(){},
            rect: function(){},
            clip: function(){},
        };
    }

    window.HTMLCanvasElement.prototype.toDataURL = function () {
        return "";
    }
}
const document = jsdom.jsdom(undefined, {
  virtualConsole: jsdom.createVirtualConsole().sendTo(console)
});

const window = document.defaultView;
mockCanvas(window);

๋ชจ๋“  25 ๋Œ“๊ธ€

๋ˆ„๊ตฐ๊ฐ€ ์ด๊ฒƒ์„ ํ•„์š”๋กœํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

const utils = require("jsdom/lib/jsdom/utils");
const canvasMock = require("canvas-mock");

function Canvas () {
    canvasMock(this);
    this.toDataURL = function() { return ""; }
}
utils.Canvas = Canvas;

๊ทธ๋Ÿฌ์ง€ ๋งˆ์„ธ์š”. ํ–ฅํ›„ ํŒจ์น˜ ๋ฆด๋ฆฌ์Šค์—์„œ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  getContext() ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: window.HTMLCanvasElement.prototype.getContext = ...

@domenic ๊ฐ์‚ฌ

@domenic ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ž‘๋™์‹œํ‚ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์žฌ์ •์˜๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด jest ๋ฐ ์„ค์ • ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

import { jsdom } from 'jsdom';
import mockLocalStorage from './mockLocalStorage';
import jQuery from 'jquery';
import Backbone from 'backbone';
import moment from 'moment';

const dom = jsdom('<!doctype html><html><body></body></html>');
const { window } = dom.defaultView;

function copyProps(src, target) {
    const props = Object.getOwnPropertyNames(src)
        .filter(prop => typeof target[prop] === 'undefined')
        .map(prop => Object.getOwnPropertyDescriptor(src, prop));
    Object.defineProperties(target, props);
}

//Mock canvas (used by qtip)
window.HTMLCanvasElement.prototype.getContext = () => {
    return {};
};

global.window = window;
global.document = window.document;
global.navigator = {
    userAgent: 'node.js',
};
global.localStorage = mockLocalStorage;
global.jQuery = jQuery;
global.$ = jQuery;
global.fetch = () => Promise.resolve();
Backbone.$ = jQuery;
copyProps(window, global);

//Mock Mousetrap (only works in browser)
jest.mock('mousetrap', () => { return { bind: () => {}}});

//Set moment locale for all tests
moment.locale('sv');

๋…ธ๋“œ์˜ ์ „์—ญ์„ ์˜ค์—ผ์‹œ์ผœ ์ฃ„์†กํ•˜์ง€๋งŒ Jest๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋ ค๊ณ  ํ•˜๋Š” ๋งค์šฐ ์˜ค๋ž˜๋˜๊ณ  ํฐ ์ฝ”๋“œ ๊ธฐ๋ฐ˜์ž…๋‹ˆ๋‹ค.
๋†๋‹ด ๋ฒ„์ „: 21.2.1
Jsdom ๋ฒ„์ „: 9.12.0

๋ชจ์˜ ์บ”๋ฒ„์Šค(Windows์—์„œ ์ง€์›๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์บ”๋ฒ„์Šค ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ)๊ฐ€ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์˜๊ฒฌ์ด ์•„๋‹ˆ๋ผ ๊ณต์‹ ๋ฌธ์„œ์—์„œ ๋‹ค๋ฃจ์–ด์ง„๋‹ค๋ฉด ๋งค์šฐ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Windows์—์„œ ์ง€์›๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์บ”๋ฒ„์Šค ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ 

์บ”๋ฒ„์Šค ์‚ฌ์ „ ์ œ์ž‘ ์˜ต์…˜์ด ์•„๋‹Œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ด๊ฒƒ์ด ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ ๋ฌธ์ œ ์—†์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(Win, Mac ๋ฐ Linux, ๋ชจ๋“  ๊ฒƒ์ด x64์—ฌ์•ผ ํ•˜์ง€๋งŒ).

์ผ๋ฐ˜์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ผํšŒ์„ฑ ๋ชจ์˜ ๋ฌธ์ œ๋ฅผ ๋„์šธ ๊ณ„ํš์ด ์—†์Šต๋‹ˆ๋‹ค. https://github.com/tmpvar/jsdom#intervening -before-parsing ์ผ๋ฐ˜์ ์œผ๋กœ ์ด ๋‚ด์šฉ์„ ๋‹ค๋ฃจ์—ˆ์œผ๋ฉฐ ํŠน์ • ๋ฌธ์ œ๋Š” ํŠน์ • ์ฝ”๋“œ๋ฒ ์ด์Šค์™€ ๊ด€๋ จ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•ด๋‚ธ ์บ”๋ฒ„์Šค๋ฅผ ์กฐ๋กฑํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

//
// Mock Canvas / Context2D calls
//
function mockCanvas (window) {
    window.HTMLCanvasElement.prototype.getContext = function () {
        return {
            fillRect: function() {},
            clearRect: function(){},
            getImageData: function(x, y, w, h) {
                return  {
                    data: new Array(w*h*4)
                };
            },
            putImageData: function() {},
            createImageData: function(){ return []},
            setTransform: function(){},
            drawImage: function(){},
            save: function(){},
            fillText: function(){},
            restore: function(){},
            beginPath: function(){},
            moveTo: function(){},
            lineTo: function(){},
            closePath: function(){},
            stroke: function(){},
            translate: function(){},
            scale: function(){},
            rotate: function(){},
            arc: function(){},
            fill: function(){},
            measureText: function(){
                return { width: 0 };
            },
            transform: function(){},
            rect: function(){},
            clip: function(){},
        };
    }

    window.HTMLCanvasElement.prototype.toDataURL = function () {
        return "";
    }
}
const document = jsdom.jsdom(undefined, {
  virtualConsole: jsdom.createVirtualConsole().sendTo(console)
});

const window = document.defaultView;
mockCanvas(window);

์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์บ”๋ฒ„์Šค ์‚ฌ์ „ ๋นŒ๋“œ ํŒจํ‚ค์ง€๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @cattermo ์ž…๋‹ˆ๋‹ค .
๋‚ด deps์— ๋ฏธ๋ฆฌ ๋นŒ๋“œ๋œ ์บ”๋ฒ„์Šค๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด jest ๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋‚˜์—๊ฒŒ ์ œ๊ณตํ•˜๋Š” ์ž‘๋™ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค
Not implemented: HTMLCanvasElement.prototype.toBlob (without installing the canvas npm package)

@micabe
๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. Jsdom์€ node_modules์— ์žˆ๋Š” ๊ฒฝ์šฐ ๋ฏธ๋ฆฌ ๋นŒ๋“œ๋œ ์บ”๋ฒ„์Šค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

ํŠน์ • ๊ธฐ๋Šฅ์ด ์ง€์›๋˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ์•„๋‹๊นŒ?

yarn cache clean ์ดํ›„์— ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ฒˆ๊ฑฐ๋กญ๊ฒŒ ํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค! @cattermo ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

์•„๋งˆ๋„ jest-canvas-mock ์ด ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์†”๋ฃจ์…˜์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. canvas ๋ฅผ devDependency๋กœ ์„ค์น˜ํ•˜๊ณ  jest ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๊ธฐ

์ฐธ์กฐ: https://github.com/jsdom/jsdom#canvas -support

jsdom์ด lib/jsdom/utils.js์—์„œ ์บ”๋ฒ„์Šค ๋ชจ๋“ˆ์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  exports.Canvas = require(moduleName);
  if (typeof exports.Canvas !== "function") {
    // In browserify, the require will succeed but return an empty object
    exports.Canvas = null;
  }

require('canvas')๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด Canvas ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” Object๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. Canvas ํ•จ์ˆ˜๋ฅผ ๋ฐ”๋กœ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋‚ด๊ฐ€ ์ž˜๋ชป ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ์บ”๋ฒ„์Šค์— ๋ฏธ๋ฆฌ ๋นŒ๋“œ๋œ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ž˜ ์ž‘๋™ํ–ˆ์ง€๋งŒ ์บ”๋ฒ„์Šค ๋ชจ๋“ˆ์— ๋‹ค๋ฅธ API๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์บ”๋ฒ„์Šค์˜ ์ตœ์‹  ๋ฒ„์ „์ธ 2.0.1์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
ํŽธ์ง‘ํ•˜๋‹ค
์ด์ „ ์ฃผ ๋ฒ„์ „(1.6.x)์„ ํ…Œ์ŠคํŠธํ–ˆ๋Š”๋ฐ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. JSDOM์ด ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š” API ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ๊ทธ๋ƒฅ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

HTMLCanvasElement.prototype.getContext = jest.fn()

์‹ค์ œ ๊ตฌํ˜„์ด ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ

jsdom์ด lib/jsdom/utils.js์—์„œ ์บ”๋ฒ„์Šค ๋ชจ๋“ˆ์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  exports.Canvas = require(moduleName);
  if (typeof exports.Canvas !== "function") {
    // In browserify, the require will succeed but return an empty object
    exports.Canvas = null;
  }

require('canvas')๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด Canvas ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” Object๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. Canvas ํ•จ์ˆ˜๋ฅผ ๋ฐ”๋กœ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋‚ด๊ฐ€ ์ž˜๋ชป ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ์บ”๋ฒ„์Šค์— ๋ฏธ๋ฆฌ ๋นŒ๋“œ๋œ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ž˜ ์ž‘๋™ํ–ˆ์ง€๋งŒ ์บ”๋ฒ„์Šค ๋ชจ๋“ˆ์— ๋‹ค๋ฅธ API๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์บ”๋ฒ„์Šค์˜ ์ตœ์‹  ๋ฒ„์ „์ธ 2.0.1์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
ํŽธ์ง‘ํ•˜๋‹ค
์ด์ „ ์ฃผ ๋ฒ„์ „(1.6.x)์„ ํ…Œ์ŠคํŠธํ–ˆ๋Š”๋ฐ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. JSDOM์ด ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š” API ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

๋‚˜๋„ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ์•ˆ๊ณ ์žˆ์–ด. ์ˆ˜์ • ์‚ฌํ•ญ์ด ์–ผ๋งˆ ์ „์— https://github.com/jsdom/jsdom/pull/1964 ์— ๋ณ‘ํ•ฉ๋˜์—ˆ๊ณ  13 ๋ฒ„์ „๋ถ€ํ„ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฌธ์ œ๊ฐ€ jsdom์— ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜, jsdom ์—์„œ ๋ฒ„์ „ jest-environment-jsdom ์—ฌ์ „ํžˆ์— ๊ฐ‡ํ˜€ ^11.5.1 ๋‚˜๋Š” ๊ทธ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ์ƒ๊ฐ :
https://github.com/facebook/jest/blob/2e2d2c8deb76e71c0dfa85ed36b81d1f89e0d87/packages/jest-environment-jsdom/package.json#L14

Canvas๋ฅผ ์„ค์น˜ํ•˜์ง€ ์•Š๊ณ  canvas-prebuilt ๋Š” HTMLCanvasElement์™€ ๊ด€๋ จ๋œ ์˜ค๋ฅ˜๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  @endel ์ด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ํ•ดํ‚น์œผ๋กœ ๋ฉ‹์ง€๊ฒŒ ์ œ์•ˆํ•œ ๋‹ค๋ฅธ ์บ”๋ฒ„์Šค ๋ฐฉ๋ฒ•์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. @hustcc๊ฐ€ ์ œ์•ˆํ•œ ๊ฒƒ์ฒ˜๋Ÿผ -canvas-mock์„ ์‚ฌ์šฉ ํ•˜์—ฌ ์•„์ฃผ ๊นจ๋—ํ•œ ์†”๋ฃจ์…˜์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๊ธฐ์ˆ ์ ์ธ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ์ด ๋Œ“๊ธ€์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

"WebkitBackingStorePixelRatio of null์„ ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค"์™€ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  "
๊ตฌํ˜„๋˜์ง€ ์•Š์Œ: HTMLCanvasElement.prototype.getContext(canvas npm ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜์ง€ ์•Š์Œ)" ๋ฐ canvas(-prebuilt) ์„ค์น˜๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. package-lock.json ๋‚ด๋ถ€๋กœ ๋“ค์–ด๊ฐ€ jest-environment-jsdom์ด jsdom 13์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. , node_modules๋ฅผ ๋ฒ„๋ฆฌ๊ณ  npm install์„ ๋‹ค์‹œ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค. @paradite ๊ฐ€ ์˜ณ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ 

https://github.com/facebook/jest/issues/8016

ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ๋†๋‹ด์ด ์ด์ „ ๋…ธ๋“œ ๋ฒ„์ „๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ง€์›์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐ ํ•˜์‹ญ์‹œ์˜ค.

@grtjn - -environment-jsdom-thirteen ์ข…์†์„ฑ์„ ํ™•์ธํ–ˆ์ง€๋งŒ ์ œ ๊ฒฝ์šฐ์—๋Š” ์—ฌ์ „ํžˆ ์ด 2๊ฐœ์˜ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
TypeError: Cannot read property 'fillRect' of null

์•ž์„œ ์–ธ๊ธ‰ํ•œ ๋‚ด ์†”๋ฃจ์…˜์„ ์œ ์ง€ํ•˜๋ฉด์„œ Node ๋ฒ„์ „์— ๋Œ€ํ•ด 10.15๊ฐ€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๋งํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌํ•œ ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Angular CLI: 7.2.4
Node: 10.15.0
OS: win32 x64
Angular: 7.2.4

์ฐธ๊ณ ๋กœ ์ œ jest ๊ตฌ์„ฑ์— "testEnvironment": "jest-environment-jsdom-thirteen" ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Canvas ํŒจํ‚ค์ง€์™€ Cairo OS ๋„๊ตฌ ์„ธํŠธ๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. Canvas-prebuilt๊ฐ€ ์ €์—๊ฒŒ ํšจ๊ณผ๊ฐ€ ์—†๋Š” ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค. ์ €๋Š” ๋ทฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Cairo OS ๋„๊ตฌ ์„ธํŠธ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ๋งํฌ? ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@danieldanielecki 'canvas' ํŒจํ‚ค์ง€ ๋ฉ”์ธ ํŽ˜์ด์ง€ ์ฐธ์กฐ: https://www.npmjs.com/package/canvas#compiling

@grtjn ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์–ธ์  ๊ฐ€๋Š” ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋†“์น˜๊ณ  ์žˆ์—ˆ์ง€๋งŒ ๋‚ด ์†”๋ฃจ์…˜๋ณด๋‹ค ๋” ๋ณต์žกํ•ด ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ์ ํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

necropost์—๊ฒŒ ๋ฏธ์•ˆํ•˜์ง€๋งŒ jest -environment-jsdom-thirteen ์„ค์น˜์— ๋Œ€ํ•œ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰