Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
benmosher committed Apr 15, 2018
2 parents e0dcfbd + ec87b64 commit 2e0ed83
Show file tree
Hide file tree
Showing 12 changed files with 488 additions and 26 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com).

## [Unreleased]
### Added
- Ignore type imports for named rule ([#931], thanks [@mattijsbliek])
- Add documentation for [`no-useless-path-segments`] rule ([#1068], thanks [@manovotny])


# [2.11.0] - 2018-04-09
Expand All @@ -16,7 +19,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel

## [2.10.0] - 2018-03-29
### Added
- Autofixer for [`order`] rule ([#711], thanks [@tihonove])
- Autofixer for [`order`] rule ([#908], thanks [@tihonove])
- Add [`no-cycle`] rule: reports import cycles.

## [2.9.0] - 2018-02-21
Expand Down Expand Up @@ -460,8 +463,10 @@ for info on changes for earlier releases.

[`memo-parser`]: ./memo-parser/README.md

[#1068]: https://github.com/benmosher/eslint-plugin-import/pull/1068
[#1046]: https://github.com/benmosher/eslint-plugin-import/pull/1046
[#944]: https://github.com/benmosher/eslint-plugin-import/pull/944
[#908]: https://github.com/benmosher/eslint-plugin-import/pull/908
[#891]: https://github.com/benmosher/eslint-plugin-import/pull/891
[#889]: https://github.com/benmosher/eslint-plugin-import/pull/889
[#880]: https://github.com/benmosher/eslint-plugin-import/pull/880
Expand Down Expand Up @@ -708,3 +713,4 @@ for info on changes for earlier releases.
[@futpib]: https://github.com/futpib
[@klimashkin]: https://github.com/klimashkin
[@lukeapage]: https://github.com/lukeapage
[@manovotny]: https://github.com/manovotny
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
* Forbid webpack loader syntax in imports ([`no-webpack-loader-syntax`])
* Forbid a module from importing itself ([`no-self-import`])
* Forbid a module from importing a module with a dependency path back to itself ([`no-cycle`])
* Prevent unnecessary path segemnts in import and require statements ([`no-useless-path-segments`])

[`no-unresolved`]: ./docs/rules/no-unresolved.md
[`named`]: ./docs/rules/named.md
Expand All @@ -37,6 +38,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
[`no-webpack-loader-syntax`]: ./docs/rules/no-webpack-loader-syntax.md
[`no-self-import`]: ./docs/rules/no-self-import.md
[`no-cycle`]: ./docs/rules/no-cycle.md
[`no-useless-path-segments`]: ./docs/rules/no-useless-path-segments.md

### Helpful warnings

Expand Down Expand Up @@ -84,6 +86,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
* Forbid default exports ([`no-default-export`])
* Forbid anonymous values as default exports ([`no-anonymous-default-export`])
* Prefer named exports to be grouped together in a single export declaration ([`group-exports`])
* Enforce a leading comment with the webpackChunkName for dynamic imports ([`dynamic-import-chunkname`])

[`first`]: ./docs/rules/first.md
[`exports-last`]: ./docs/rules/exports-last.md
Expand All @@ -99,6 +102,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
[`no-anonymous-default-export`]: ./docs/rules/no-anonymous-default-export.md
[`group-exports`]: ./docs/rules/group-exports.md
[`no-default-export`]: ./docs/rules/no-default-export.md
[`dynamic-import-chunkname`]: ./docs/rules/dynamic-import-chunkname.md

## Installation

Expand Down
3 changes: 1 addition & 2 deletions config/recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ module.exports = {
// red flags (thus, warnings)
'import/no-named-as-default': 'warn',
'import/no-named-as-default-member': 'warn',
'import/no-duplicates': 'warn',
'import/unambiguous': 'warn',
'import/no-duplicates': 'warn'
},

// need all these for parsing dependencies (even if _your_ code doesn't need
Expand Down
66 changes: 66 additions & 0 deletions docs/rules/dynamic-import-chunkname.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# dynamic imports require a leading comment with a webpackChunkName (dynamic-import-chunkname)

This rule reports any dynamic imports without a webpackChunkName specified in a leading block comment in the proper format.

This rule enforces naming of webpack chunks in dynamic imports. When you don't explicitly name chunks, webpack will autogenerate chunk names that are not consistent across builds, which prevents long-term browser caching.

## Rule Details
This rule runs against `import()` by default, but can be configured to also run against an alternative dynamic-import function, e.g. 'dynamicImport.'
You can also configure the regex format you'd like to accept for the webpackChunkName - for example, if we don't want the number 6 to show up in our chunk names:
```javascript
{
"dynamic-import-chunkname": [2, {
importFunctions: ["dynamicImport"],
webpackChunknameFormat: "[a-zA-Z0-57-9-/_]"
}]
}
```

### invalid
The following patterns are invalid:

```javascript
// no leading comment
import('someModule');

// incorrectly formatted comment
import(
/*webpackChunkName:"someModule"*/
'someModule',
);

// chunkname contains a 6 (forbidden by rule config)
import(
/* webpackChunkName: "someModule6" */
'someModule',
);

// using single quotes instead of double quotes
import(
/* webpackChunkName: 'someModule' */
'someModule',
);

// single-line comment, not a block-style comment
import(
// webpackChunkName: "someModule"
'someModule',
);
```
### valid
The following patterns are valid:

```javascript
import(
/* webpackChunkName: "someModule" */
'someModule',
);
import(
/* webpackChunkName: "someOtherModule12345789" */
'someModule',
);
```

## When Not To Use It

If you don't care that webpack will autogenerate chunk names and may blow up browser caches and bundle size reports.
3 changes: 2 additions & 1 deletion docs/rules/named.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ Note: for packages, the plugin will find exported names
from [`jsnext:main`], if present in `package.json`.
Redux's npm module includes this key, and thereby is lintable, for example.

A module path that is [ignored] or not [unambiguously an ES module] will not be reported when imported.
A module path that is [ignored] or not [unambiguously an ES module] will not be reported when imported. Note that type imports, as used by [Flow], are always ignored.

[ignored]: ../../README.md#importignore
[unambiguously an ES module]: https://github.com/bmeck/UnambiguousJavaScriptGrammar
[Flow]: https://flow.org/


## Rule Details
Expand Down
48 changes: 48 additions & 0 deletions docs/rules/no-useless-path-segments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# import/no-useless-path-segments

Use this rule to prevent unnecessary path segemnts in import and require statements.

## Rule Details

Given the following folder structure:

```
my-project
├── app.js
├── footer.js
├── header.js
└── pages
├── about.js
├── contact.js
└── index.js
```

The following patterns are considered problems:

```js
/**
* in my-project/app.js
*/

import "./../pages/about.js"; // should be "./pages/about.js"
import "./../pages/about"; // should be "./pages/about"
import "../pages/about.js"; // should be "./pages/about.js"
import "../pages/about"; // should be "./pages/about"
import "./pages//about"; // should be "./pages/about"
import "./pages/"; // should be "./pages"
```

The following patterns are NOT considered problems:

```js
/**
* in my-project/app.js
*/

import "./header.js";
import "./pages";
import "./pages/about";
import ".";
import "..";
import fs from "fs";
```
8 changes: 8 additions & 0 deletions memo-parser/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# eslint-plugin-import/memo-parser


## NOTE!

This used to improve performance, but as of ESLint 5 and v2 of this plugin, it seems to just consume a bunch of memory and slightly increase lint times.

**Not recommended for use at this time!**


This parser is just a memoizing wrapper around some actual parser.

To configure, just add your _actual_ parser to the `parserOptions`, like so:
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const rules = {
'unambiguous': require('./rules/unambiguous'),
'no-unassigned-import': require('./rules/no-unassigned-import'),
'no-useless-path-segments': require('./rules/no-useless-path-segments'),
'dynamic-import-chunkname': require('./rules/dynamic-import-chunkname'),

// export
'exports-last': require('./rules/exports-last'),
Expand Down
70 changes: 70 additions & 0 deletions src/rules/dynamic-import-chunkname.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import docsUrl from '../docsUrl'

module.exports = {
meta: {
docs: {
url: docsUrl('dynamic-import-chunkname'),
},
schema: [{
type: 'object',
properties: {
importFunctions: {
type: 'array',
uniqueItems: true,
items: {
type: 'string',
},
},
webpackChunknameFormat: {
type: 'string',
},
},
}],
},

create: function (context) {
const config = context.options[0]
const { importFunctions = [] } = config || {}
const { webpackChunknameFormat = '[0-9a-zA-Z-_/.]+' } = config || {}

const commentFormat = ` webpackChunkName: "${webpackChunknameFormat}" `
const commentRegex = new RegExp(commentFormat)

return {
CallExpression(node) {
if (node.callee.type !== 'Import' && importFunctions.indexOf(node.callee.name) < 0) {
return
}

const sourceCode = context.getSourceCode()
const arg = node.arguments[0]
const leadingComments = sourceCode.getComments(arg).leading

if (!leadingComments || leadingComments.length !== 1) {
context.report({
node,
message: 'dynamic imports require a leading comment with the webpack chunkname',
})
return
}

const comment = leadingComments[0]
if (comment.type !== 'Block') {
context.report({
node,
message: 'dynamic imports require a /* foo */ style comment, not a // foo comment',
})
return
}

const webpackChunkDefinition = comment.value
if (!webpackChunkDefinition.match(commentRegex)) {
context.report({
node,
message: `dynamic imports require a leading comment in the form /*${commentFormat}*/`,
})
}
},
}
},
}
3 changes: 2 additions & 1 deletion src/rules/named.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ module.exports = {

create: function (context) {
function checkSpecifiers(key, type, node) {
if (node.source == null) return // local export, ignore
// ignore local exports and type imports
if (node.source == null || node.importKind === 'type') return

if (!node.specifiers
.some(function (im) { return im.type === type })) {
Expand Down
Loading

0 comments on commit 2e0ed83

Please sign in to comment.