diff --git a/README.md b/README.md index a8ba375..ad770cd 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ npm install --save-dev babel-plugin-inline-react-svg - `ignorePattern` - A pattern that imports will be tested against to selectively ignore imports. - `caseSensitive` - A boolean value that if true will require file paths to match with case-sensitivity. Useful to ensure consistent behavior if working on both a case-sensitive operating system like Linux and a case-insensitive one like OS X or Windows. +- *`spreadDefaultProps`* - A boolean value that if `true` will spread additional props, rather than setting them as `defaultProps` static assignment. This is important for tree shaking, as static assignments prevent efficient dead code removal. - `svgo` - svgo options (`false` to disable). Example: ```json { diff --git a/src/index.js b/src/index.js index 2934b6c..ce83824 100644 --- a/src/index.js +++ b/src/index.js @@ -39,9 +39,26 @@ export default declare(({ `; if (SVG_NAME !== 'default') { - return template(namedTemplate)({ SVG_NAME, SVG_CODE, SVG_DEFAULT_PROPS_CODE }); + const substitutions = { SVG_CODE, SVG_NAME }; + + // If a key is present in the substitutions object, but is unused in the template, even if + // even if it's value is undefined, Babel will throw an error. + if (SVG_DEFAULT_PROPS_CODE) { + substitutions.SVG_DEFAULT_PROPS_CODE = SVG_DEFAULT_PROPS_CODE; + } + + return template(namedTemplate)(substitutions); } - return template(anonymousTemplate)({ SVG_CODE, SVG_DEFAULT_PROPS_CODE, EXPORT_FILENAME }); + + const substitutions = { SVG_CODE, EXPORT_FILENAME }; + + // If a key is present in the substitutions object, but is unused in the template, even if + // even if it's value is undefined, Babel will throw an error. + if (SVG_DEFAULT_PROPS_CODE) { + substitutions.SVG_DEFAULT_PROPS_CODE = SVG_DEFAULT_PROPS_CODE; + } + + return template(anonymousTemplate)(substitutions); }; function applyPlugin(importIdentifier, importPath, path, state, isExport, exportFilename) { @@ -95,8 +112,9 @@ export default declare(({ EXPORT_FILENAME: exportFilename, }; - // Move props off of element and into defaultProps - if (svgCode.openingElement.attributes.length > 1) { + // Move props off of element and into defaultProps, but only if + // the "spreadDefaultProps" argument is not true + if (state.opts.spreadDefaultProps !== true && svgCode.openingElement.attributes.length > 1) { const keepProps = []; const defaultProps = []; diff --git a/test/sanity.js b/test/sanity.js index c397fba..7245b97 100644 --- a/test/sanity.js +++ b/test/sanity.js @@ -14,8 +14,20 @@ function assertReactImport(result) { } } +function assertSpreadProps(result) { + const hasSpreadProps = result.code.match(/_extends\(\{.*"'data-name'": "Livello 1".*\}, props\)/gs); + if (!hasSpreadProps) { + throw new Error('Spread props were not found'); + } + + const hasDefaultProps = result.code.match(/\.defaultProps/g); + if (hasDefaultProps) { + throw new Error('Default props were found, when spread should have been used instead'); + } +} + function validateDefaultProps(result) { - if (!(/'data-name':/g).test(result.code)) { + if (!(/'data-name':?/g).test(result.code)) { throw new Error('data-* props need to be quoted'); } } @@ -226,3 +238,14 @@ transformFile('test/fixtures/test-commented.jsx', { console.log('test/fixtures/test-commented.jsx', result.code); }); */ +transformFile('test/fixtures/test-export-default-as.jsx', { + presets: ['airbnb'], + plugins: [ + [inlineReactSvgPlugin, { spreadDefaultProps: true }], + ], +}, (err, result) => { + if (err) throw err; + console.log('test/fixtures/test-export-default-as.jsx', result.code); + validateDefaultProps(result); + assertSpreadProps(result); +});