Vm2: vm2๋ฅผ Webpack๊ณผ ํ˜ธํ™˜๋˜๋„๋ก ์„ค์ •

์— ๋งŒ๋“  2017๋…„ 04์›” 26์ผ  ยท  5์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: patriksimek/vm2

  • [x] ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ๊นจ์ง€ ์•Š๊ณ  coffee-script require๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„ ๋ด…๋‹ˆ๋‹ค.
  • [] fs-sandbox.js ๋ฐ contextify.js๋ฅผ ํ†ตํ•ด๋กœ๋“œ ๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฒˆ๋“ค๋งํ•˜๋„๋ก webpack์— ์ง€์‹œํ•˜๋Š” ๋ฐฉ๋ฒ• ๊ทธ๋ฆผ
feature request help wanted

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

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค์Œ์€ vm2 ๋ฅผ Webpack ์™€ ํ˜ธํ™˜๋˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฐ€์žฅ ์ข‹๊ณ  ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. vm2 ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ 3 ์ค„์˜ ์ถ”๊ฐ€ ๊ตฌ์„ฑ๊ณผ ๊ฐ„๋‹จํ•œ NPM ์Šคํฌ๋ฆฝํŠธ ๋งŒ ์žˆ์œผ๋ฉด๋ฉ๋‹ˆ๋‹ค.

  1. output/ ๋””๋ ‰ํ„ฐ๋ฆฌ์— package.json ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
{
    "dependencies": {
        "vm2": "latest"
    }
}
  1. Webpack ๊ตฌ์„ฑ์—์„œ vm2 ๋ฅผ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
externals: {
    "vm2": "require('vm2')"
}
  1. Webpack์ด ๋ชจ๋“  ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋ฉด output/ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ข…์†์„ฑ์„ ์„ค์น˜ํ•˜๋Š” ์ถ”๊ฐ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ NPM์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
"scripts": {
    "prepare-output": "cd output && npm install",
    "prepare": "webpack --progress && npm run prepare-output"
}

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

๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” require ์ž…๋‹ˆ๋‹ค. webpack์€ ๋‹ค์Œ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ :

WARNING in ./~/vm2/lib/main.js
147:26-33 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

WARNING in ./~/vm2/lib/main.js
251:3-10 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

WARNING in ./~/vm2/lib/main.js
295:26-33 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

webpack์€ ์‹ค์ œ๋กœ require ๋ฅผ exceptions ๋กœ ๋Œ€์ฒดํ–ˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, webpack ์ „์— :

        Reflect.defineProperty(this, '_internal', {
            value: vm.runInContext(`(function(require, host) { ${cf} \n})`, this._context, {
                filename: `${__dirname}/contextify.js`,
                displayErrors: false
            }).call(this._context, require, host)
        });

์›นํŒฉ ์ดํ›„ :

        Reflect.defineProperty(this, '_internal', {
            value: vm.runInContext(`(function(require, host) { ${cf} \n})`, this._context, {
                filename: `${__dirname}/contextify.js`,
                displayErrors: false
            }).call(this._context, !(function webpackMissingModule() { var e = new Error("Cannot find module \".\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()), host)
        });

require ๋ฅผ eval('require') ๋ฐ”๊พธ๋ฉด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ๋‚˜์€ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค์Œ์€ vm2 ๋ฅผ Webpack ์™€ ํ˜ธํ™˜๋˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฐ€์žฅ ์ข‹๊ณ  ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. vm2 ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ 3 ์ค„์˜ ์ถ”๊ฐ€ ๊ตฌ์„ฑ๊ณผ ๊ฐ„๋‹จํ•œ NPM ์Šคํฌ๋ฆฝํŠธ ๋งŒ ์žˆ์œผ๋ฉด๋ฉ๋‹ˆ๋‹ค.

  1. output/ ๋””๋ ‰ํ„ฐ๋ฆฌ์— package.json ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
{
    "dependencies": {
        "vm2": "latest"
    }
}
  1. Webpack ๊ตฌ์„ฑ์—์„œ vm2 ๋ฅผ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
externals: {
    "vm2": "require('vm2')"
}
  1. Webpack์ด ๋ชจ๋“  ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋ฉด output/ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ข…์†์„ฑ์„ ์„ค์น˜ํ•˜๋Š” ์ถ”๊ฐ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ NPM์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
"scripts": {
    "prepare-output": "cd output && npm install",
    "prepare": "webpack --progress && npm run prepare-output"
}

์•ˆ๋…•ํ•˜์„ธ์š” !

๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๊ณ  ์—ฌ๊ธฐ์— ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์ฒซ์งธ, ์†Œ์Šค๋ฅผ ์ˆ˜์ •ํ•ด์•ผํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“ˆ์„ npm ๋ชจ๋“ˆ๋กœ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๋‚ด ํ”„๋กœ์ ํŠธ์˜ ํด๋”์—์„œ lib๋ฅผ c / c๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค (ํŒŒ์ผ ๋ช‡ ๊ฐœ์— ๋ถˆ๊ณผํ•˜๋ฏ€๋กœ ๋ฌธ์ œ ์—†์Œ).

  2. sandbox.js / contextify.js์˜ fs ์ •๋ณด : sandbox.txt ๋ฐ contextify.txt๋กœ ์ด๋ฆ„์„ ๋ฐ”๊พผ ๋‹ค์Œ ์›์‹œ ๋กœ๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ฐ˜ ํ…์ŠคํŠธ๋กœ๋กœ๋“œํ–ˆ์Šต๋‹ˆ๋‹ค.

main.js (์ƒ๋‹จ)

const sb = require('./sandbox.txt');
const cf = require('./contextify.txt');

webpack.config.js

{
    test: /\.txt$/,
    use: 'raw-loader'
}

sandbox.js / contextify.js์˜ ๋ชจ๋“  ์ฐธ์กฐ๋ฅผ main.js์˜ sandbox.txt / contextify.txt๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

  1. ๋งˆ์ง€๋ง‰์œผ๋กœ ๊นŒ๋‹ค๋กœ์šด ๋ถ€๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. NodeVM์˜ ๊ฒฝ์šฐ ํ•œ ์ค„์„ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

main.js (์•ฝ 250 ํ–‰)

[...]
const host = {
    version: parseInt(process.versions.node.split('.')[0]),
    require: eval('require'),
    process,
    console,
[...]

๋‚˜๋Š” "require"๋ฅผ "require : eval ( 'require')"๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ webpack์ด ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  (Coxxs์—์„œ ์ œ์•ˆํ•œ๋Œ€๋กœ) ํŠธ๋ฆญ์„ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ vm2๋ฅผ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉํ•  ํ•„์š”์—†์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋งค์šฐ ๊นŒ๋‹ค ๋กญ๊ณ  ๊นจ๋—ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์ง€๊ธˆ๊นŒ์ง€ ๋‚ด๊ฐ€ ์–ป์€ ์œ ์ผํ•œ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๋‹ค.
๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋‹น์‹  ์ค‘ ์ผ๋ถ€๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ๊ณ  ๋˜ํ•œ ์‹ค์ œ ์ˆ˜์ •์— ๋„์›€์ด๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ์†”๋ฃจ์…˜์ด ์žˆ๋‹ค๋ฉด ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค! :)

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

FWIW-๋Œ€์ƒ์ด node Webpack 5์™€ ๋ฒˆ๋“ค๋ง์ด ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

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