UNPKG

@wordpress/babel-plugin-import-jsx-pragma

Version:

Babel transform plugin for automatically injecting an import to be used as the pragma for the React JSX Transform plugin.

116 lines (103 loc) 3.23 kB
/** * Default options for the plugin. * * @property {string} scopeVariable Name of variable required to be in scope * for use by the JSX pragma. For the default * pragma of React.createElement, the React * variable must be within scope. * @property {string} scopeVariableFrag Name of variable required to be in scope * for use by the Fragment pragma. * @property {string} source The module from which the scope variable * is to be imported when missing. * @property {boolean} isDefault Whether the scopeVariable is the default * import of the source module. */ const DEFAULT_OPTIONS = { scopeVariable: 'React', scopeVariableFrag: null, source: 'react', isDefault: true, }; /** * Babel transform plugin for automatically injecting an import to be used as * the pragma for the React JSX Transform plugin. * * @see http://babeljs.io/docs/en/babel-plugin-transform-react-jsx * * @param {Object} babel Babel instance. * * @return {Object} Babel transform plugin. */ module.exports = ( babel ) => { const { types: t } = babel; function getOptions( state ) { if ( ! state._options ) { state._options = Object.assign( {}, DEFAULT_OPTIONS, state.opts ); } return state._options; } return { visitor: { JSX( path, state ) { if ( state.hasUndeclaredScopeVariable ) { return; } const { scopeVariable } = getOptions( state ); state.hasUndeclaredScopeVariable = ! path.scope.hasBinding( scopeVariable ); }, JSXFragment( path, state ) { if ( state.hasUndeclaredScopeVariableFrag ) { return; } const { scopeVariableFrag } = getOptions( state ); if ( scopeVariableFrag === null ) { return; } state.hasUndeclaredScopeVariableFrag = ! path.scope.hasBinding( scopeVariableFrag ); }, Program: { exit( path, state ) { const { scopeVariable, scopeVariableFrag, source, isDefault, } = getOptions( state ); let scopeVariableSpecifier; let scopeVariableFragSpecifier; if ( state.hasUndeclaredScopeVariable ) { if ( isDefault ) { scopeVariableSpecifier = t.importDefaultSpecifier( t.identifier( scopeVariable ) ); } else { scopeVariableSpecifier = t.importSpecifier( t.identifier( scopeVariable ), t.identifier( scopeVariable ) ); } } if ( state.hasUndeclaredScopeVariableFrag ) { scopeVariableFragSpecifier = t.importSpecifier( t.identifier( scopeVariableFrag ), t.identifier( scopeVariableFrag ) ); } const importDeclarationSpecifiers = [ scopeVariableSpecifier, scopeVariableFragSpecifier, ].filter( Boolean ); if ( importDeclarationSpecifiers.length ) { const importDeclaration = t.importDeclaration( importDeclarationSpecifiers, t.stringLiteral( source ) ); path.unshiftContainer( 'body', importDeclaration ); } }, }, }, }; };