Skip to content

Commit 8604129

Browse files
committed
Add new rule no-webpack-loader-syntax
Webpack allows specifying loaders and their configuration inline in imports using a non-standard import syntax. This rule allows disabling this non-standard syntax in imports.
1 parent e3c41ca commit 8604129

File tree

5 files changed

+143
-0
lines changed

5 files changed

+143
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
1010
- `recommended` shared config. Roughly `errors` and `warnings` mixed together,
1111
with some `parserOptions` in the mix. ([#402])
1212
- `react` shared config: added `jsx: true` to `parserOptions.ecmaFeatures`.
13+
- Added [`no-webpack-loader-syntax`] rule: forbid custom Webpack loader syntax in imports. ([#585], thanks [@fson]!)
1314

1415
### Breaking
1516
- [`import/extensions` setting] defaults to `['.js']`. ([#306])
@@ -331,7 +332,9 @@ for info on changes for earlier releases.
331332
[`max-dependencies`]: ./docs/rules/max-dependencies.md
332333
[`no-internal-modules`]: ./docs/rules/no-internal-modules.md
333334
[`no-dynamic-require`]: ./docs/rules/no-dynamic-require.md
335+
[`no-webpack-loader-syntax`]: ./docs/rules/no-webpack-loader-syntax.md
334336

337+
[#585]: https://github.com/benmosher/eslint-plugin-import/pull/585
335338
[#568]: https://github.com/benmosher/eslint-plugin-import/pull/568
336339
[#555]: https://github.com/benmosher/eslint-plugin-import/pull/555
337340
[#538]: https://github.com/benmosher/eslint-plugin-import/pull/538
@@ -488,3 +491,4 @@ for info on changes for earlier releases.
488491
[@spalger]: https://github.com/spalger
489492
[@preco21]: https://github.com/preco21
490493
[@skyrpex]: https://github.com/skyrpex
494+
[@fson]: https://github.com/fson
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# no-webpack-loader-syntax
2+
3+
Forbid Webpack loader syntax in imports.
4+
5+
[Webpack](http://webpack.github.io) allows specifying [loaders](http://webpack.github.io/docs/loaders.html) and their configuration inline in imports using a special syntax like this:
6+
```js
7+
var moduleWithOneLoader = require("my-loader!./my-awesome-module");
8+
```
9+
10+
This syntax is non-standard, so it couples the code using to Webpack. The recommended way to specify Webpack loader configuration is in a [Webpack configuration file](http://webpack.github.io/docs/loaders.html#loaders-by-config).
11+
12+
## Rule Details
13+
14+
### Fail
15+
16+
```js
17+
import myModule from 'my-loader!my-module';
18+
import theme from 'style!css!./theme.css';
19+
20+
var myModule = require('my-loader!./my-module');
21+
var theme = require('style!css!./theme.css');
22+
```
23+
24+
### Pass
25+
26+
```js
27+
import myModule from 'my-module';
28+
import theme from './theme.css';
29+
30+
var myModule = require('my-module');
31+
var theme = require('./theme.css');
32+
```
33+
34+
## When Not To Use It
35+
36+
If you have a project that doesn't use Webpack you can safely disable this rule.

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const rules = {
2121
'no-extraneous-dependencies': require('./rules/no-extraneous-dependencies'),
2222
'no-absolute-path': require('./rules/no-absolute-path'),
2323
'no-nodejs-modules': require('./rules/no-nodejs-modules'),
24+
'no-webpack-loader-syntax': require('./rules/no-webpack-loader-syntax'),
2425
'order': require('./rules/order'),
2526
'newline-after-import': require('./rules/newline-after-import'),
2627
'prefer-default-export': require('./rules/prefer-default-export'),

src/rules/no-webpack-loader-syntax.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import isStaticRequire from '../core/staticRequire'
2+
3+
function reportIfNonStandard(context, node, name) {
4+
if (name.indexOf('!') !== -1) {
5+
context.report(node, `Unexpected '!' in '${name}'. ` +
6+
'Do not use import syntax to configure webpack loaders.'
7+
)
8+
}
9+
}
10+
11+
module.exports = {
12+
meta: {
13+
docs: {},
14+
},
15+
16+
create: function (context) {
17+
return {
18+
ImportDeclaration: function handleImports(node) {
19+
reportIfNonStandard(context, node, node.source.value)
20+
},
21+
CallExpression: function handleRequires(node) {
22+
if (isStaticRequire(node)) {
23+
reportIfNonStandard(context, node, node.arguments[0].value)
24+
}
25+
},
26+
}
27+
},
28+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { test } from '../utils'
2+
3+
import { RuleTester } from 'eslint'
4+
5+
const ruleTester = new RuleTester()
6+
, rule = require('rules/no-webpack-loader-syntax')
7+
8+
const message = 'Do not use import syntax to configure webpack loaders.'
9+
10+
ruleTester.run('no-webpack-loader-syntax', rule, {
11+
valid: [
12+
test({ code: 'import _ from "lodash"'}),
13+
test({ code: 'import find from "lodash.find"'}),
14+
test({ code: 'import foo from "./foo.css"'}),
15+
test({ code: 'import data from "@scope/my-package/data.json"'}),
16+
test({ code: 'var _ = require("lodash")'}),
17+
test({ code: 'var find = require("lodash.find")'}),
18+
test({ code: 'var foo = require("./foo")'}),
19+
test({ code: 'var foo = require("../foo")'}),
20+
test({ code: 'var foo = require("foo")'}),
21+
test({ code: 'var foo = require("./")'}),
22+
test({ code: 'var foo = require("@scope/foo")'}),
23+
],
24+
invalid: [
25+
test({
26+
code: 'import _ from "babel!lodash"',
27+
errors: [
28+
{ message: `Unexpected '!' in 'babel!lodash'. ${message}` },
29+
],
30+
}),
31+
test({
32+
code: 'import find from "-babel-loader!lodash.find"',
33+
errors: [
34+
{ message: `Unexpected '!' in '-babel-loader!lodash.find'. ${message}` },
35+
],
36+
}),
37+
test({
38+
code: 'import foo from "style!css!./foo.css"',
39+
errors: [
40+
{ message: `Unexpected '!' in 'style!css!./foo.css'. ${message}` },
41+
],
42+
}),
43+
test({
44+
code: 'import data from "json!@scope/my-package/data.json"',
45+
errors: [
46+
{ message: `Unexpected '!' in 'json!@scope/my-package/data.json'. ${message}` },
47+
],
48+
}),
49+
test({
50+
code: 'var _ = require("babel!lodash")',
51+
errors: [
52+
{ message: `Unexpected '!' in 'babel!lodash'. ${message}` },
53+
],
54+
}),
55+
test({
56+
code: 'var find = require("-babel-loader!lodash.find")',
57+
errors: [
58+
{ message: `Unexpected '!' in '-babel-loader!lodash.find'. ${message}` },
59+
],
60+
}),
61+
test({
62+
code: 'var foo = require("style!css!./foo.css")',
63+
errors: [
64+
{ message: `Unexpected '!' in 'style!css!./foo.css'. ${message}` },
65+
],
66+
}),
67+
test({
68+
code: 'var data = require("json!@scope/my-package/data.json")',
69+
errors: [
70+
{ message: `Unexpected '!' in 'json!@scope/my-package/data.json'. ${message}` },
71+
],
72+
}),
73+
],
74+
})

0 commit comments

Comments
 (0)