C3: Jest์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ ค๋ฉด require()๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2017๋…„ 08์›” 07์ผ  ยท  13์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: c3js/c3

TypeError: Cannot read property 'prototype' of undefined

      at ../../../../node_modules/c3/c3.js:2720:30
      at ../../../../node_modules/c3/c3.js:3263:3
      at Object.<anonymous>.CLASS.target (../../../../node_modules/c3/c3.js:2:82)
      at Object.<anonymous> (../../../../node_modules/c3/c3.js:5:2)

์ด๋‹ค

        window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {

์ด๊ฒƒ์„ ์–ด๋””์— ์‹ ๊ณ ํ•ด์•ผ ํ• ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋†๋‹ด, jsdom, ์—ฌ๊ธฐ?

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

@fernandes ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ์กฐ๊ธˆ ๋” ๊ฐ€์ง€๊ณ  ๋†€์•˜๊ณ  c3์„ ์กฐ๋กฑํ•˜์—ฌ ์Šค๋ƒ…์ƒท ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

// __mocks__/c3.js
module.exports = () => 'c3';

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‚ด package.json ์˜ Jest ๊ตฌ์„ฑ ๋ถ€๋ถ„์—์„œ :

"moduleNameMapper": {
  "c3": "<rootDir>/__mocks__/c3.js",
}

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

๋˜ํ•œ ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. c3 ๋˜๋Š” jsdom์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋นˆ npm ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค์Œ์„ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค.

npm i -S c3 jsom
node -e "var JSDOM = require('jsdom').JSDOM; global.window = new JSDOM().window; require('c3');"

์‚ฐ์ถœ:

/home/herinson/example/node_modules/c3/c3.js:2720
        window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {
                             ^

TypeError: Cannot read property 'prototype' of undefined
    at /home/herinson/example/node_modules/c3/c3.js:2720:30
    at /home/herinson/example/node_modules/c3/c3.js:3263:3
    at CLASS.target (/home/herinson/example/node_modules/c3/c3.js:2:82)
    at Object.<anonymous> (/home/herinson/example/node_modules/c3/c3.js:5:2)
    at Module._compile (module.js:573:30)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Module.require (module.js:517:17)

์ด์ „์—๋Š” ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
์•„๋งˆ๋„ ์ด๊ฒƒ๊ณผ ๊ด€๋ จ์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค https://github.com/tmpvar/jsdom/pull/1445

SVGPathElement ์†์„ฑ์„ ์กฐ๋กฑํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

๋‚˜๋Š” ๋ถ„๋ช…ํžˆ jsdom์˜ ๋ถˆ์™„์ „ํ•œ SVG ๊ตฌํ˜„์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ข‹์€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? jsdom/jest์— ์ข…์†์„ฑ์œผ๋กœ C3๊ฐ€ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹จ์œ„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ๊ฝค ํฐ ์ฐจ๋‹จ๊ธฐ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ C3 ๊ธฐ๋Šฅ ์ค‘ ์–ด๋–ค ๊ฒƒ๋„ ๋‹จ์œ„ ํ…Œ์ŠคํŠธํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์Šคํ…์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค...

SVGPathElement ์†์„ฑ์„ ์กฐ๋กฑํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

๊ทธ๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ ํ•ด๊ฒฐ์ฑ…์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” c3๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋„ ์•Š์ง€๋งŒ ์•„๋งˆ๋„ ๋‚ด ํ”„๋กœ์ ํŠธ์˜ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๋Š” ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‚ด ํ…Œ์ŠคํŠธ๋Š” ๋งŽ์€ ์ข…์†์„ฑ์„ ์—…๋ฐ์ดํŠธํ•  ๋•Œ๊นŒ์ง€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์—ฌ์ „ํžˆ c3๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ข…์†์„ฑ์„ ํŒŒ์•…ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ถ”์‹ : jsdom์€ ๋‚ด ํ…Œ์ŠคํŠธ ํŒŒ์ผ์— ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์„ ๋ฐœ๊ฒฌ! ๋‚ ์นด๋กœ์šด-js๋ฅผ v3.4.1๋กœ ๋กค๋ฐฑํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ "ํ•ด๊ฒฐ"๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ๋ฒ„์ „์€ 4.0.0์ž…๋‹ˆ๋‹ค.

๋‚˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์‚ฌ๋žŒ์˜ ๊ฒฝ์šฐ Keen์€ ๊ธฐ๋ณธ ํŒจํ‚ค์ง€๋ฅผ 3๊ฐœ์˜ ๊ฐœ๋ณ„ ํŒจํ‚ค์ง€๋กœ ๋‚˜๋ˆ„๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/keen/keen-js/releases/tag/v4.0.0

๋ฌธ์ œ๋Š” sharp-dataviz.js๊ฐ€ c3.js๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ฐจํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜์˜ ๊ฒฝ์šฐ ํ•ด๊ฒฐ์ฑ…์€ ์˜ˆ๋ฆฌํ•œ ์ถ”์ ์„ ์„ค์น˜ํ•˜๊ณ  ์˜ˆ๋ฆฌํ•œ js๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

jest ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ์œผ๋ฉฐ

    TypeError: Cannot read property 'prototype' of undefined

      at node_modules/c3/c3.js:2806:30
      at node_modules/c3/c3.js:3349:3

ํ–‰ ๋ฒˆํ˜ธ์˜ ์•ฝ๊ฐ„์˜ ์ฐจ์ด์ , ์•„๋งˆ๋„ ์ผ๋ถ€ ๋นŒ๋“œ ๊ด€๋ จ(์ €๋Š” c3 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค: 0.4.18)

์—…๋ฐ์ดํŠธ: window.SVGPathElement.prototype.createSVGPathSegClosePath = function () ๋Š” ์—ฌ๊ธฐ์—๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”์‹ : ๋ธŒ๋ผ์šฐ์ €์—์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋†๋‹ด์œผ๋กœ ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด https://github.com/tmpvar/jsdom/issues/1423์— ๋Œ€ํ•œ ๋‹ต์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

@brandonros
jest ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์—์„œ c3 ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด SVGPathElement๋ฅผ ๋”๋ฏธ ๊ฐ์ฒด๋กœ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ด ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด window.SVGPathElement๋ฅผ ๋”๋ฏธํ™”ํ•˜์—ฌ ๋…ธ๋“œ ํ™˜๊ฒฝ์—์„œ c3.js๋ฅผ ์š”๊ตฌํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

var JSDOM = require('jsdom').JSDOM;
global.window = new JSDOM().window;
window.SVGPathElement = function () {};
console.log(require('c3')); // => no error!

@fernandes ์ €๋„ ๋น„์Šทํ•œ ๋ฌธ์ œ์— ์ง๋ฉดํ•ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์Šต๋‹ˆ๊นŒ?

์•ˆ๋…• @esonmez , ๋‚˜๋Š” ...

jsdom์ด SVG๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์กฐ์‚ฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ(jdsom์„ ์‚ฌ์šฉํ•˜๋Š”)์—์„œ c3๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ํ•œ c3 ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ์ด ํ…Œ์ŠคํŠธ๋ฅผ ์ค‘๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

@fernandes ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ์กฐ๊ธˆ ๋” ๊ฐ€์ง€๊ณ  ๋†€์•˜๊ณ  c3์„ ์กฐ๋กฑํ•˜์—ฌ ์Šค๋ƒ…์ƒท ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

// __mocks__/c3.js
module.exports = () => 'c3';

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‚ด package.json ์˜ Jest ๊ตฌ์„ฑ ๋ถ€๋ถ„์—์„œ :

"moduleNameMapper": {
  "c3": "<rootDir>/__mocks__/c3.js",
}

ํ•˜ํ•˜ํ•˜ ํฅ๋ฏธ๋กญ๋„ค์š”. ํŒ์„ ๊ณต์œ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@esonmez ์˜ ์ œ์•ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ฒŒ ๋˜์–ด

Out of the box, Create React App only supports overriding these Jest options:

  โ€ข collectCoverageFrom
  โ€ข coverageReporters
  โ€ข coverageThreshold
  โ€ข snapshotSerializers.

These options in your package.json Jest configuration are not currently supported by Create React App:

  โ€ข moduleNameMapper

If you wish to override other Jest options, you need to eject from the default setup. You can do so by running npm run eject but remember that this is a one-way operation. You may also file an issue with Create React App to discuss supporting more options out of the box.

ํ•œ๋งˆ๋””๋กœ ์‹ค๋ง์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ์šฐ๋ฆฌ์˜ jest ์„ค์ • ํŒŒ์ผ์—์„œ @kt3k ๊ฐ€ ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์กฐ๋กฑํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

global.SVGPathElement = function () {}

๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ๋งค๋ ฅ์ฒ˜๋Ÿผ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘ ๋„์™€์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

C3.js์™€ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(react, vuejs, ..) ๊ฐ„์˜ ์ƒํ˜ธ ์ž‘์šฉ๊ณผ ๊ด€๋ จ๋œ ์งˆ๋ฌธ์€ https://groups.google.com/forum/#!forum/c3js ์—์„œ Google ๊ทธ๋ฃน์„ ์‚ฌ์šฉ

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

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