Skip to content

Commit

Permalink
Add export ... from ... support
Browse files Browse the repository at this point in the history
  • Loading branch information
futpib committed Jul 18, 2020
1 parent 4e08529 commit ce6d268
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/rules/import-style.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ Default: `true`

Pass `"checkDynamicImport": false` to disable linting of dynamic import statements (like `await import('foo')`) completely.

### checkExportFrom

Type: `boolean`\
Default: `false`

Pass `"checkExportFrom": true` to enable linting of export-from statements (like `export ... from 'foo'`).

### checkRequire

Type: `boolean`\
Expand Down
52 changes: 52 additions & 0 deletions rules/import-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,30 @@ const getActualImportDeclarationStyles = importDeclaration => {
return [...styles];
};

const getActualExportDeclarationStyles = exportDeclaration => {
const {specifiers} = exportDeclaration;

if (specifiers.length === 0) {
return ['unassigned'];
}

const styles = new Set();

for (const specifier of specifiers) {
if (specifier.type === 'ExportSpecifier') {
if (specifier.exported.type === 'Identifier' && specifier.exported.name === 'default') {
styles.add('default');
continue;
}

styles.add('named');
continue;
}
}

return [...styles];
};

const getActualAssignmentTargetImportStyles = assignmentTarget => {
if (assignmentTarget.type === 'Identifier') {
return ['namespace'];
Expand Down Expand Up @@ -124,6 +148,7 @@ const create = context => {
extendDefaultStyles = true,
checkImport = true,
checkDynamicImport = true,
checkExportFrom = false,
checkRequire = true
} = {}
] = context.options;
Expand Down Expand Up @@ -219,6 +244,30 @@ const create = context => {
};
}

if (checkExportFrom) {
visitor = {
...visitor,

ExportAllDeclaration(node) {
const moduleName = getStringIfConstant(node.source, context.getScope());

const allowedImportStyles = styles.get(moduleName);
const actualImportStyles = ['namespace'];

report(node, moduleName, actualImportStyles, allowedImportStyles);
},

ExportNamedDeclaration(node) {
const moduleName = getStringIfConstant(node.source, context.getScope());

const allowedImportStyles = styles.get(moduleName);
const actualImportStyles = getActualExportDeclarationStyles(node);

report(node, moduleName, actualImportStyles, allowedImportStyles);
}
};
}

if (checkRequire) {
visitor = {
...visitor,
Expand Down Expand Up @@ -261,6 +310,9 @@ const schema = [
checkDynamicImport: {
type: 'boolean'
},
checkExportFrom: {
type: 'boolean'
},
checkRequire: {
type: 'boolean'
},
Expand Down
54 changes: 54 additions & 0 deletions test/import-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const ruleTester = avaRuleTester(test, {
});

const options = {
checkExportFrom: true,
styles: {
unassigned: {
unassigned: true
Expand Down Expand Up @@ -77,6 +78,7 @@ ruleTester.run('import-style', rule, {
'require(\'unassigned\')',
'import \'unassigned\'',
'import(\'unassigned\')',
'export {} from \'unassigned\'',

'const x = require(\'default\')',
'const {default: x} = require(\'default\')',
Expand All @@ -86,6 +88,7 @@ ruleTester.run('import-style', rule, {
const {default: x} = await import('default');
}
`,
'export {default} from \'default\'',

'const x = require(\'namespace\')',
'import * as x from \'namespace\'',
Expand All @@ -94,6 +97,7 @@ ruleTester.run('import-style', rule, {
const x = await import('namespace');
}
`,
'export * from \'namespace\'',

'const {x} = require(\'named\')',
'const {x: y} = require(\'named\')',
Expand All @@ -109,6 +113,8 @@ ruleTester.run('import-style', rule, {
const {x: y} = await import('named');
}
`,
'export {x} from \'named\'',
'export {x as y} from \'named\'',

{
code: 'import {inspect} from \'util\'',
Expand Down Expand Up @@ -264,6 +270,22 @@ ruleTester.run('import-style', rule, {
`,
errors: [unassignedError]
},
{
code: 'export * from \'unassigned\'',
errors: [unassignedError]
},
{
code: 'export {x} from \'unassigned\'',
errors: [unassignedError]
},
{
code: 'export {x as y} from \'unassigned\'',
errors: [unassignedError]
},
{
code: 'export {default} from \'unassigned\'',
errors: [unassignedError]
},

{
code: 'require(\'default\')',
Expand Down Expand Up @@ -321,6 +343,18 @@ ruleTester.run('import-style', rule, {
`,
errors: [defaultError]
},
{
code: 'export * from \'default\'',
errors: [defaultError]
},
{
code: 'export {x} from \'default\'',
errors: [defaultError]
},
{
code: 'export {x as y} from \'default\'',
errors: [defaultError]
},

{
code: 'require(\'namespace\')',
Expand Down Expand Up @@ -374,6 +408,18 @@ ruleTester.run('import-style', rule, {
`,
errors: [namespaceError]
},
{
code: 'export {x} from \'namespace\'',
errors: [namespaceError]
},
{
code: 'export {x as y} from \'namespace\'',
errors: [namespaceError]
},
{
code: 'export {default} from \'namespace\'',
errors: [namespaceError]
},

{
code: 'require(\'named\')',
Expand Down Expand Up @@ -419,6 +465,14 @@ ruleTester.run('import-style', rule, {
`,
errors: [namedError]
},
{
code: 'export * from \'named\'',
errors: [namedError]
},
{
code: 'export {default} from \'named\'',
errors: [namedError]
},

{
code: 'import util, {inspect} from \'named\'',
Expand Down

0 comments on commit ce6d268

Please sign in to comment.