diff --git a/README.md b/README.md index a25f57f..3b97916 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,12 @@ Available transforms: '[kebab](https://www.npmjs.com/package/lodash.kebabcase)', and '[camel](https://www.npmjs.com/package/lodash.camelcase)' +If you prefer to use suffixes for your files (e.g. `Foo.react.js` for a React component file), you can use the following configuration: + +```json +"filenames/match-exported": [2, "", "\\.react"] +``` + ### Don't allow index.js files (no-index) Having a bunch of `index.js` files can have negative influence on developer experience, e.g. when diff --git a/lib/rules/match-exported.js b/lib/rules/match-exported.js index 20cb038..1544c00 100644 --- a/lib/rules/match-exported.js +++ b/lib/rules/match-exported.js @@ -39,6 +39,7 @@ module.exports = function(context) { return { "Program": function (node) { var transformName = context.options[0], + replacePattern = context.options[1] ? new RegExp(context.options[1]) : null, filename = context.getFilename(), absoluteFilename = path.resolve(filename), parsed = parseFilename(absoluteFilename), @@ -46,17 +47,18 @@ module.exports = function(context) { exportedName = getExportedName(node), isExporting = Boolean(exportedName), expectedExport = getStringToCheckAgainstExport(parsed), - transformed = transform(exportedName, transformName), + transformedExport = replacePattern ? expectedExport.replace(replacePattern, '') : expectedExport, + transformedName = transform(exportedName, transformName), everythingIsIndex = exportedName === 'index' && parsed.name === 'index', - matchesExported = transformed === expectedExport || everythingIsIndex, + matchesExported = transformedName === transformedExport || everythingIsIndex, reportIf = function (condition, messageForNormalFile, messageForIndexFile) { var message = (!messageForIndexFile || !isIndexFile(parsed)) ? messageForNormalFile : messageForIndexFile; if (condition) { context.report(node, message, { name: parsed.base, - expectedExport: expectedExport, - exportName: transformed, + expectedExport: transformedExport, + exportName: transformedName, extension: parsed.ext }); } @@ -74,6 +76,9 @@ module.exports = function(context) { module.exports.schema = [ { - "enum": ["kebab", "snake", "camel"] + "enum": ["", "kebab", "snake", "camel"] + }, + { + "type": "string" } ]; diff --git a/test/index.js b/test/index.js index 83eebdd..5a2fd87 100644 --- a/test/index.js +++ b/test/index.js @@ -11,11 +11,11 @@ describe("index.js", function () { expect(index.rules['match-regex']).to.equal(matchRegex); }); - it("should export the match-regex rule", function () { + it("should export the match-exported rule", function () { expect(index.rules['match-exported']).to.equal(matchExported); }); - it("should export the match-regex rule", function () { + it("should export the no-index rule", function () { expect(index.rules['no-index']).to.equal(noIndex); }); }); diff --git a/test/rules/match-exported.js b/test/rules/match-exported.js index ae30166..35de1d9 100644 --- a/test/rules/match-exported.js +++ b/test/rules/match-exported.js @@ -197,6 +197,14 @@ ruleTester.run("lib/rules/match-exported", exportedRule, { errors: [ { message: "The directory 'foo' must be named 'exported', after the exported value of its index file.", column: 1, line: 1 } ] + }, + { + code: exportedJsxClassCode, + filename: "/some/dir/Foo.react.js", + parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } }, + errors: [ + { message: "Filename 'Foo.react' must match the exported name 'Foo'.", column: 1, line: 1 } + ] } ] }); @@ -240,6 +248,18 @@ ruleTester.run("lib/rules/match-exported with configuration", exportedRule, { filename: "variableName.js", parserOptions: { ecmaVersion: 6, sourceType: "module" }, options: ['camel'] + }, + { + code: exportedJsxClassCode, + filename: "/some/dir/Foo.react.js", + parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } }, + options: ["", "\\.react"] + }, + { + code: exportedEs6JsxClassCode, + filename: "/some/dir/Foo.react.js", + parserOptions: { ecmaVersion: 6, sourceType: "module", ecmaFeatures: { jsx: true } }, + options: ["", "\\.react"] } ], @@ -260,6 +280,15 @@ ruleTester.run("lib/rules/match-exported with configuration", exportedRule, { errors: [ { message: "Filename 'variableName' must match the exported name 'variable-name'.", column: 1, line: 1 } ] + }, + { + code: exportedEs6JsxClassCode, + filename: "/some/dir/Foo.bar.js", + parserOptions: { ecmaVersion: 6, sourceType: "module", ecmaFeatures: { jsx: true } }, + options: ["", "\\.react"], + errors: [ + { message: "Filename 'Foo.bar' must match the exported name 'Foo'.", column: 1, line: 1 } + ] } ] });