crxjs / chrome-extension-tools

Bundling Chrome Extensions can be pretty complex. It doesn't have to be.
https://crxjs.dev/vite-plugin
2.71k stars 181 forks source link

eslint-plugin-import unable to resolve path to `@crxjs/vite-plugin` #684

Open karlhorky opened 1 year ago

karlhorky commented 1 year ago

Build tool

Vite

Where do you see the problem?

Describe the bug

The eslint-plugin-import rule import/no-unresolved cannot resolve the @crxjs/vite-plugin import within manifest.config.ts mentioned in the docs:

$ pnpm eslint manifest.config.ts

/home/projects/node-vqr1sb/manifest.config.ts
  1:32  error  Unable to resolve path to module '@crxjs/vite-plugin'  import/no-unresolved

✖ 1 problem (1 error, 0 warnings)

Screenshot 2023-04-02 at 19 11 23

Screenshot 2023-04-02 at 19 11 10

Reproduction

StackBlitz Demo (run pnpm eslint manifest.config.ts): https://stackblitz.com/edit/node-vqr1sb?file=manifest.config.ts&file=.eslintrc.cjs

Reproduce with:

  1. Scaffold the project
mkdir repro && cd repro
pnpm create vite . --template react-ts
pnpm add --save-dev @crxjs/vite-plugin@beta
pnpm add --save-dev eslint eslint-plugin-import @typescript-eslint/parser eslint-import-resolver-typescript
  1. Edit tsconfig.node.json: add "manifest.config.ts" and ".eslintrc.cjs" to the "include" array

  2. Then add two files:

manifest.config.ts, based off the docs:

import { defineManifest } from '@crxjs/vite-plugin';

const version = '0.1.0-beta6';

// Convert from Semver (example: 0.1.0-beta6)
const [major, minor, patch, label = '0'] = version
  // can only contain digits, dots, or dash
  .replace(/[^\d.-]+/g, '')
  // split into version parts
  .split(/[.-]/);

export default defineManifest(async (env) => ({
  manifest_version: 3,
  name:
    env.mode === 'staging'
      ? '[INTERNAL] CRXJS Power Tools'
      : 'CRXJS Power Tools',
  // up to four numbers separated by dots
  version: `${major}.${minor}.${patch}.${label}`,
  // semver is OK in "version_name"
  version_name: version,
}));

.eslintrc.cjs

const config = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: ['./tsconfig.json', './tsconfig.node.json'],
  },
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': ['.ts', '.tsx'],
    },
    'import/resolver': {
      typescript: {
        project: ['./tsconfig.json', './tsconfig.node.json'],
      },
    },
  },
  plugins: ['import'],
  rules: {
    'import/no-unresolved': 'error',
  },
};

module.exports = config;
  1. Finally, run the following in the terminal:
pnpm eslint manifest.config.ts

Logs

No response

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 7.17.0 - /usr/local/bin/npm
  npmPackages:
    @crxjs/vite-plugin: 2.0.0-beta.15 => 2.0.0-beta.15 
    vite: ^4.2.0 => 4.2.1

Severity

annoyance

karlhorky commented 1 year ago

It may be related to the broken types published with @crxjs/vite-plugin, which you can see on Are the types wrong?:

Imports of "@crxjs/vite-plugin" under all modern module resolution settings resolved through a conditional package.json export, but only after failing to resolve through an earlier condition. This behavior is a TypeScript bug and should not be relied upon.

Imports of "@crxjs/vite-plugin" under the node16 module resolution setting when the importing module is ESM (its extension is .mts or .mjs, or it has a .ts or .js extension and is in scope of a package.json that contains "type": "module") resolved to CJS types, but ESM implementations.

Screenshot 2023-04-02 at 19 25 00

karlhorky commented 1 year ago

Workaround

For now, users can work around this problem by:

  1. Importing directly from the dist/index.mjs file:
-import { defineManifest } from '@crxjs/vite-plugin';
+import { defineManifest } from '@crxjs/vite-plugin/dist/index.mjs';
  1. Patching their node_modules using pnpm patch or patch-package: rename node_modules/@crxjs/vite-plugin/dist/index.d.ts to node_modules/@crxjs/vite-plugin/dist/index.d.mts (note the m in the .mts extension)