Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add import-style rule #232

Closed
wants to merge 6 commits into from
Closed

Add import-style rule #232

wants to merge 6 commits into from

Conversation

rahgurung
Copy link

@rahgurung rahgurung commented Feb 2, 2019

Fixed #211

Things Done:

  • Throws error on directly importing default modules like utils, lodash, etc with support for overriding the objects to add own modules.

@sindresorhus sindresorhus changed the title #211 - Add no-direct-import rule Add no-direct-import rule Feb 2, 2019
@sindresorhus
Copy link
Owner

(I just need a little help on the todo part, can you give me a code pointer or any current rule which does this, I will come up with a solution.)

This rule accepts options: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/rules/catch-error-name.js See the schema part. More here; https://eslint.org/docs/developer-guide/working-with-rules#options-schemas

test/no-direct-import.js Outdated Show resolved Hide resolved
docs/rules/no-direct-import.md Outdated Show resolved Hide resolved
readme.md Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
readme.md Outdated Show resolved Hide resolved
@sindresorhus
Copy link
Owner

The rule should support enforcing destructuring and using default import, as commented in #211 (comment) So I think the rule needs a better name. It can't have the no- prefix:

we could also have a list for the inverse? For example, chalk should not be destructured, but people still do. Same with the core path module.

@rahgurung
Copy link
Author

The rule should support enforcing destructuring and using default import, as commented in #211 (comment) So I think the rule needs a better name. It can't have the no- prefix:

we could also have a list for the inverse? For example, chalk should not be destructured, but people still do. Same with the core path module.

how about prefer-default-import ? @sindresorhus

@futpib
Copy link
Contributor

futpib commented Feb 5, 2019

How about import-specifier-style or import-destructuring?

@rahgurung
Copy link
Author

@sindresorhus

@sindresorhus
Copy link
Owner

How about import-specifier-style or import-destructuring?

The specifier is the right side of the import statement. The braces in import is also not destructuring.

How about just import-style or import-default-or-named?

@rahgurung
Copy link
Author

Another problem is how can I work for the inverse part, can I take an input from user where he will input something like import-style: inverse and those module names will be linted in inverse way ?

@rahgurung
Copy link
Author

How about import-specifier-style or import-destructuring?

The specifier is the right side of the import statement. The braces in import is also not destructuring.

How about just import-style or import-default-or-named?

Import-style sounds good to me,

@futpib
Copy link
Contributor

futpib commented Feb 7, 2019

The specifier is the right side of the import statement. The braces in import is also not destructuring.

Specifier is the left-hand side. In case of a require call it can instead be a destructring. import-style is ok

@sindresorhus
Copy link
Owner

sindresorhus commented Feb 7, 2019

Specifier is the left-hand side.

I just Google'd "javascript import specifier" and all the sources claim it's the right part, like: https://nodejs.org/api/esm.html#esm_url_based_paths

@sindresorhus
Copy link
Owner

Alright, let's go with import-style.

@sindresorhus
Copy link
Owner

Another problem is how can I work for the inverse part, can I take an input from user where he will input something like import-style: inverse and those module names will be linted in inverse way ?

The rule should accepts an options-object like this:

{
	defaultExport: [
		'path',
		'chalk'
	],
	namedExport: [
		'util',
		'lodash',
		'underscore'
	]
}

With the above being the default.

@sindresorhus
Copy link
Owner

sindresorhus commented Feb 7, 2019

@futpib Or do you think we should do it like this so it's easier to override individual entries?

{
	defaultExport: {
		path: true,
		chalk: true
	},
	namedExport: {
		util: true,
		lodash: true,
		underscore: true
	}
}

@futpib
Copy link
Contributor

futpib commented Feb 7, 2019

I just Google'd "javascript import specifier" and all the sources claim it's the right part, like: nodejs.org/api/esm.html#esm_url_based_paths

I went with what astexplorer and estree call import specifier, and it's the same in the standard. Ok, this is too confusing for a rule name.

@futpib
Copy link
Contributor

futpib commented Feb 7, 2019

Or do you think we should do it like this so it's easier to override individual entries?

Yes, I prefer the object variant. Would be consistent with what I chose in #237

@sindresorhus
Copy link
Owner

