Created
June 27, 2018 03:37
-
-
Save LiuJi-Jim/817cb55db5cc27e376b99de63a4ac6fd to your computer and use it in GitHub Desktop.
eval module with local variables
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const CLIEngine = require("eslint").CLIEngine; | |
function getIdentifiers(code) { | |
if (!code) { | |
return []; | |
} | |
var cli = new CLIEngine({ | |
envs: ['browser', 'node'], | |
useEslintrc: false, | |
parserOptions: { | |
"ecmaVersion": 2016 | |
}, | |
rules: { | |
'no-undef': 1 | |
} | |
}); | |
var report = cli.executeOnText(code); | |
return report.results[0].messages.map(msg => msg.message.match(/'(.+?)'/)[1]) | |
} | |
const targetCode = ` | |
const localVar = 'local value'; | |
const sameNameVar = 'inner new value'; | |
console.log('local var:', localVar); | |
console.log('same name var:', sameNameVar) | |
console.log('var from context:', contextVar); | |
try { | |
console.log('var not existed', notExisted); // this will cause exception | |
} catch(ex) { | |
console.log('should catch exception here:', ex.message) | |
} | |
` | |
function copyLocalVarToContext(vars) { | |
const codes = []; | |
for (let i = 0; i < vars.length; ++i) { | |
const id = vars[i]; | |
codes.push(`if (typeof ${id} !== 'undefined') context['${id}'] = ${id};`) | |
} | |
return codes.join('\n'); | |
} | |
function extract(context, contextName) { | |
const codes = []; | |
Object.keys(context).forEach(id => { | |
codes.push(`const ${id} = ${contextName}['${id}'];`) | |
}) | |
return codes.join('\n'); | |
} | |
function main() { | |
const ids = getIdentifiers(targetCode); | |
const contextVar = 'outer value'; | |
const sameNameVar = 'outer old value'; | |
const context = {}; | |
eval(copyLocalVarToContext(ids)); | |
const contextName = `__context_${(new Date()).getTime()}_${Math.random().toString().replace(/\./g, '')}__` | |
const fnCode = [ | |
extract(context, contextName), | |
'//////', | |
targetCode | |
].join('\n') | |
const fn = new Function(contextName, fnCode) | |
// console.log(fn.toString()) | |
// console.log(context) | |
fn(context) | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment