diff --git a/src/conditionalClassMerge.js b/src/conditionalClassMerge.js index 617599c..cb7bbf5 100644 --- a/src/conditionalClassMerge.js +++ b/src/conditionalClassMerge.js @@ -12,6 +12,7 @@ export default ( classNameExpression: any, styleNameExpression: any, ): any => { + // classNameExpression ? (classNameExpression + ' ') : '' + styleNameExpression return binaryExpression( '+', conditionalExpression( diff --git a/src/findMatchedFiletype.js b/src/findMatchedFiletype.js new file mode 100644 index 0000000..b74a0b2 --- /dev/null +++ b/src/findMatchedFiletype.js @@ -0,0 +1,25 @@ +// @flow + +export default (sourceFilePath: string, filetypes: $ReadOnlyArray): ?string => { + // Try to match as the RegExp pattern + for (const pattern of filetypes) { + if (!pattern.match(/^\.[a-z0-9A-Z]+?$/)) { + if (sourceFilePath.match(new RegExp(pattern))) { + return pattern; + } + } + } + + const extensionDotIndex = sourceFilePath.lastIndexOf('.'); + + if (extensionDotIndex > -1) { + const extension = sourceFilePath.substr(extensionDotIndex); + const index = filetypes.indexOf(extension); + + if (index > -1) { + return filetypes[index]; + } + } + + return null; +}; diff --git a/src/getClassName.js b/src/getClassName.js index 1bf05fb..823ce16 100644 --- a/src/getClassName.js +++ b/src/getClassName.js @@ -120,6 +120,7 @@ export default (styleNameValue: string, styleModuleImportMap: StyleModuleImportM return getClassNameFromMultipleImports(styleName, styleModuleImportMap, handleMissingStyleName); } + // There is only one imported CSS module file. const styleModuleMap: StyleModuleMapType = styleModuleImportMap[styleModuleImportMapKeys[0]]; if (!styleModuleMap[styleName]) { diff --git a/src/index.js b/src/index.js index 305d941..477026b 100644 --- a/src/index.js +++ b/src/index.js @@ -15,6 +15,7 @@ import requireCssModule from './requireCssModule'; import resolveStringLiteral from './resolveStringLiteral'; import replaceJsxExpressionContainer from './replaceJsxExpressionContainer'; import attributeNameExists from './attributeNameExists'; +import findMatchedFiletype from './findMatchedFiletype'; import createSpreadMapper from './createSpreadMapper'; import handleSpreadClassName from './handleSpreadClassName'; @@ -130,12 +131,12 @@ export default ({ return filename.match(new RegExp(exclude)); }; + // decide whether the import statement should be processed as CSS module const notForPlugin = (path: *, stats: *) => { stats.opts.filetypes = stats.opts.filetypes || {}; - const extension = path.node.source.value.lastIndexOf('.') > -1 ? path.node.source.value.substr(path.node.source.value.lastIndexOf('.')) : null; - - if (extension !== '.css' && Object.keys(stats.opts.filetypes).indexOf(extension) < 0) { + // @HACK + if (path.node.source.value.indexOf('babel-plugin-react-css-modules') === 0) { return true; } @@ -145,7 +146,10 @@ export default ({ return true; } - return false; + const filetypeKeys = Object.keys(stats.opts.filetypes); + filetypeKeys.push('.css'); + + return !findMatchedFiletype(filename, filetypeKeys); }; return { diff --git a/src/requireCssModule.js b/src/requireCssModule.js index 0268a43..d77c25a 100644 --- a/src/requireCssModule.js +++ b/src/requireCssModule.js @@ -18,6 +18,7 @@ import type { GenerateScopedNameConfigurationType, StyleModuleMapType } from './types'; +import findMatchedFiletype from './findMatchedFiletype'; import optionsDefaults from './schemas/optionsDefaults'; type FiletypeOptionsType = {| @@ -36,10 +37,9 @@ type OptionsType = {| |}; const getFiletypeOptions = (cssSourceFilePath: string, filetypes: FiletypesConfigurationType): ?FiletypeOptionsType => { - const extension = cssSourceFilePath.substr(cssSourceFilePath.lastIndexOf('.')); - const filetype = filetypes ? filetypes[extension] : null; + const matchedKey = findMatchedFiletype(cssSourceFilePath, Object.keys(filetypes)); - return filetype; + return matchedKey ? filetypes && filetypes[matchedKey] : null; }; // eslint-disable-next-line flowtype/no-weak-types diff --git a/src/resolveStringLiteral.js b/src/resolveStringLiteral.js index b1d4f32..f62e42a 100644 --- a/src/resolveStringLiteral.js +++ b/src/resolveStringLiteral.js @@ -41,7 +41,6 @@ export default ( } else { throw new Error('Unexpected attribute value:' + destinationAttribute.value); } - path.node.openingElement.attributes.splice(path.node.openingElement.attributes.indexOf(sourceAttribute), 1); } else { sourceAttribute.name.name = destinationName; diff --git a/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/bar.less b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/bar.less new file mode 100644 index 0000000..6586489 --- /dev/null +++ b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/bar.less @@ -0,0 +1,3 @@ +@color: #f00; + +.a {background-color: @color;} diff --git a/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/bar.md.less b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/bar.md.less new file mode 100644 index 0000000..6586489 --- /dev/null +++ b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/bar.md.less @@ -0,0 +1,3 @@ +@color: #f00; + +.a {background-color: @color;} diff --git a/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/input.js b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/input.js new file mode 100644 index 0000000..25d6c7d --- /dev/null +++ b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/input.js @@ -0,0 +1,3 @@ +import './bar.md.less'; + +
; diff --git a/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/options.json b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/options.json new file mode 100644 index 0000000..0e3777a --- /dev/null +++ b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/options.json @@ -0,0 +1,15 @@ +{ + "plugins": [ + [ + "../../../../src", + { + "generateScopedName": "[name]__[local]", + "filetypes": { + "\\.md\\.less$": { + "syntax": "postcss-less" + } + } + } + ] + ] +} diff --git a/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/output.js b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/output.js new file mode 100644 index 0000000..e77b991 --- /dev/null +++ b/test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/output.js @@ -0,0 +1,5 @@ +"use strict"; + +require("./bar.md.less"); + +
; diff --git a/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/bar.md.css b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/bar.md.css new file mode 100644 index 0000000..07a8534 --- /dev/null +++ b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/bar.md.css @@ -0,0 +1 @@ +.a {background-color: #f00;} diff --git a/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/foo.css b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/foo.css new file mode 100644 index 0000000..07a8534 --- /dev/null +++ b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/foo.css @@ -0,0 +1 @@ +.a {background-color: #f00;} diff --git a/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/input.js b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/input.js new file mode 100644 index 0000000..d00c4be --- /dev/null +++ b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/input.js @@ -0,0 +1,4 @@ +import barMd from './bar.md.css'; +import base from './styles/base.css'; + +
; diff --git a/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/options.json b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/options.json new file mode 100644 index 0000000..5adefe5 --- /dev/null +++ b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/options.json @@ -0,0 +1,16 @@ +{ + "plugins": [ + [ + "../../../../src", + { + "generateScopedName": "[name]__[local]", + "filetypes": { + "\\.md\\.less$": { + "syntax": "postcss-less" + }, + "styles/.*?\\.css$": {} + } + } + ] + ] +} diff --git a/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/output.js b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/output.js new file mode 100644 index 0000000..882cb0a --- /dev/null +++ b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/output.js @@ -0,0 +1,9 @@ +"use strict"; + +var _barMd = _interopRequireDefault(require("./bar.md.css")); + +var _base = _interopRequireDefault(require("./styles/base.css")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +
; diff --git a/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/styles/base.css b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/styles/base.css new file mode 100644 index 0000000..f454509 --- /dev/null +++ b/test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/styles/base.css @@ -0,0 +1 @@ +.b {background-color: #0f0;} \ No newline at end of file