{"_id":"eslint-plugin-esm-import","_rev":"2-832edeb879a11cf256f8f83b8eb6ea3d","name":"eslint-plugin-esm-import","dist-tags":{"latest":"1.0.1"},"versions":{"0.0.1":{"name":"eslint-plugin-esm-import","version":"0.0.1","keywords":["eslint","eslintplugin","eslint-plugin","esm"],"author":{"name":"Marko Bonaci","email":"support@sematext.com"},"license":"ISC","_id":"eslint-plugin-esm-import@0.0.1","maintainers":[{"name":"sematext","email":"packages@sematext.com"}],"homepage":"https://github.com/sematext/eslint-plugin-esm-import#readme","bugs":{"url":"https://github.com/sematext/eslint-plugin-esm-import/issues"},"dist":{"shasum":"c6e1490da5b6fb8026db7889f13bab00872477a1","tarball":"https://registry.npmjs.org/eslint-plugin-esm-import/-/eslint-plugin-esm-import-0.0.1.tgz","fileCount":4,"integrity":"sha512-xTDN8u1WTWJ8J/AWS2BHli9lI64j+xMdM90ceNiv+QCVXlyLj0fHH0KcN1Can/QYEU41fJlQEmXh64KTkWt0HQ==","signatures":[{"sig":"MEUCIF2NkGVJpXBuQ+o5My99H/e+EPJ6TcELDJZy1CQ2NFpIAiEAxoabAog8QD7TCIf5jagqXJteygfc7MFFkwmlxLd/0ZQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":8862},"main":"index.js","gitHead":"66852c77254801ec971f695d6eb3e5181d4ab9f0","scripts":{"fix":"cd test && npm link .. && npm i && ./node_modules/.bin/eslint . --fix","lint":"cd test && npm link .. && npm i && ./node_modules/.bin/eslint ."},"_npmUser":{"name":"sematext","email":"packages@sematext.com"},"repository":{"url":"git+https://github.com/sematext/eslint-plugin-esm-import.git","type":"git"},"_npmVersion":"10.5.1","description":"ESLint plugin which enforces explicit .js extensions in local imports while leveraging import resolvers.","directories":{},"_nodeVersion":"18.20.0","_hasShrinkwrap":false,"peerDependencies":{"eslint":"^8","eslint-module-utils":"^2","eslint-plugin-import":"^2"},"_npmOperationalInternal":{"tmp":"tmp/eslint-plugin-esm-import_0.0.1_1715275721108_0.8092343415403507","host":"s3://npm-registry-packages"}},"1.0.0":{"name":"eslint-plugin-esm-import","version":"1.0.0","keywords":["eslint","eslintplugin","eslint-plugin","esm"],"author":{"name":"Marko Bonaci","email":"support@sematext.com"},"license":"ISC","_id":"eslint-plugin-esm-import@1.0.0","maintainers":[{"name":"sematext","email":"packages@sematext.com"}],"homepage":"https://github.com/sematext/eslint-plugin-esm-import#readme","bugs":{"url":"https://github.com/sematext/eslint-plugin-esm-import/issues"},"dist":{"shasum":"d2b5cf0a554a80a088c568f510688ddda1b798f5","tarball":"https://registry.npmjs.org/eslint-plugin-esm-import/-/eslint-plugin-esm-import-1.0.0.tgz","fileCount":4,"integrity":"sha512-1lAn2EQJwKGvDvYa5eAHlXTaQjtv4Pj8iVozFkA1l2mX14UtsXmyVO6IDZvHDS4+rjVqAzBS90BCGAaylk60FQ==","signatures":[{"sig":"MEQCIA1c2cB0d+SeiyVeYtGavdPmQIFapa5QULetwEHWi5YOAiAkD3GhNoATyZTmqQ8IVEOH230dkaVohJ1JwGqnX4b0WQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9710},"main":"index.js","type":"commonjs","gitHead":"d276a35ac2ddf90f08f69e2db35f9fd6f9116975","scripts":{"fix":"npm i && cd test && npm link .. && npm i && ./node_modules/.bin/eslint . --fix || true","lint":"npm i && cd test && npm link .. && npm i && ./node_modules/.bin/eslint . || true"},"_npmUser":{"name":"sematext","email":"packages@sematext.com"},"repository":{"url":"git+https://github.com/sematext/eslint-plugin-esm-import.git","type":"git"},"_npmVersion":"10.9.2","description":"ESLint plugin which enforces explicit .js extensions in local imports while leveraging import resolvers.","directories":{},"_nodeVersion":"22.13.1","_hasShrinkwrap":false,"devDependencies":{"eslint":"^9","eslint-module-utils":"^2","eslint-plugin-import":"^2"},"peerDependencies":{"eslint":"^9","eslint-module-utils":"^2","eslint-plugin-import":"^2"},"_npmOperationalInternal":{"tmp":"tmp/eslint-plugin-esm-import_1.0.0_1739639795432_0.10165442158766691","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"eslint-plugin-esm-import","version":"1.0.1","description":"ESLint plugin which enforces explicit .js extensions in local imports while leveraging import resolvers.","main":"index.js","type":"commonjs","scripts":{"lint":"npm i && cd test && npm link .. && npm i && ./node_modules/.bin/eslint . || true","fix":"npm i && cd test && npm link .. && npm i && ./node_modules/.bin/eslint . --fix || true"},"repository":{"type":"git","url":"git+https://github.com/sematext/eslint-plugin-esm-import.git"},"keywords":["eslint","eslintplugin","eslint-plugin","esm"],"author":{"name":"Marko Bonaci","email":"support@sematext.com"},"license":"ISC","bugs":{"url":"https://github.com/sematext/eslint-plugin-esm-import/issues"},"homepage":"https://github.com/sematext/eslint-plugin-esm-import#readme","peerDependencies":{"eslint":"^9","eslint-plugin-import":"^2.31.0","eslint-module-utils":"^2.12.0"},"devDependencies":{"eslint":"^9","eslint-plugin-import":"^2.31.0","eslint-module-utils":"^2.12.0"},"_id":"eslint-plugin-esm-import@1.0.1","gitHead":"775665cd5947eccad025b91655e8d4909ab7249c","_nodeVersion":"22.13.1","_npmVersion":"10.9.2","dist":{"integrity":"sha512-swGk1Y3D/k7W4Bb/aitxXQnj6gru/dq7DTJA7zon/4t/nhwZmbWi5p54btKfEPqrrl6CKfJocc5GjUidv1Pdzg==","shasum":"e84c4414c8cd6a954ccafdece89bd5484cd87d83","tarball":"https://registry.npmjs.org/eslint-plugin-esm-import/-/eslint-plugin-esm-import-1.0.1.tgz","fileCount":4,"unpackedSize":10276,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIECO80JWIBT5Cx55Ag0L7q1Dsry0B4KAkfXkpoz/Nbb/AiALiBpcXjXPgA7VgZJ7fZyhA7I3Z3sWCMKEE+lkCNBndw=="}]},"_npmUser":{"name":"sematext","email":"packages@sematext.com"},"directories":{},"maintainers":[{"name":"sematext","email":"packages@sematext.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/eslint-plugin-esm-import_1.0.1_1739680753849_0.24703434070719466"},"_hasShrinkwrap":false}},"time":{"created":"2024-05-09T17:28:41.107Z","modified":"2025-02-16T04:39:14.196Z","0.0.1":"2024-05-09T17:28:41.253Z","1.0.0":"2025-02-15T17:16:35.712Z","1.0.1":"2025-02-16T04:39:14.022Z"},"bugs":{"url":"https://github.com/sematext/eslint-plugin-esm-import/issues"},"author":{"name":"Marko Bonaci","email":"support@sematext.com"},"license":"ISC","homepage":"https://github.com/sematext/eslint-plugin-esm-import#readme","keywords":["eslint","eslintplugin","eslint-plugin","esm"],"repository":{"type":"git","url":"git+https://github.com/sematext/eslint-plugin-esm-import.git"},"description":"ESLint plugin which enforces explicit .js extensions in local imports while leveraging import resolvers.","maintainers":[{"name":"sematext","email":"packages@sematext.com"}],"readme":"# eslint-plugin-esm-import\n\nAn ESLint plugin which enforces explicit `.js` extensions in local imports.\n\nThe purpose of this plugin is to\n  - help with the initial migration of a common.js project to ESM, by leveraging the `eslint --fix` feature:\n    - `import x from './x-file'` -> `import x from './x-file.js'`\n    - `import y from './y-folder'` -> `import y from './y-folder/index.js'`\n  - enforce explicit `.js` extensions on all relevant imports during development\n\n__NOTE__ This plugin will be usefult to you only if you've been writing ESM-style imports in an otherwise common.js project, using babel and/or tsc to transpile it, so you are now stuck with a large number of file imports which don't have extensions and folder imports which don't have index files and thus do not conform to the ESM spec.   \nThis was a fairly standard practice ever since ES6 (ES2015) came out.\n\n## Key features\n  - leverages existing import resolvers from the ESLint configuration (e.g. `node`, `webpack`, `typescript`)\n  - honors the convention of importing `.ts` and `.tsx` files as `.js`\n  - configurable list of ignored extensions (see [Configure](#configure))\n  - configurable list of _index files_  (see [Configure](#configure))\n\n\nInspired by [eslint-plugin-require-extensions](https://github.com/solana-labs/eslint-plugin-require-extensions), which only recognizes imports which start with `./`, meaning it [doesn't know](https://github.com/solana-labs/eslint-plugin-require-extensions/issues/10) how to handle imports which use resolver aliases (`resolve.alias` from _Webpack_ conf or `compilerOptions.paths` from `tsconfig` and so on), which are usually the vast majority of imports in complex projects.\n\n## Install\n\n| ESLint | This package | eslint config example |\n|-|-|-|\n| `v9`   | `v1.0.1`  | [eslint.config.js](https://github.com/sematext/eslint-plugin-esm-import/blob/master/test/eslint.config.js) |\n| `v8`  | `v0.0.1`  | [.eslintrc](https://github.com/sematext/eslint-plugin-esm-import/blob/d276a35ac2ddf90f08f69e2db35f9fd6f9116975/test/.eslintrc) |\n| `< v8`  | unsupported, but try `v0.0.1`  |  |\n\n\n1. Install\n```shell\nnpm install --save-dev eslint-plugin-esm-import\n```\n\n2. Add these snippets to your `eslint.config.js` (see the table above for earlier ESLint versions)\n```js\nimport esmImport from 'eslint-plugin-esm-import';\nexport default [\n  {\n    plugins: {\n      'esm-import': esmImport\n    },\n    rules: {\n      ...esmImport.configs.recommended.rules\n    }\n  }\n]\n```\nRestart ESLint server to force conf reload in your IDE (in VSCode: `Help > Show all commands > Restart ESLint server`).\n\n3. Code\n```js\n// source.js\nimport RelativeFile from '../../shared/components/RelativeFile';\nimport AliasedFile from 'Components/AliasedFile';   // provided there's a Components alias\nimport AliasedFolder from 'Modules/aliased-folder'; // provided there's a Modules alias\n```\n\n4. Lint\n\n```shell\n> ./node_modules/.bin/eslint ./src/source.js\n\nsource.js\n  1:1  error  Local imports and exports must end with .js   esm-import/extensions\n  1:1  error  Local imports and exports must end with .js   esm-import/extensions\n  1:1  error  Importing a directory requires /index.js      esm-import/extensions\n\n✖ 3 problems (3 errors, 0 warnings)\n  3 errors and 0 warnings potentially fixable with the `--fix` option.\n```\nThe purpose of the GH action is to run eslint in order to show the plugin in action:  \n![GH action lint run](gh-action.png)\n\n5. Fix\n\n```shell\n> ./node_modules/.bin/eslint --fix ./src/source.js\n```\n```js\n// source.js\nimport RelativeFile from '../../components/RelativeFile.js';\nimport AliasedFile from 'components/AliasedFile.js';\nimport AliasedFolder from 'Modules/aliased-folder/index.js';\n```\n\n## Configure\nThe plugin allows you to configure:\n - the list of ignored extensions, so this plugin can ignore imports which end with any of those extensions (defaults to `[\".js\", \".cjs\", \".json\", \".css\", \".scss\"]`)\n - the list of _index files_, in order to recognize that a folder got resolved to an index file and thus knows that the fix is to append `/index.js`, not `.js` (defaults to `[\"index.js\", \"index.jsx\", \"index.ts\", \"index.tsx\"]`)\n\n\n```js\n// eslint.config.js example settings\nsettings: {\n  'esm-import': {\n    ignore: ['.js', '.cjs', '.json', '.css', '.scss', '.svg', '.png', '.gif', '.mp3'],\n    index: ['index.js', 'index.jsx', 'index.ts', 'index.tsx']\n  }\n}\n```\n\n### TypeScript\nMake sure you define extension aliases in your Webpack configuration, otherwise eslint won't be able to resolve imports of TS files from JS as `.js`:\n```js\n  resolve: {\n    extensionAlias: {\n      '.js': [\n        '.ts',\n        '.tsx',\n        '.d.ts',\n      ],\n    },\n  },\n```\n\n### Background info\n\n`eslint-plugin-import` [has no plans](https://github.com/import-js/eslint-plugin-import/issues/2111) to treat `ts` imports as `js`.  \n`TypeScript` has no plans to [transform](https://github.com/microsoft/TypeScript/issues/16577) nor [enforce](https://github.com/microsoft/TypeScript/issues/42813) extensions.\n\n\n### Changelog\n\n[CHANGELOG.md](./CHANGELOG.md)\n\n### Cutting a new version\n\nAfter changes are made:\n1. Test whether the plugin still does its job by running `npm run lint` and `npm run fix`.\n1. Bump the project's version in the [package.json](./package.json)\n1. Populate the [CHANGELOG.md](./CHANGELOG.md)\n1. Run `npm publish --auth-type legacy`\n1. When asked to log in use `sematext` npm account (you'll need 2FA OTP).","readmeFilename":"README.md"}