import-js / import-js/eslint-plugin-import
Webpack aliasing JSON module throws `import/extensions`
- Dominant language
- JavaScript
- Stars
- 5.9k
- Forks
- 1.5k
- PR merge metrics
- No merged PRs in 30d
Description
When aliasing a module to a JSON file in a webpack config, `import/extensions` get triggered. Is it possible to get around this error with some additonal config (I played around with it but no luck)?
First ran into this with the [`eslint-config-airbnb-base`](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb-base) but here is a slimmed down example.
```
error [import/extensions]: Missing file extension for "some-map"
/foo.js at 2:21
```
`foo.js`
```js
import someMap from 'some-map';
console.log(someMap);
```
`webpack.config.js`
```js
module.exports = {
resolve: {
alias: {
'some-map': '/some-map.json'
}
}
};
```
`.eslintrc`
```json
{
"env": {
"es6": true
},
"parserOptions": {
"sourceType": "module",
},
"plugins": [
"import"
],
"settings": {
"import/resolver": {
"webpack": {
"config": "/webpack.config.js"
}
}
},
"rules": {
"import/extensions": ["error", "always", {
"js": "never"
}]
}
}
```
---
Standalone example
```js
const proxyquire = require('proxyquire');
const MemoryFS = require('memory-fs');
const memoryFs = new MemoryFS();
// Doesn't work
memoryFs['@global'] = true;
// Probably need this but running into https://github.com/thlorenz/proxyquire/issues/93
//memoryFs['@runtimeGlobal'] = true;
const stubs = {
fs: memoryFs
};
const eslint = proxyquire('eslint', stubs);
const CLIEngine = eslint.CLIEngine;
const EslintConfig = proxyquire('eslint/lib/config',stubs);
const importPlugin = proxyquire('eslint-plugin-import', stubs);
const importResolverWebpackPlugin = proxyquire('eslint-import-resolver-webpack', stubs);
// Setup our directory
// -----------------------------
memoryFs.writeFileSync('/some-map.json', `{ "foo": "bar" }`, 'utf-8');
memoryFs.writeFileSync('/webpack.config.js', `
module.exports = {
resolve: {
alias: {
'some-map': '/some-map.json'
}
}
};
`, 'utf-8');
//console.log(memoryFs.readdirSync('/'));
const troubleCode = `
import someMap from 'some-map';
console.log(someMap);
`;
const troubleConfig = {
"env": {
"es6": true
},
"parserOptions": {
"sourceType": "module",
},
"plugins": [
"import"
],
"settings": {
"import/resolver": {
"webpack": {
"config": "/webpack.config.js"
}
}
},
rules: {
'import/extensions': ['error', 'always', {
js: 'never',
}]
}
};
const cli = new CLIEngine(troubleConfig);
cli.addPlugin('eslint-plugin-import', importPlugin);
cli.addPlugin('eslint-import-resolver-webpack', importResolverWebpackPlugin);
const report = cli.executeOnText(troubleCode, '/foo.js');
console.log(report);
console.log(`Errors (${report.errorCount}), Warnings (${report.warningCount})`);
report.results.forEach((result) => {
result.messages.forEach((message) => {
let severityString = 'info';
if(message.severity === 1) {
severityString = 'warning';
}
else if(message.severity === 2) {
severityString = 'error';
}
console.log(`${severityString} [${message.ruleId}]: ${message.message}\n\t${result.filePath} at ${message.line}:${message.column}`)
});
})
```
---
https://gitlab.com/gitlab-org/gitlab-ce/issues/29160
Contributor guide
Research direction
Start with the standalone reproduction using foo.js, webpack.config.js, .eslintrc, and the in-memory JSON file, then run it to confirm how the webpack resolver handles the aliased module. Trace the resolver and import/extensions interaction to determine whether the JSON extension is recognized; done means the reproduced alias no longer reports a missing extension without breaking the shown rule configuration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100