import-js / eslint-plugin-import Goto Github PK
View Code? Open in Web Editor NEWESLint plugin with rules that help validate proper imports.
License: MIT License
ESLint plugin with rules that help validate proper imports.
License: MIT License
verify this shows up as a default export in an importing module, i.e.
// mod.js
export default function () {}
// bar.js
export default from './mod'
// foo.js
import default from './bar' // <= should not report for import/default
Upon reflection, things like Babel's different module modes (AMD, CommonJS, etc.) lend themselves to using ES6 imports for modules that may not be ES6 modules. (i.e., most npm modules)
Possible solutions:
lib
into node_modules
) will be losteslint-disable
but scoped to the plugin (i.e., redundant)working today: use //eslint-disable-line import/...
In the interest of highlighting the source string instead of its leading quote, as shown here:
...add 1 to the column location of node.source
when reporting.
Probably want to pull this out to some util since it will be needed by a number of rules (no-duplicates
shown here).
Also worth opening up PyCharm to see what the impact is there. This may be a Sublime quirk.
I'm getting an error using 0.7.4
:
node_modules/eslint/lib/eslint.js:650
throw new Error("Definition for rule '" + key + "' was not
^
Error: Definition for rule 'import/no-reassign' was not found.
at node_modules/eslint/lib/eslint.js:650:27
/title
Investigate. Fix.
(maybe the .
is actual YAML syntax?)
import/commonjs
or something. maybe even as a metaplugin?at module scope level:
exports.[name]
and exports["string literal"]
as named exportsmodule.exports = { ... }
as namespace (all keys as named exports)module.exports = non-object
as defaultThings that will spuriously warn as a result:
May force ESLint >=0.19 dependency, given the escope
issues before then.
I'm curious why...
I'm seeing an error in the SublimeText console when running 0.7.5
:
SublimeLinter: eslint: Example.jsx ['node_modules/.bin/eslint', '--format', 'compact', '--stdin', '--stdin-filename', '__RELATIVE_TO_FOLDER__', '--stdin-filename', '@']
SublimeLinter: eslint output:
Error while loading rule 'import/export': Set is not defined
ReferenceError: Error while loading rule 'import/export': Set is not defined
at exports.default (node_modules/eslint-plugin-import/lib/rules/export.js:16:22)
at node_modules/eslint/lib/eslint.js:628:32
at Array.forEach (native)
at EventEmitter.module.exports.api.verify (node_modules/eslint/lib/eslint.js:619:16)
at processText (node_modules/eslint/lib/cli-engine.js:201:27)
at CLIEngine.executeOnText (node_modules/eslint/lib/cli-engine.js:361:26)
at Object.cli.execute (node_modules/eslint/lib/cli.js:179:36)
at configInit.initializeConfig.exitCode (node_modules/eslint/bin/eslint.js:13:28)
at ConcatStream.<anonymous> (node_modules/eslint/node_modules/concat-stream/index.js:36:43)
at ConcatStream.EventEmitter.emit (events.js:117:20)
For reference, we use Set
in nfl/react-helmet, and include a shim to polyfill them.
It would be nice to have the ability to exclude certain modules for the named
rule.
Modules like react-router and immutable do not use ES6 exports, for example.
Alternatively, searching for modification of exports
may allow it to work appropriately.
I.E.
`'${name}' was not found in imported module '${source}'`
Warning rule for ES6 imports where the remote module mentions module
, module.exports
, exports
.
Need to investigate swapping in babel-eslint
as the parser instead of the baked-in espree
, as an option.
For those brave enough to use babel-eslint
, this would continue to allow all the bleeding-edge experimental JS through without parse errors. (prompted by issue #36)
Best case: infer this setting from the .eslintrc
/rule context.
Worst case: add an import/parser
setting analogously to the setting in ESLint proper.
For example, I get this exception regarding an import of core Node module crypto
:
Error: ENOENT, no such file or directory 'crypto'
I can only imagine the exceptions from trying to parse CoffeeScript... should just swallow errors as if the file does not exist, and let exists
handle it.
Need a better name.
Given:
// foo.js
export default 'foo';
export const bar = 'baz';
...this would be valid:
import foo from './foo.js';
...and this would be reported:
import bar from './foo.js';
Message something like Using exported name 'bar' as identifier for default export.
Rationale: using an exported name as the name of the default export is either
foo.js
probably expect the name to be foo
bar
and forgot the brackets (the case that is prompting this)Question: use babel-runtime
+ runtime
transformer instead of importing specific polyfills for Map, Set, etc.?
Could set as a peerDependency
so installation is up to the user to determine necessity (wouldn't be required once Node fully implements all ES6 runtime features).
Add a setting to swap out and/or add a custom package resolver.
When importing a module that contains stage 0 proposals, e.g.:
// Foo.jsx
class Foo {
// ES7 static members
static bar = true;
}
export default Foo;
// Importer.jsx
import Foo from "Foo"
I get the following false-positive:
error No default export found in module import/default
I dug into the code a bit and found Espree has issues parsing experimental code:
{ settings:
{ 'import/ignore': [ 'node_modules' ],
'import/resolve': { extensions: [Object], moduleDirectory: [Object] } },
hasDefault: false,
named: {},
errors:
[ { [Error: Line 6: Unexpected token =]
index: 185,
lineNumber: 6,
column: 24,
description: 'Unexpected token =' } ] }
Note: We use babel-eslint in order to support linting with experimental code.
I'm not asking that you support experimental code (although it would be nice!), but it would be great if the parsing error was surfaced, or at the very least a note that this rule does not support experimental code.
idea: check export cache for imported names that match undefined vars?
no-common
=> es6-only
? or add no-amd
?
no-common
won't detect AMD modules... should the arms race of specific non-ES6 module types continue (more come to mind) or should it be retooled to report all import statements with specifiers* that point to a resolved module without ES6 syntax?
A thought: this would probably be cheaper to implement, as export
syntax may only be present in the root scope. Would not need to traverse any deeper than the body, which means estraverse
goes away and an empty ExportsMap
is the harbinger of this report.
Also removes the need for "es6-only"
as a setting for any rules.
I think I've sold myself on es6-only
as a first-class rule, and dropping no-common
+ rule-specific measures.
import 'module'
. Which makes sense.import { key } from './module'
const { key: path } = this.props.row
erronously flags key
as a re-assign, while conversely
import { key } from './module'
const { path: key } = this.props.row
is not reported (but is the true re-assignment),
Currently, it's highlighting the import
keyword. Should highlight the invalid path, instead.
Specifically, Immutable.js's UMD preamble does not trigger a no-common
report:
function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.Immutable = factory()
}...
New rule to report on assignment to any imported name (default, name, or namespace) at any scope.
Need to check:
Flag subsequent export default ...
statements if more than one is encountered in a given file.
Is it a preventer or an enforcer?
Need to see what ESLint does to get around this.
index.js
if path is a directory (and node
is specified as an environment?)Hi,
Great plugin! We use React internally and use .jsx
as our file extensions. Can you add an option to configure what extensions should be resolved? resolve
already takes this option. In fact, maybe it would be best if we could pass an object of options which would be fed to resolve
.
Thoughts?
Hi, presumably I'm doing something wrong here, but I couldn't find any info. I've just installed and added this plugin to my .eslintrc
:
{
"parser": "babel-eslint",
"extends": "eslint:recommended",
"plugins": [ "react", "import" ],
"rules": {
"comma-dangle": 0,
"no-unused-vars": [2, {"vars": "all", "args": "none"}],
"no-console": 1,
"no-var": 2,
"no-debugger": 1,
"indent": [2, 2, {"SwitchCase": 1}],
"max-len": [1, 80, 2],
"prefer-const": 2
},
"settings": {
"import/resolve": {
"extenstions": [ ".es6", ".js", ".jsx" ]
},
"import/parser": "babel-eslint"
},
"env": {
"browser": true
}
}
But when I parse I get this:
/Users/rhys/Projects/2suggestions/paydirt/app/assets/javascripts/es6/components/projects/show_details.es6
4:41 error Unable to resolve path to module '../input/dropdown' import/no-unresolved
4:41 warning 'null' imported multiple times import/no-duplicates
5:20 error Unable to resolve path to module './status' import/no-unresolved
5:20 warning 'null' imported multiple times import/no-duplicates
6:18 error Unable to resolve path to module '../icon' import/no-unresolved
6:18 warning 'null' imported multiple times import/no-duplicates
7:48 error Unable to resolve path to module '../../entities/projects' import/no-unresolved
7:48 warning 'null' imported multiple times import/no-duplicates
8:29 error Unable to resolve path to module '../anchors' import/no-unresolved
8:29 warning 'null' imported multiple times import/no-duplicates
// show_details.es6
import Dropdown, { Item, Divider } from '../input/dropdown';
import Status from './status';
import Icon from '../icon';
import { hasHourly, invoiceUrl, moveUrl } from '../../entities/projects';
import { ModalAnchor } from '../anchors';
// ...
I'd really appreciate some help, this looks to be an excellent tool!
(optional?) rule to warn on more than one import from the same module path, i.e.
import { x } from './mod'
import { y } from './mod'
reports on both lines, whereas
import { x, y } from './mod'
is valid.
Also need to consider an option / internal work up / an additional rule to consider the abbreviated export/import syntax from Lee Byron's ES7 import proposal.
i.e. no-import-export
or something to warn on
import { foo } from './mod'
export { foo }
and recommend
export { foo } from './mod'
Those are valid ES6, but would need to consider things like
export MyCoolClass from './mod'
vs.
import MyCoolClass from './mod'
export default MyCoolClass
as the latter is the valid ES6 form.
Ensure that it does not report on normal object/array creation, just Patterns for variable assignment/declaration/parameters.
Report require(...)
of ES6 modules.
Similarly to named
rule, need option to ignore if there are no export statements at all.
//index.js
export function test {}
//client.js
import {test} from './middlewares'
Error: test not found in './middlewares' [import/named]
Not my actual real project, but this was the most minimal example i could find ๐
Investigate a plugin-level cache for export names, such that linting a large project in one go (one process) need not re-parse repeatedly imported modules.
Not even sure this is possible given the eslint architecture/plugin system. Feels intuitively useful, though.
fc4f99e breaks file resolution on Microsoft Windows. The implementation of fileExistsWithCaseSync fails to take into account drive letters and will always return false due to path.basename("C:") returning an empty string.
Looks like ESLint proper has updated no-redeclare
to include modules as of 1.0.0-rc1 (see eslint/eslint#2948).
As such, should excise the redundant bits of no-reassign
and refocus on imported namespace mutation.
Ensure, given:
export * from './Panel'
export * from './buttons'
export { x as v } from './x'
./Panel
, ./buttons
each have any named exports (import/export
)
./Panel
, ./buttons
should be resolvable (import/no-unresolved
)import/named
should confirm ./x
exports name x
invalid: export { default as Glyphicon } from './Glyphicon'
Lee Byron's ES7 stage 1 proposed additions: (require babel-eslint
for now)
// need default check
export v from 'mod'
export default from 'mod'
// need namespace check
export * as ns from 'mod'
// not sure if these will follow from the above
export v, {x, y as w} from "mod"
export v, * as ns from "mod"
mod
has a default export (via import/default
)mod
exposed any names (via import/namespace
)mod
does not export a name v
(via import/no-named-as-default
)extra credit: something like an import/experimental
setting for stage 0, 1, 2 for things like this? I figure it's implicitly on/off via import/parser
=babel-eslint
, by virtue of Espree probably barfing on this syntax, prompting a report from no-errors
.
Are there any thoughts on implementing sorting rule? With logic like:
Does it make any sense for anyone?
need to figure out how to run tests without the polyfill to simulate live plugin execution.
probably should compile tests or rewrite back to ES5, and reference lib/rules
instead of src/rules
.
~/project/node_modules/eslint-plugin-import/lib/rules/no-reassign.js:15
if (locals.has(id.name)) context.report(id, message(id.name))
^
TypeError: Cannot read property 'name' of null
at checkIdentifier (~/project/node_modules/eslint-plugin-import/lib/rules/no-reassign.js:15:22)
at EventEmitter.FunctionDeclaration (~/project/node_modules/eslint-plugin-import/lib/rules/no-reassign.js:53:7)
at EventEmitter.emit (events.js:129:20)
at Controller.controller.traverse.enter (~/project/node_modules/eslint/lib/eslint.js:725:25)
at Controller.__execute (~/project/node_modules/eslint/node_modules/estraverse/estraverse.js:393:31)
at Controller.traverse (~/project/node_modules/eslint/node_modules/estraverse/estraverse.js:491:28)
at EventEmitter.module.exports.api.verify (~/project/node_modules/eslint/lib/eslint.js:718:24)
at verify (~/project/node_modules/gulp-eslint/index.js:21:25)
at DestroyableTransform._transform (~/project/node_modules/gulp-eslint/index.js:44:18)
at DestroyableTransform.Transform._read (~/project/node_modules/gulp-eslint/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
This: http://www.appveyor.com/docs/lang/nodejs-iojs
Need a root path, a la webpack's resolve.root
. i.e., if .eslintrc
has something like
---
settings:
resolve.root: 'src'
...then the resolver for resolve.js
should look in path.join(process.cwd(), 'src')
as an additional base path.
Extra credit: allow specification of a Node-compatible JS/JSON file with a path (i.e. './webpack.config.js:resolve.root').
May want to spec out some environment-based defaults (webpack, browserify, requirejs, explicitly check for node, etc.)
Need to investigate proper setting key conventions (i.e. import/resolveRoot
?) within ESLint plugins.
Hi, can you update your peerDependency to work with [email protected]
? This is the same issue as: jsx-eslint/eslint-plugin-react#154.
The following should work:
"peerDependencies": {
"eslint": ">=0.16.0 || ~1.0.0-rc-0"
}
Here's a strange little edge case I just bumped into.
If any exported object contains a spread of another exported object, import/named
and import/namespace
breaks.
package.json
dependencies:
"babel": "^5.8.23",
"babel-core": "^5.8.23",
"babel-eslint": "^4.1.1",
"eslint": "^1.3.1",
"eslint-plugin-import": "^0.7.8",
"eslint-plugin-react": "^3.3.1"
eslintrc
:
{
"parser": "babel-eslint",
"plugins": [
"react",
"import"
],
"env": {
"browser": true,
"node": true
},
"ecmaFeatures": {
"arrowFunctions": true,
"blockBindings": true,
"classes": true,
"defaultParams": true,
"destructuring": true,
"forOf": true,
"generators": false,
"modules": true,
"objectLiteralComputedProperties": true,
"objectLiteralDuplicateProperties": false,
"objectLiteralShorthandMethods": true,
"objectLiteralShorthandProperties": true,
"spread": true,
"superInFunctions": true,
"templateStrings": true,
"jsx": true
}
}
test1.js
contains:
export const test = {
hello: '1'
};
export const betterTest = {
...test,
world: '1'
};
test2.js
contains:
import * as mock from './test1';
import {test} from './test1';
console.log(mock.betterTest);
console.log(test);
Running local ESLint:
`npm bin`/eslint --no-color test2.js
Outputs:
test2.js
1:8 error No exported names found in module './test1' import/namespace
2:9 error test not found in './test1' import/named
4:18 error 'betterTest' not found in imported namespace mock import/namespace
โ 3 problems (3 errors, 0 warnings)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.