Created
September 14, 2018 13:17
-
-
Save rafeca/e06e88feed05eaa526bd96744337c29f to your computer and use it in GitHub Desktop.
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
/** | |
* @format | |
*/ | |
const t = require('@babel/types'); | |
const babylon = require('@babel/parser'); | |
const invariant = require('invariant'); | |
const isGlobal = binding => !binding; | |
const isFlowDeclared = binding => t.isDeclareVariable(binding.path); | |
function isGlobalOrFlowDeclared(binding) { | |
return isGlobal(binding) || isFlowDeclared(binding); | |
} | |
function isReplaceableGlobal(node, parent, scope, opts) { | |
if (!t.isIdentifier(node)) { | |
return false; | |
} | |
if (!Object.hasOwnProperty.call(opts, node.name)) { | |
return false; | |
} | |
// Check that it's a global variable (not defined in any other place, or an object | |
// property). | |
return ( | |
isGlobalOrFlowDeclared(scope.getBinding(node.name)) && | |
!t.isMemberExpression(parent) && | |
!(t.isObjectProperty(parent) && parent.key === node) | |
); | |
} | |
function getValue(node, opts) { | |
invariant( | |
opts.hasOwnProperty(node.name), | |
`property ${node.name} should be present in plugin options`, | |
); | |
return opts[node.name]; | |
} | |
function getAstFromValue(value) { | |
switch (typeof value) { | |
case 'string': | |
return t.stringLiteral(value); | |
case 'boolean': | |
return t.booleanLiteral(value); | |
case 'number': | |
return t.numericLiteral(value); | |
case 'undefined': | |
return t.unaryExpression('void', t.numericLiteral(0), true); | |
} | |
return babylon.parseExpression(JSON.stringify(value)); | |
} | |
module.exports = function replaceGlobal() { | |
return { | |
visitor: { | |
Identifier(path, state) { | |
if ( | |
isReplaceableGlobal(path.node, path.parent, path.scope, state.opts) | |
) { | |
const value = getValue(path.node, state.opts); | |
path.replaceWith(getAstFromValue(value)); | |
} | |
}, | |
}, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment