Jsdom: localstorage๋Š” jsdom ๋‚ด์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค

์— ๋งŒ๋“  2015๋…„ 05์›” 28์ผ  ยท  29์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jsdom/jsdom

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„,

๋ˆ„๊ตฐ๊ฐ€ jsdom์—์„œ localStorage/sessionStorage API๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋ฌธ์•ˆ ์ธ์‚ฌ,
์•Œ๋ฐ”๋กœ

best-fixed-by-webidl2js feature html living standard

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

@justinmchase ์˜ ์†”๋ฃจ์…˜์€ ํ…Œ์ŠคํŠธ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. sessionStorage๋„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    var jsdom = require('jsdom').jsdom;
    document = jsdom('hello world');
    window = document.defaultView;
    navigator = window.navigator;
    window.localStorage = window.sessionStorage = {
        getItem: function (key) {
            return this[key];
        },
        setItem: function (key, value) {
            this[key] = value;
        }
    };

FAIK ์ด๊ฒƒ์€ ์ž˜ ์กฐ๋กฑํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ํ…Œ์ŠคํŠธ ์ค‘ ์ผ๋ถ€๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”.

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

๋ถˆํ–‰ํžˆ๋„ ES2015 ํ”„๋ก์‹œ ์—†์ด๋Š” ๋งค์šฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. (. getItem/setItem/etc.๊ฐ€ ์ž‘๋™ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์†์„ฑ ์ˆ˜์ •์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ์šฉํ•˜๋Š” ๊ฒƒ์€ ์‹ค์ œ๋กœ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ ์–ด๋„ ์ธ๋ฉ”๋ชจ๋ฆฌ ๊ฒฝํ—˜, ์ฆ‰ sessionStorage์™€ ์œ ์‚ฌํ•œ ๋™์ž‘์„ ๊ฐ–๋Š” localStorage๊ฐ€ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋œ ๋ณต์žกํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

์•„๋‹ˆ์š”. API๋ฅผ ์ถฉ๋ถ„ํžˆ ์—๋ฎฌ๋ ˆ์ดํŠธํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€(์˜ˆ: getItem/setItem๋งŒ ์‚ฌ์šฉ)์˜ ๊ฒฝ์šฐ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์†์„ฑ์— ์ง์ ‘ ์•ก์„ธ์Šคํ•˜๋Š” ์ฆ‰์‹œ ๊ตฌํ˜„์ด ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค.

@Sebmaster : ๋ณ„๋„์˜ ํŒจํ‚ค์ง€์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์Šคํ† ๋ฆฌ์ง€ ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ shim์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

https://github.com/mnahkies/node-storage-shim

ํ˜„์žฌ ์ผ์‹œ์ ์ธ ์†”๋ฃจ์…˜์ด๋ฉฐ ์Šคํ† ๋ฆฌ์ง€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์„œ๋“œ ์ด๋ฆ„๊ณผ ์ถฉ๋Œํ•˜๋Š” ํ‚ค ์„ค์ •์„ ๊ธˆ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํ˜„์žฌ ์‚ฌ์–‘์˜ ์ด๋ฒคํŠธ ๋ฐœ์ƒ ๋ถ€๋ถ„์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‹ค์ œ localStorage๋Š” setItem์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ํ‚ค๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์†์„ฑ ์•ก์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋Šฅ ์ •์˜๊ฐ€ ๋‚ ์•„๊ฐ€๊ณ  ์ผ๋‹จ ์„ค์ •๋˜๋ฉด ์†์„ฑ ์•ก์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ํ‚ค์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ์ œํ•œ ์‚ฌํ•ญ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๊ฝค ์ถฉ์‹คํ•œ ๊ตฌํ˜„์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
https://github.com/mnahkies/node-storage-shim/blob/master/test.js

API์˜ ์–ด๋–ค ์ธก๋ฉด์„ ์ถฉ๋ถ„ํžˆ ์—๋ฎฌ๋ ˆ์ดํŠธํ•  ์ˆ˜ ์—†๋Š”์ง€ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ํ˜„์žฌ ์—๋ฎฌ๋ ˆ์ดํŠธํ•  ์ˆ˜ ์—†๋Š” ์ฃผ์š” ์‚ฌํ•ญ์€ ์†์„ฑ ์„ค์ •์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ์Šคํ† ๋ฆฌ์ง€ ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค.

์–ธ๊ธ‰๋œ ์ฃผ์˜ ์‚ฌํ•ญ์œผ๋กœ ์ถฉ๋ถ„ํžˆ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋ฉด jsdom๊ณผ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

API์˜ ์–ด๋–ค ์ธก๋ฉด์„ ์ถฉ๋ถ„ํžˆ ์—๋ฎฌ๋ ˆ์ดํŠธํ•  ์ˆ˜ ์—†๋Š”์ง€ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

localStorage๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ง์ ‘ ์†์„ฑ ์ด๋ฆ„ ์„ค์ •์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

localStorage.myKey = "myVal";
localStorage.getItem('myKey') // 'myVal'

localStorage.setItem('otherKey', 'val')
localStorage.otherKey // 'val'

setItem์ด ํ˜ธ์ถœ๋˜๋ฉด ํ•ญ์ƒ getter๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์–ด๋Š ์ •๋„ ์—๋ฎฌ๋ ˆ์ดํŠธํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ”„๋ก์‹œ ์—†์ด๋Š” ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ(๊ฐ์ฒด์— ์ž„์˜ ์†์„ฑ ์„ค์ •)์„ ์ง€์›ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋งž์Šต๋‹ˆ๋‹ค. ์†์„ฑ ์•ก์„ธ์Šค๋กœ ํ‚ค๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ๋œ ์ฃผ์š” ๋ฌธ์ œ๋Š” ์‹ค์ œ ์ธํ„ฐํŽ˜์ด์Šค์ฒ˜๋Ÿผ ๊ฐ’์„ ๋ฌธ์ž์—ด๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฐ•์ œ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋„ค, ์ด๋Š” ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์˜ ๋งค์šฐ ์ค‘์š”ํ•œ ์ธก๋ฉด์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ES6 ํ”„๋ก์‹œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. v8์€ ์•„์ง ์ด๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค(microsoft์™€ mozilla๋Š” ์ด๋ฏธ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค!)

์šฐ๋ฆฌ๋Š” jsdom์˜ ์—ฌ๋Ÿฌ ์œ„์น˜์—์„œ ๋™์ผํ•œ ๋กœ๋“œ ๋ธ”๋ก์„ ์น˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

var localStorage = {
  getItem: function (key) {
    return this[key];
  },
  setItem: function (key, value) {
    this[key] = value;
  }
};

localStorage.setItem('foo', 'bar');
localStorage.bar = 'foo'
assert(localStorage.foo === 'bar')
assert(localStorage.getItem('bar') === 'foo')

๋‚ด๊ฐ€ ๋ฌด์—‡์„ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์†์„ฑ ์•ก์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ญ๋ชฉ์„ ์„ค์ •ํ•  ๋•Œ ์‹ค์ œ localStorage๋Š” ํ•ญ์ƒ ๊ฐ’์„ ๋ฌธ์ž์—ด๋กœ ๊ฐ•์ œ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

localStorage.foo = 35
assert(typeof localStorage.foo === "string")

localStorage.foo = {my: 'object'}
assert(localStorage.foo === "[object Object]")

์ด๊ฒƒ์€ ES6 ํ”„๋ก์‹œ ์—†์ด๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉฐ localStorage์˜ ์ค‘์š”ํ•œ ํŠน์„ฑ์ž…๋‹ˆ๋‹ค.

์•Œ ๊ฒ ์–ด์š”. ๋น„๋ก ๋‹น์‹ ์ด ๊ทธ ์ˆ˜์น˜๋ฅผ ๋‹น์‹ ์—๊ฒŒํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ;)

