From 266d26ac514fea3a3cd69eb98c9ce292a3a477b0 Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Sat, 28 Dec 2019 18:10:42 -0500 Subject: [PATCH] Register Module Binding --- src/index.js | 12 ++++++----- test/fixtures/test-no-duplicate-react.jsx | 5 +++++ test/sanity.js | 26 ++++++++++++++++++++++- 3 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 test/fixtures/test-no-duplicate-react.jsx diff --git a/src/index.js b/src/index.js index 85658dd..ed9a63f 100644 --- a/src/index.js +++ b/src/index.js @@ -28,7 +28,7 @@ export default declare(({ }) => { const namedTemplate = ` var SVG_NAME = function SVG_NAME(props) { return SVG_CODE; }; - ${SVG_DEFAULT_PROPS_CODE ? 'SVG_NAME.defaultProps = SVG_DEFAULT_PROPS_CODE;' : ''} + ${SVG_DEFAULT_PROPS_CODE ? 'SVG_NAME.defaultProps = SVG_DEFAULT_PROPS_CODE;' : ''} ${IS_EXPORT ? 'export { SVG_NAME };' : ''} `; const anonymousTemplate = ` @@ -44,7 +44,6 @@ export default declare(({ return template(anonymousTemplate)({ SVG_CODE, SVG_DEFAULT_PROPS_CODE, EXPORT_FILENAME }); }; - function applyPlugin(importIdentifier, importPath, path, state, isExport, exportFilename) { if (typeof importPath !== 'string') { throw new TypeError('`applyPlugin` `importPath` must be a string'); @@ -124,19 +123,22 @@ export default declare(({ return { visitor: { Program: { - enter({ scope, node }, { file, opts, filename }) { + enter(path, { file, opts, filename }) { if (typeof filename === 'string' && typeof opts.filename !== 'undefined') { throw new TypeError('the "filename" option may only be provided when transforming code'); } if (typeof filename === 'undefined' && typeof opts.filename !== 'string') { throw new TypeError('the "filename" option is required when transforming code'); } - if (!scope.hasBinding('React')) { + if (!path.scope.hasBinding('React')) { const reactImportDeclaration = t.importDeclaration([ t.importDefaultSpecifier(t.identifier('React')), ], t.stringLiteral('react')); - file.set('ensureReact', () => { node.body.unshift(reactImportDeclaration); }); + file.set('ensureReact', () => { + const [newPath] = path.unshiftContainer('body', reactImportDeclaration); + newPath.get('specifiers').forEach((specifier) => { path.scope.registerBinding('module', specifier); }); + }); } else { file.set('ensureReact', () => {}); } diff --git a/test/fixtures/test-no-duplicate-react.jsx b/test/fixtures/test-no-duplicate-react.jsx new file mode 100644 index 0000000..3fe0b60 --- /dev/null +++ b/test/fixtures/test-no-duplicate-react.jsx @@ -0,0 +1,5 @@ +import MySvg from './close.svg'; + +export function MyFunctionIcon() { + return MySvg; +} diff --git a/test/sanity.js b/test/sanity.js index 81e2176..b04db4c 100644 --- a/test/sanity.js +++ b/test/sanity.js @@ -58,6 +58,30 @@ transformFile('test/fixtures/test-no-react.jsx', { validateDefaultProps(result); }); +transformFile('test/fixtures/test-no-duplicate-react.jsx', { + babelrc: false, + presets: ['@babel/preset-react'], + plugins: [ + inlineReactSvgPlugin, + ({ + visitor: { + Program: { + exit({ scope }) { + if (!scope.hasBinding('React')) { + throw new Error('React binding was expected.'); + } + }, + }, + }, + }), + ], +}, (err, result) => { + if (err) throw err; + console.log('test/fixtures/test-no-duplicate-react.jsx', result.code); + assertReactImport(result); + validateDefaultProps(result); +}); + if (fs.existsSync(path.resolve('./PACKAGE.JSON'))) { transformFile('test/fixtures/test-case-sensitive.jsx', { babelrc: false, @@ -71,7 +95,7 @@ if (fs.existsSync(path.resolve('./PACKAGE.JSON'))) { if (err && err.message.indexOf('match case') !== -1) { console.log('test/fixtures/test-case-sensitive.jsx', 'Test passed: Expected case sensitive error was thrown'); } else { - throw new Error('Test failed: Expected case sensitive error wasn‘t thrown, got: ' + err.message); + throw new Error(`Test failed: Expected case sensitive error wasn‘t thrown, got: ${err.message}`); } }); } else {