diff --git a/README.md b/README.md index 0f636bc..9f9b6d6 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,7 @@ Configure the options for the plugin within your `.babelrc` as follows: |`webpackHotModuleReloading`|`boolean`|Enables hot reloading of CSS in webpack|`false`| |`handleMissingStyleName`|`"throw"`, `"warn"`, `"ignore"`|Determines what should be done for undefined CSS modules (using a `styleName` for which there is no CSS module defined). Setting this option to `"ignore"` is equivalent to setting `errorWhenNotFound: false` in [react-css-modules](https://github.com/gajus/react-css-modules#errorwhennotfound). |`"throw"`| |`attributeNames`|`?AttributeNameMapType`|Refer to [Custom Attribute Mapping](#custom-attribute-mapping)|`{"styleName": "className"}`| +|`skip`|`boolean`|Whether to apply plugin if no matching `attributeNames` found in the file|`false`| Missing a configuration? [Raise an issue](https://github.com/gajus/babel-plugin-react-css-modules/issues/new?title=New%20configuration:). diff --git a/src/attributeNameExists.js b/src/attributeNameExists.js new file mode 100644 index 0000000..6314634 --- /dev/null +++ b/src/attributeNameExists.js @@ -0,0 +1,31 @@ +// @flow + +import optionsDefaults from './schemas/optionsDefaults'; + +const attributeNameExists = (programPath: *, stats: *): boolean => { + let exists = false; + + let attributeNames = optionsDefaults.attributeNames; + + if (stats.opts && stats.opts.attributeNames) { + attributeNames = Object.assign({}, attributeNames, stats.opts.attributeNames); + } + + programPath.traverse({ + JSXAttribute (attrPath: *) { + if (exists) { + return; + } + + const attribute = attrPath.node; + + if (typeof attribute.name !== 'undefined' && typeof attributeNames[attribute.name.name] === 'string') { + exists = true; + } + } + }); + + return exists; +}; + +export default attributeNameExists; diff --git a/src/index.js b/src/index.js index 4bd892e..a584fe0 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,7 @@ import createObjectExpression from './createObjectExpression'; import requireCssModule from './requireCssModule'; import resolveStringLiteral from './resolveStringLiteral'; import replaceJsxExpressionContainer from './replaceJsxExpressionContainer'; +import attributeNameExists from './attributeNameExists'; const ajv = new Ajv({ // eslint-disable-next-line id-match @@ -31,6 +32,8 @@ export default ({ }) => { const filenameMap = {}; + let skip = false; + const setupFileForRuntimeResolution = (path, filename) => { const programPath = path.findParent((parentPath) => { return parentPath.isProgram(); @@ -147,7 +150,7 @@ export default ({ inherits: babelPluginJsxSyntax, visitor: { ImportDeclaration (path: *, stats: *): void { - if (notForPlugin(path, stats)) { + if (skip || notForPlugin(path, stats)) { return; } @@ -183,6 +186,10 @@ export default ({ } }, JSXElement (path: *, stats: *): void { + if (skip) { + return; + } + const filename = stats.file.opts.filename; if (stats.opts.exclude && isFilenameExcluded(filename, stats.opts.exclude)) { @@ -250,6 +257,10 @@ export default ({ filenameMap[filename] = { styleModuleImportMap: {} }; + + if (stats.opts.skip && !attributeNameExists(path, stats)) { + skip = true; + } } } }; diff --git a/src/schemas/optionsSchema.json b/src/schemas/optionsSchema.json index e14e525..2b3041f 100644 --- a/src/schemas/optionsSchema.json +++ b/src/schemas/optionsSchema.json @@ -69,6 +69,9 @@ } }, "type": "object" + }, + "skip": { + "type": "boolean" } }, "type": "object" diff --git a/test/fixtures/react-css-modules/does not apply plugin if no styleName/bar.css b/test/fixtures/react-css-modules/does not apply plugin if no styleName/bar.css new file mode 100644 index 0000000..5512dae --- /dev/null +++ b/test/fixtures/react-css-modules/does not apply plugin if no styleName/bar.css @@ -0,0 +1 @@ +.a {} diff --git a/test/fixtures/react-css-modules/does not apply plugin if no styleName/input.js b/test/fixtures/react-css-modules/does not apply plugin if no styleName/input.js new file mode 100644 index 0000000..9b3805b --- /dev/null +++ b/test/fixtures/react-css-modules/does not apply plugin if no styleName/input.js @@ -0,0 +1,3 @@ +import 'bar.css'; + +
; diff --git a/test/fixtures/react-css-modules/does not apply plugin if no styleName/options.json b/test/fixtures/react-css-modules/does not apply plugin if no styleName/options.json new file mode 100644 index 0000000..88e0d9d --- /dev/null +++ b/test/fixtures/react-css-modules/does not apply plugin if no styleName/options.json @@ -0,0 +1,11 @@ +{ + "plugins": [ + [ + "../../../../src", + { + "generateScopedName": "[name]__[local]", + "skip": true + } + ] + ] +} diff --git a/test/fixtures/react-css-modules/does not apply plugin if no styleName/output.js b/test/fixtures/react-css-modules/does not apply plugin if no styleName/output.js new file mode 100644 index 0000000..f8754b6 --- /dev/null +++ b/test/fixtures/react-css-modules/does not apply plugin if no styleName/output.js @@ -0,0 +1,5 @@ +"use strict"; + +require("bar.css"); + +;