๋” ์ค‘์š”ํ•œ ๊ฒƒ์€ ๊ฐ์ฒด๋กœ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒฝ์šฐ jsdom์— ์˜ํ•ด ๋งˆ์Šคํ‚น๋œ ๋‹ค์Œ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฒ„๊ทธ์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

+1

+1

์•„๋งˆ๋„ ์ด์™€ ๊ฐ™์€ ๊ฒƒ์ด https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage ?

์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์‹ค์ œ ๋กœ์ปฌ ์ €์žฅ์†Œ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ผ๋ถ€ ๋™์ž‘์„ ์—ฌ์ „ํžˆ ๋†“์น˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ๋œ ์†”๋ฃจ์…˜์€ ์ข‹์€ ํด๋ฆฌํ•„์„ ๋งŒ๋“ค์ง€๋งŒ jsdom์— ๋Œ€ํ•œ ์ถฉ์‹คํ•œ ๊ตฌํ˜„์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@mnahkies ์†”์งํžˆ, polyfill์€ ์—†๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚ซ์Šต๋‹ˆ๋‹ค(์ง€๊ธˆ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค). ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์„ ๋„ฃ๊ณ  99%์˜ ์‚ฌ๋žŒ๋“ค์ด ์–ด์จŒ๋“  ๋ถ€๋”ชํžˆ์ง€ ์•Š์„ ํ•œ๊ณ„์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰ ์ฃผ์„์— +1, MDN์˜ ์˜ˆ ๋Š” setItem ๋ฐ getItem ๋ฅผ ์ €์žฅ์†Œ์— ๋Œ€ํ•œ ์ ‘๊ทผ์ž๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๊ฐ€ ์‹ค์ œ๋กœ ๋†“์น˜๊ณ  ์žˆ๋Š” ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ jasmine.createSpy ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

