From 8dd11cdaa32ad85f729cb630d9583a48c8dd6bcd Mon Sep 17 00:00:00 2001 From: super-cattle Date: Sun, 3 Mar 2019 18:41:09 +0800 Subject: [PATCH 1/6] feat: use RegExp as including condition in filetype config --- src/conditionalClassMerge.js | 1 + src/findMatchedFiletype.js | 23 +++++++++++++++++++++++ src/index.js | 13 ++++++++++--- src/requireCssModule.js | 6 +++--- src/resolveStringLiteral.js | 1 - 5 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 src/findMatchedFiletype.js 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..6723fc1 --- /dev/null +++ b/src/findMatchedFiletype.js @@ -0,0 +1,23 @@ +// @flow + +export default (sourceFilePath: string, filetypes: $ReadOnlyArray): ?string => { + const extensionDotIndex = sourceFilePath.lastIndexOf('.'); + + if (extensionDotIndex > -1) { + const extension = sourceFilePath.substr(extensionDotIndex); + const index = filetypes.indexOf(extension); + + if (index > -1) { + return filetypes[index]; + } + } + + // Try to match as the RegExp pattern + for (const pattern of filetypes) { + if (sourceFilePath.match(new RegExp(pattern))) { + return pattern; + } + } + + return null; +}; diff --git a/src/index.js b/src/index.js index 5c728f7..bfe432b 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'; const ajv = new Ajv({ // eslint-disable-next-line id-match @@ -131,9 +132,8 @@ export default ({ 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; } @@ -143,6 +143,13 @@ export default ({ return true; } + const filetypeKeys = Object.keys(stats.opts.filetypes); + + filetypeKeys.push('.css'); + if (!findMatchedFiletype(filename, filetypeKeys)) { + return true; + } + return false; }; 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; From cce93c86ff59452c1eb18dce17048b9bbbf6fddc Mon Sep 17 00:00:00 2001 From: super-cattle Date: Sun, 3 Mar 2019 18:45:45 +0800 Subject: [PATCH 2/6] test: add corresponding test cases. --- .../bar.less | 3 +++ .../bar.md.less | 3 +++ .../input.js | 3 +++ .../options.json | 15 +++++++++++++++ .../output.js | 5 +++++ .../bar.md.css | 1 + .../foo.css | 1 + .../input.js | 4 ++++ .../options.json | 16 ++++++++++++++++ .../output.js | 9 +++++++++ .../styles/base.css | 1 + 11 files changed, 61 insertions(+) create mode 100644 test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/bar.less create mode 100644 test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/bar.md.less create mode 100644 test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/input.js create mode 100644 test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/options.json create mode 100644 test/fixtures/react-css-modules/resolves less stylesheets matching RegExp/output.js create mode 100644 test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/bar.md.css create mode 100644 test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/foo.css create mode 100644 test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/input.js create mode 100644 test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/options.json create mode 100644 test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/output.js create mode 100644 test/fixtures/react-css-modules/resolves namespaced styleName matching RegExp/styles/base.css 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 From 9f41cf7c238a9e90f87ad0b22b20ea4981cf0802 Mon Sep 17 00:00:00 2001 From: super-cattle Date: Sun, 3 Mar 2019 23:10:22 +0800 Subject: [PATCH 3/6] fix: do not use extension-style filrtype as RegExp pattern --- src/findMatchedFiletype.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/findMatchedFiletype.js b/src/findMatchedFiletype.js index 6723fc1..4114b35 100644 --- a/src/findMatchedFiletype.js +++ b/src/findMatchedFiletype.js @@ -14,6 +14,9 @@ export default (sourceFilePath: string, filetypes: $ReadOnlyArray): ?str // Try to match as the RegExp pattern for (const pattern of filetypes) { + if (pattern.match(/^\.[a-z0-9A-Z]+?$/)) { + continue; + } if (sourceFilePath.match(new RegExp(pattern))) { return pattern; } From 3dd9bfe34b34217dd70388836ad533fa574608d4 Mon Sep 17 00:00:00 2001 From: super-cattle Date: Sun, 3 Mar 2019 23:12:40 +0800 Subject: [PATCH 4/6] feat: modify the priority between RegExp pattern filetype and extension style filetype --- src/findMatchedFiletype.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/findMatchedFiletype.js b/src/findMatchedFiletype.js index 4114b35..92506e3 100644 --- a/src/findMatchedFiletype.js +++ b/src/findMatchedFiletype.js @@ -1,6 +1,16 @@ // @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]+?$/)) { + continue; + } + if (sourceFilePath.match(new RegExp(pattern))) { + return pattern; + } + } + const extensionDotIndex = sourceFilePath.lastIndexOf('.'); if (extensionDotIndex > -1) { @@ -12,15 +22,5 @@ export default (sourceFilePath: string, filetypes: $ReadOnlyArray): ?str } } - // Try to match as the RegExp pattern - for (const pattern of filetypes) { - if (pattern.match(/^\.[a-z0-9A-Z]+?$/)) { - continue; - } - if (sourceFilePath.match(new RegExp(pattern))) { - return pattern; - } - } - return null; }; From fb7a8294512bb9c98ad35a58f6c64113ef561400 Mon Sep 17 00:00:00 2001 From: super-cattle Date: Mon, 4 Mar 2019 00:05:21 +0800 Subject: [PATCH 5/6] style: no continue --- src/findMatchedFiletype.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/findMatchedFiletype.js b/src/findMatchedFiletype.js index 92506e3..b74a0b2 100644 --- a/src/findMatchedFiletype.js +++ b/src/findMatchedFiletype.js @@ -3,11 +3,10 @@ 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]+?$/)) { - continue; - } - if (sourceFilePath.match(new RegExp(pattern))) { - return pattern; + if (!pattern.match(/^\.[a-z0-9A-Z]+?$/)) { + if (sourceFilePath.match(new RegExp(pattern))) { + return pattern; + } } } From 1c94157fdf0414f41d77057a04d81a1672ad1d44 Mon Sep 17 00:00:00 2001 From: Xu Xinhang Date: Sun, 12 Apr 2020 11:49:36 +0800 Subject: [PATCH 6/6] style: for comment #2 --- src/getClassName.js | 1 + src/index.js | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) 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 bfe432b..219d72d 100644 --- a/src/index.js +++ b/src/index.js @@ -129,6 +129,7 @@ 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 || {}; @@ -144,13 +145,9 @@ export default ({ } const filetypeKeys = Object.keys(stats.opts.filetypes); - filetypeKeys.push('.css'); - if (!findMatchedFiletype(filename, filetypeKeys)) { - return true; - } - return false; + return !findMatchedFiletype(filename, filetypeKeys); }; return {