Skip to content

Commit

Permalink
import/extensions setting: parser whitelist. fixes #267
Browse files Browse the repository at this point in the history
  • Loading branch information
benmosher committed May 2, 2016
1 parent 73164f8 commit 359cbbb
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,10 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
- [`newline-after-import`], new rule. ([#245], thanks [@singles])
- Added an `optionalDependencies` option to [`no-extraneous-dependencies`] to allow/forbid optional dependencies ([#266], thanks [@jfmengels]).

### Breaking
- [`import/extensions` setting]: a whitelist of file extensions to parse as modules
and search for `export`s. Defaults to `['.js']`.

## resolvers/webpack/0.2.4 - 2016-04-29
### Changed
- automatically find webpack config with `interpret`-able extensions ([#287], thanks [@taion])
Expand Down Expand Up @@ -174,6 +178,7 @@ for info on changes for earlier releases.

[`import/cache` setting]: ./README.md#importcache
[`import/ignore` setting]: ./README.md#importignore
[`import/extensions` setting]: ./README.md#importextensions

[`no-unresolved`]: ./docs/rules/no-unresolved.md
[`no-deprecated`]: ./docs/rules/no-deprecated.md
Expand Down
13 changes: 13 additions & 0 deletions README.md
Expand Up @@ -146,6 +146,19 @@ If you are interesting in writing a resolver, see the [spec](./resolvers/README.

You may set the following settings in your `.eslintrc`:

#### `import/extensions`

A whitelist of file extensions that will be parsed as modules and inspected for
`export`s. This defaults to `['.js']`, unless you are using the `react` shared config,
in which case it is specified as `['.js', '.jsx']`.

Note that this is different from (and likely a subset of) any `import/resolver`
extensions settings, which may include `.json`, `.coffee`, etc. which will still
factor into the `no-unresolved` rule.

Also, `import/ignore` patterns will overrule this whitelist, so `node_modules` that
end in `.js` will still be ignored by default.

#### `import/ignore`

A list of regex strings that, if matched by a path, will
Expand Down
8 changes: 8 additions & 0 deletions config/react.js
@@ -0,0 +1,8 @@
/**
* - adds `.jsx` as an extension
*/
module.exports = {
settings: {
'import/extensions': ['.js', '.jsx'],
},
}
21 changes: 20 additions & 1 deletion src/core/ignore.js
@@ -1,9 +1,28 @@
import { extname } from 'path'
import Set from 'es6-set'

// one-shot memoized
let cachedSet, lastSettings
function validExtensions({ settings }) {
if (cachedSet && settings === lastSettings) {
return cachedSet
}

// todo: add 'mjs'?
lastSettings = settings
cachedSet = new Set(settings['import/extensions'] || [ '.js' ])
return cachedSet
}

export default function ignore(path, context) {
// ignore node_modules by default
var ignoreStrings = context.settings['import/ignore']
const ignoreStrings = context.settings['import/ignore']
? [].concat(context.settings['import/ignore'])
: ['node_modules']

// check extension whitelist first (cheap)
if (!validExtensions(context).has(extname(path))) return true

if (ignoreStrings.length === 0) return false

for (var i = 0; i < ignoreStrings.length; i++) {
Expand Down
3 changes: 3 additions & 0 deletions src/index.js
Expand Up @@ -27,6 +27,9 @@ export const configs = {
'errors': require('../config/errors'),
'warnings': require('../config/warnings'),

// useful stuff for folks using React
'react': require('../config/react'),

// shhhh... work in progress "secret" rules
'stage-0': require('../config/stage-0'),
}
1 change: 1 addition & 0 deletions tests/files/data.json
@@ -0,0 +1 @@
{ "foo": "bar" }
4 changes: 3 additions & 1 deletion tests/src/rules/named.js
@@ -1,4 +1,4 @@
import { test } from '../utils'
import { test, SYNTAX_CASES } from '../utils'
import { RuleTester } from 'eslint'

var ruleTester = new RuleTester()
Expand Down Expand Up @@ -96,6 +96,7 @@ ruleTester.run('named', rule, {
settings: { 'import/ignore': ['common'] },
}),

...SYNTAX_CASES,
],

invalid: [
Expand Down Expand Up @@ -166,6 +167,7 @@ ruleTester.run('named', rule, {
// parse errors
test({
code: "import { a } from './test.coffee';",
settings: { 'import/extensions': ['.js', '.coffee'] },
errors: [{
message: "Parse errors in imported module './test.coffee': Unexpected token > (1:20)",
type: 'Literal',
Expand Down
3 changes: 2 additions & 1 deletion tests/src/rules/namespace.js
@@ -1,4 +1,4 @@
var test = require('../utils').test
import { test, SYNTAX_CASES } from '../utils'
import { RuleTester } from 'eslint'

var ruleTester = new RuleTester({ env: { es6: true }})
Expand Down Expand Up @@ -86,6 +86,7 @@ const valid = [
parser: 'babel-eslint',
}),

...SYNTAX_CASES,
]

const invalid = [
Expand Down
4 changes: 3 additions & 1 deletion tests/src/rules/no-named-as-default.js
@@ -1,4 +1,4 @@
import { test } from '../utils'
import { test, SYNTAX_CASES } from '../utils'
import { RuleTester } from 'eslint'

const ruleTester = new RuleTester()
Expand All @@ -16,6 +16,8 @@ ruleTester.run('no-named-as-default', rule, {
, parser: 'babel-eslint' }),
test({ code: 'export bar from "./bar";'
, parser: 'babel-eslint' }),

...SYNTAX_CASES,
],

invalid: [
Expand Down
3 changes: 3 additions & 0 deletions tests/src/utils.js
Expand Up @@ -57,4 +57,7 @@ export const SYNTAX_CASES = [
test({ code: 'export default x' }),
test({ code: 'export default class x {}' }),

// issue #267: parser whitelist
test({ code: 'import json from "./data.json"' }),

]

0 comments on commit 359cbbb

Please sign in to comment.