@justinmchase ์˜ ์†”๋ฃจ์…˜์€ ํ…Œ์ŠคํŠธ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. sessionStorage๋„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    var jsdom = require('jsdom').jsdom;
    document = jsdom('hello world');
    window = document.defaultView;
    navigator = window.navigator;
    window.localStorage = window.sessionStorage = {
        getItem: function (key) {
            return this[key];
        },
        setItem: function (key, value) {
            this[key] = value;
        }
    };

FAIK ์ด๊ฒƒ์€ ์ž˜ ์กฐ๋กฑํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ํ…Œ์ŠคํŠธ ์ค‘ ์ผ๋ถ€๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”.

๋ˆ„๊ตฐ๊ฐ€ ์‹ค์ˆ˜๋กœ ์†์„ฑ ์•ก์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ ์ €์žฅ์†Œ์— ๊ฐœ์ฒด๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋ฏธ๋ฌ˜ํ•œ ๋ฒ„๊ทธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๊นŒ์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

์ œ ์ƒ๊ฐ์—๋Š” ํ…Œ์ŠคํŠธ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ์†”๋ฃจ์…˜์œผ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๋Š” ์Šค์™‘ ๊ฐ€๋Šฅํ•œ ์Šคํ† ๋ฆฌ์ง€ ๋ฐฑ์—”๋“œ๋กœ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์ถ”์ƒํ™”ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‚˜์ค‘์— ํ•„์š”ํ•  ๊ฒฝ์šฐ ์•”ํ˜ธํ™”, ์••์ถ•, ์บ์‹ฑ์„ ํ†ตํ•œ ์“ฐ๊ธฐ ๋“ฑ๊ณผ ๊ฐ™์€ ๋ณต์žกํ•œ ์ž‘์—…์„ ๋” ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋•Œ๊ฐ€๋๋‹ค!!!

Node.js v6์ด ๋‚˜์™”๊ณ , ๊ทธ๊ฒƒ๊ณผ ํ•จ๊ป˜... PROXIES.

@Sebmaster , ๋ช…๋ช…๋œ getters/setters/deleters๊ฐ€ ์žˆ์„ ๋•Œ ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก webidl2js๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? NamedNodeMap์ด๋‚˜ NodeList ๋“ฑ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ฒƒ๋“ค์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•˜๊ธฐ ์ „์— ๋จผ์ € ์ด ์š”์ฒญ์„ ๋Œ€์ƒ์œผ๋กœ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ›Œ๋ฅญํ•˜๊ณ  ๋…๋ฆฝ์ ์ด๋ฉฐ ํ•ต์‹ฌ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ์˜ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

https://html.spec.whatwg.org/multipage/webstorage.html#storage -2์—๋Š” ์ง€์›ํ•ด์•ผ ํ•˜๋Š” IDL์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐˆ ๋ฐฉ๋ฒ•์€ ๋‹จ์ˆœํžˆ ํ”„๋ก์‹œ์˜ get ๋™์ž‘ ๋Œ€๋ฆฌ์ž๋ฅผ impl์˜ getItem ๋“ฑ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

+1

node-localstorage๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

var LocalStorage = require('node-localstorage').LocalStorage;
global.localStorage = new LocalStorage('./build/localStorageTemp');

global.document = jsdom('');

global.window = document.defaultView;
global.window.localStorage = global.localStorage;