sindresorhus commented Feb 7, 2019

👍, let's go with the object variant.

@rahgurung
Copy link
Author

Ok thanks, I will come up with a commit soon.

@rahgurung rahgurung changed the title Add no-direct-import rule Add import-style rule Feb 11, 2019
@rahgurung
Copy link
Author

I'm stuck on how to pass the configurations, I am working in AST Explorer How do I pass options here? @futpib @sindresorhus

@futpib
Copy link
Contributor

futpib commented Feb 18, 2019

@gurungrahul2 Not sure if you can. But you can hardcode them for testing and remove when you are ready to commit the code.

@rahgurung
Copy link
Author

What would having something like

defaultExport: {
		mymodule: false
	}

mean?
Should mymodule be destructed or false means let it be imported anyway?
@sindresorhus @futpib

@futpib
Copy link
Contributor

futpib commented Jul 13, 2019

@gurrrung We are basically modelling a set of strings in JSON here. defaultExport would be a set of module names for which only the default export should be used. Only value true means that the module is in the set.

The benefit of this design is that users can override the build-in defaults. We could merge the user-supplied option with the default one (for example with defaultsDeep). So if we had { util: true, path: true } hardcoded, and a user (who wants to lift the restriction off of util module) passed { util: false }, the result would be { util: false, path: true }, which result in util not being restricted, but all the other hardcoded defaults (in this example, only path) would still apply.

@sindresorhus
Copy link
Owner

@gurrrung Still interested in finishing this?

@rahgurung
Copy link
Author

Yes, I'm on it.

@rahgurung
Copy link
Author

Why would Integration tests blow up. 😕

@sindresorhus
Copy link
Owner

@fisker Would you be able to help review this?

errors: [buildError({moduleName: 'util', type: 'defaultImport'})]
},
{
code: 'const foo = myFunction(\'util\')',
Copy link
Collaborator

@fisker fisker Sep 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is error?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! Thanks for the review. I was a little busy in academic work. Yeah, it shouldn't be error, I'll add the check to throw error only in case of require().

Copy link
Collaborator

@fisker fisker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the result of

const promisify = require('utils').promisify;

and dynamic import

(async () => {
  const lodash = (await import('lodash')).default;
})();

(async () => {
  const {default: lodash} = await import('lodash');
})();

(async () => {
  const {chunk} = await import('lodash');
})();

we should add them to tests

@fisker
Copy link
Collaborator

fisker commented Sep 25, 2019

Should we also check export ... from ...?

export {chunk} from 'utils';
export * as default from 'utils';
export {default as default} from 'lodash';
export {default as lodash} from 'lodash';
export * from 'lodash';

@rahgurung
Copy link
Author

rahgurung commented Oct 19, 2019

What is the result of

const promisify = require('utils').promisify;

and dynamic import

(async () => {
  const lodash = (await import('lodash')).default;
})();

(async () => {
  const {default: lodash} = await import('lodash');
})();

(async () => {
  const {chunk} = await import('lodash');
})();

we should add them to tests

that's brilliant. I really couldn't thing of this. Can you give me more insight like what should be the behaviour?

@sindresorhus
Copy link
Owner

Can you give me more insight like what should be the behaviour?

@fisker ^

@sindresorhus
Copy link
Owner

@gurrrung Still interested in finishing this?

@fisker
Copy link
Collaborator

fisker commented Feb 16, 2020

@gurrrung

const promisify = require('utils').promisify;

I mean we need add test, make sure this pass.


(async () => {
  const lodash = (await import('lodash')).default;
})();

(async () => {
  const {default: lodash} = await import('lodash');
})();

(async () => {
  const {chunk} = await import('lodash');
})();

I'm not sure should we support dynamic import?


@sindresorhus

export ... from and import() support? You should make the call.

I suggest we should support export ... from, import() maybe a little hard , we can ignore that for now.

@sindresorhus
Copy link
Owner

I'm not sure should we support dynamic import?

Nah, not worth the effort. For all our rules, we can stay with the top-level imports.

I suggest we should support export ... from,

Agreed

@sindresorhus
Copy link
Owner

Closing for lack of activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rule proposal: Don't import util Node.js core module directly
4 participants