Jsdom: ์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ๋Š” ์–ด๋–ป๊ฒŒ ๋กœ๋“œํ•ฉ๋‹ˆ๊นŒ?

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

jsdom์€ ๋ฌธ์„œ์˜ <head> ํƒœ๊ทธ ๋‚ด๋ถ€์— ์ธ๋ผ์ธ์œผ๋กœ ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ <script src=""> ๋ฅผ ํ†ตํ•ด ๋ฌธ์„œ ํ—ค๋“œ์— ์—ฐ๊ฒฐ๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์˜ต์…˜์˜ ๊ฒฝ์šฐ:

{
    url: url,
    resources: 'usable',
    runScripts: 'dangerously',
}

๊ธฐ๋ณธ ์ •๋ณด:

  • Node.js ๋ฒ„์ „: 8.1.2
  • jsdom ๋ฒ„์ „: 11.1.0

์ตœ์†Œํ•œ์˜ ์žฌ์ƒ์‚ฐ ์ผ€์ด์Šค:

// index.js
const request = require('request')
const jsdom = require('jsdom')
const {JSDOM} = jsdom
const url = 'http://localhost:8000'

request(url, (error, response, body) => {
  const options = {
    url: url,
    resources: 'usable',
    runScripts: 'dangerously',
  }

  const dom = new JSDOM(body, options)

  console.log(dom.window.document.body.children.length) // Expecting to see `1`
  console.log(dom.window.document.body.innerHTML) // Expecting to see `<h1>Hello world</h1>`
})
// external.js
document.addEventListener('DOMContentLoaded', () => {
  document.write('<h1>Hello world!</h1>')
})
<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>JSDOM test</title>
    <script src="external.js"></script>
  </head>
  <body>
  </body>
</html>

์™„์ „ํ•œ ์ตœ์†Œ ์ž‘์—… ์˜ˆ์ œ: https://github.com/cg433n/jsdom-test

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

์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” DOMContentLoaded ๊ฐ€ ๋น„๋™๊ธฐ์‹ ์ด๋ฒคํŠธ๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์ด ์ผ์–ด๋‚  ๊ธฐํšŒ๊ฐ€ ์žˆ๊ธฐ ์ „์— ๊ธฐ๋กํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถˆ์ด ๋ถ™์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์•ผ๋งŒ document.write() ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

const dom = new JSDOM(body, options)

dom.window.document.addEventListener('DOMContentLoaded', () => {
  // We need to delay one extra turn because we are the first DOMContentLoaded listener,
  // but we want to execute this code only after the second DOMContentLoaded listener
  // (added by external.js) fires.
  setImmediate(() => {
    console.log(dom.window.document.body.children.length) // Expecting to see `1`
    console.log(dom.window.document.body.innerHTML) // Expecting to see `<h1>Hello world</h1>`
  });
});

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

์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” DOMContentLoaded ๊ฐ€ ๋น„๋™๊ธฐ์‹ ์ด๋ฒคํŠธ๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์ด ์ผ์–ด๋‚  ๊ธฐํšŒ๊ฐ€ ์žˆ๊ธฐ ์ „์— ๊ธฐ๋กํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถˆ์ด ๋ถ™์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์•ผ๋งŒ document.write() ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

const dom = new JSDOM(body, options)

dom.window.document.addEventListener('DOMContentLoaded', () => {
  // We need to delay one extra turn because we are the first DOMContentLoaded listener,
  // but we want to execute this code only after the second DOMContentLoaded listener
  // (added by external.js) fires.
  setImmediate(() => {
    console.log(dom.window.document.body.children.length) // Expecting to see `1`
    console.log(dom.window.document.body.innerHTML) // Expecting to see `<h1>Hello world</h1>`
  });
});

๋‚ด๊ฐ€ ์ฐธ์กฐ! ์—ฌ๋Ÿฌ๋ถ„์€ ํ™˜์ƒ์ ์ž…๋‹ˆ๋‹ค. ๊ณ„์†ํ•ด์„œ ์ข‹์€ ์ผ์„ ํ•˜์‹ญ์‹œ์˜ค!

์•Œ๋ฆผ: ์œ„ ๋ฐ๋ชจ์˜ 2๊ฐ€์ง€ ๊ธฐ๋Šฅ์€ ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค.

FS ํ•ดํ‚น

๋˜๋Š” fs FS.read() ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์—์„œ js ์ฝ”๋“œ๋ฅผ ์ฝ๊ณ  ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค addEventListener() #1914. ๋‚ด๊ฐ€ ์ œ์•ˆํ•˜๋Š” ์ž‘์—… ๋ฐ๋ชจ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • fs.readFileSync ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์™ธ๋ถ€ js๋ฅผ html์— ๋ฌธ์ž์—ด๋กœ ๋กœ๋“œ
  • ์—ฌ๋Ÿฌ ์™ธ๋ถ€ js ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฃจํ”„
  • ์™ธ๋ถ€ js์˜ ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€
  • ํ„ฐ๋ฏธ๋„ ๋ณ€์ˆ˜๋ฅผ ๋…ธ๋“œ์— ์ „๋‹ฌํ•œ ๋‹ค์Œ ์™ธ๋ถ€ js ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€

์ด๋Š” xhr/API ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜์—ฌ ๋ถ€๋ถ„์ ์œผ๋กœ๋งŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

URL

URL ์ž‘์—…์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
์ด์ƒ์ ์œผ๋กœ๋Š” URL ์ž‘์—… ๋ฐ๋ชจ๋ฅผ ํ†ตํ•ด external.js ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๋Š” ์—…๋ฐ์ดํŠธ๋œ ์ตœ์†Œ JSDOM ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. :๋งˆ์Œ:

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