@adjavaherian @justinmchase ๋‚˜๋Š” react-jwt-auth ์™€ react-jwt-auth-redux ๋ชจ๋‘์—์„œ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” jsdom์„ ๊ฐ€์ง€๊ณ  ๋†€๊ณ  ์žˆ์—ˆ๊ณ  ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๋˜ํ•œ ๋™ํ˜• ๊ฐœ๋ฐœ์„ ์œ„ํ•œ enverse - ํ™˜๊ฒฝ ๊ฒ€์‚ฌ์— ๋Œ€ํ•ด ์ผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜ํ‘œ ์ค‘ ํ•˜๋‚˜๋Š” localStorage ๋ฐ sessionStorage ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋™์ผํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ •ํ™•ํžˆ ์‹คํ–‰ํ–ˆ์œผ๋ฉฐ ๊ท€ํ•˜์˜ polyfil์€ ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๊ธฐ๋ณธ์ ์œผ๋กœ jsdom์ด ํ•จ๊ป˜ ์ œ๊ณต๋œ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•œ webidl2js ์ง€์›์ด ์ด์ œ ์ œ์ž๋ฆฌ์— ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ์ด๊ฒƒ์„ ๋ฐ›์•„๋“ค์ด๊ณ  ์‹ถ๋‹ค๋ฉด ์ตœ๊ทผ์— ๋‚˜์˜จ DOMStringList ๊ตฌํ˜„(๋ฐ์ดํ„ฐ ์„ธํŠธ์šฉ)์„ ์—ฐ๊ตฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ๋กœ์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ๋ฉ”๋ชจ๋ฆฌ์— ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ฒฐ๊ตญ ์‚ฌ๋žŒ๋“ค์ด ์›ํ•  ๊ฒฝ์šฐ ๋””์Šคํฌ์— ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (์‚ฌ๋žŒ๋“ค์ด ๊ทธ๊ฑธ ์›ํ•ด?)

์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ‚ค๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ, ๋•Œ๋ฌธ์—์ด ๋ชจํ˜•์€ ์ž˜ ์ž‘๋™ localStorage.getItem() ๋ฐ˜ํ™˜ํ•˜๋„๋ก๋˜์–ด null ํ•˜์ง€ undefined :

const jsdom = require('jsdom');
// setup the simplest document possible
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');;

// get the window object out of the document
const win = doc.defaultView;

win.localStorage = win.sessionStorage = {
  getItem: function(key) {
    const value = this[key];
    return typeof value === 'undefined' ? null : value;
  },
  setItem: function (key, value) {
    this[key] = value;
  },
  removeItem: function(key) {
    return delete this[key]
  }
};

// set globals for mocha that make access to document and window feel
// natural in the test environment
global.document = doc;
global.window = win;

์™œ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋ž˜ ์ค„์€ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. json.parse() undefined ๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋ฉด json.parse() ๊ฐ€ ์‹คํŒจํ•˜์ง€๋งŒ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ null ํ•˜๋ฉด ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

let users = JSON.parse(localStorage.getItem('users')) || [];

@simoami win.localStorage = win.sessionStorage = { ... } ์—ฐ๊ฒฐ๋˜๋Š” ํ• ๋‹น์„ ์กฐ์‹ฌํ•˜์„ธ์š”. ๋‘ ๋ณ€์ˆ˜์— ํ• ๋‹น๋œ ๋™์ผํ•œ ๊ฐœ์ฒด ์ฐธ์กฐ์ด๋ฏ€๋กœ ๋‘˜ ์ค‘ ํ•˜๋‚˜์˜ get/set ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋™์ผํ•œ ๊ธฐ๋ณธ ๊ฐœ์ฒด์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด localStorage.set('foo', 'bar') ํ˜ธ์ถœํ•˜๋ฉด sessionStorage.get('foo') ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ์—์„œ๋Š” ๊ดœ์ฐฎ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ณ„๋„์˜ ์ €์žฅ ๊ณต๊ฐ„์ด ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์€ ์—‰๋ง์ด ๋ฉ๋‹ˆ๋‹ค.

https://gist.github.com/rkurbatov/17468b2ade459a7498c8209800287a03 - ์ด ํด๋ฆฌํ•„์„ ๋กœ์ปฌ/์„ธ์…˜ ์Šคํ† ๋ฆฌ์ง€ ๋ชจ๋‘์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. @capaj์˜ https://github.com/capaj/localstorage-polyfill ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜์ค‘์— ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ•œ ์‚ฌ๋žŒ๋“ค์€ ์ตœ๊ทผ jsdom ๊ฐœ์„  ํ›„์— window._localStorage ๋ฅผ ์ž์‹ ์˜ ๋ชจ์˜ ์ €์žฅ์†Œ๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ”ผ๋“œ๋ฐฑ์œผ๋กœ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ ์–ธ๊ธ‰๋œ ๊ธฐ๋ณธ localStorage ์ด๋ฒคํŠธ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  jsdom์„ ๋ณ‘๋ ฌ๋กœ ์‚ฌ์šฉํ•˜๊ณ  localStorage๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์—๊ฒŒ๋Š” node-localstorage ๋“ฑ์€ ๊ฑฐ์˜ ์“ธ๋ชจ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๋ฐ”ํ€ด๋ฅผ ๋‹ค์‹œ ๋ฐœ๋ช…ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ณ‘๋ ฌ ์‚ฌ์šฉ์„ ์œ„ํ•ด ์„ค๊ณ„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. for(var key in localStorage) ๋˜๋Š” Object.keys(localStorage) ๋“ฑ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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