Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

importing aliased ts files using their corresponding js extesions fails #7918

Closed
7 tasks done
wight554 opened this issue Apr 26, 2022 · 4 comments
Closed
7 tasks done

Comments

@wight554
Copy link

Describe the bug

Support for .ts to .js alias was added in #5510 and #7005.
But it doesn't really work when using with typescript path alias:

// from vite.config.ts
  resolve: {
    alias: [
      {
        find: '@src',
        replacement: './src',
      },
    ],
  },
// from tsconfig.json

"paths": {
  "@src/*": ["./src/*"],
  "@server/*": ["./server/*"],
  "@test/*": ["./test/*"]
},

Currently I can fix it by:

resolve: {
    alias: [{ find: /^(@.*\/.*)\.js$/, replacement: '$1.ts' }]
}

Reproduction

wight554/blog-template#50

System Info

System:
    OS: macOS 12.3.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 303.88 MB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node
    Yarn: 3.1.1 - ~/.nvm/versions/node/v16.14.2/bin/yarn
    npm: 8.5.0 - ~/.nvm/versions/node/v16.14.2/bin/npm
    Watchman: 2022.03.21.00 - /usr/local/bin/watchman
  Browsers:
    Chrome: 100.0.4896.127
    Edge: 100.0.1185.50
    Firefox: 99.0.1
    Safari: 15.4
  npmPackages:
    vite: ^2.9.5 => 2.9.5

Used Package Manager

yarn

Logs

vite:config TS + native esm config loaded in 295.70ms URL {
  href: 'file:///Users/.../vite/blog-template/vite.config.ts',
  origin: 'null',
  protocol: 'file:',
  username: '',
  password: '',
  host: '',
  hostname: '',
  port: '',
  pathname: '/Users/.../vite/blog-template/vite.config.ts',
  search: '',
  searchParams: URLSearchParams {},
  hash: ''
} +0ms
  vite:config using resolved config: {
  vite:config   plugins: [
  vite:config     'vite:build-metadata',
  vite:config     'alias',
  vite:config     'vite:preact-jsx',
  vite:config     'preact:devtools',
  vite:config     'vite:tsconfig-paths',
  vite:config     'vite:modulepreload-polyfill',
  vite:config     'vite:resolve',
  vite:config     'vite:html-inline-proxy',
  vite:config     'vite:css',
  vite:config     'vite:esbuild',
  vite:config     'vite:json',
  vite:config     'vite:wasm',
  vite:config     'vite:worker',
  vite:config     'vite:asset',
  vite:config     'preact:config',
  vite:config     'prefresh',
  vite:config     'vite-plugin-checker',
  vite:config     'vite:define',
  vite:config     'vite:css-post',
  vite:config     'vite:build-html',
  vite:config     'vite:worker-import-meta-url',
  vite:config     'vite:watch-package-data',
  vite:config     'commonjs',
  vite:config     'vite:data-uri',
  vite:config     'rollup-plugin-dynamic-import-variables',
  vite:config     'vite:asset-import-meta-url',
  vite:config     'vite:build-import-analysis',
  vite:config     'vite:esbuild-transpile',
  vite:config     'vite:terser',
  vite:config     'vite:reporter',
  vite:config     'vite:load-fallback'
  vite:config   ],
  vite:config   build: {
  vite:config     target: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
  vite:config     polyfillModulePreload: true,
  vite:config     outDir: '/Users/.../vite/blog-template/dist/public',
  vite:config     assetsDir: 'assets',
  vite:config     assetsInlineLimit: 4096,
  vite:config     cssCodeSplit: true,
  vite:config     cssTarget: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
  vite:config     sourcemap: false,
  vite:config     rollupOptions: {},
  vite:config     minify: 'esbuild',
  vite:config     terserOptions: {},
  vite:config     write: true,
  vite:config     emptyOutDir: true,
  vite:config     manifest: false,
  vite:config     lib: false,
  vite:config     ssr: false,
  vite:config     ssrManifest: false,
  vite:config     reportCompressedSize: true,
  vite:config     chunkSizeWarningLimit: 500,
  vite:config     watch: null,
  vite:config     commonjsOptions: { include: [Array], extensions: [Array] },
  vite:config     dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] }
  vite:config   },
  vite:config   test: {
  vite:config     environment: 'jsdom',
  vite:config     globals: true,
  vite:config     coverage: { exclude: [Array] },
  vite:config     setupFiles: [ 'test/testSetup.ts', 'test/recoilTestSetup.ts' ]
  vite:config   },
  vite:config   resolve: {
  vite:config     dedupe: undefined,
  vite:config     alias: [ [Object], [Object], [Object], [Object], [Object], [Object] ]
  vite:config   },
  vite:config   optimizeDeps: {
  vite:config     include: [ 'preact/jsx-runtime' ],
  vite:config     esbuildOptions: { keepNames: undefined, preserveSymlinks: undefined }
  vite:config   },
  vite:config   configFile: '/Users/.../vite/blog-template/vite.config.ts',
  vite:config   configFileDependencies: [
  vite:config     '/Users/.../vite/blog-template/vite.config.ts'
  vite:config   ],
  vite:config   inlineConfig: {
  vite:config     root: undefined,
  vite:config     base: undefined,
  vite:config     mode: undefined,
  vite:config     configFile: undefined,
  vite:config     logLevel: undefined,
  vite:config     clearScreen: undefined,
  vite:config     build: {}
  vite:config   },
  vite:config   root: '/Users/.../vite/blog-template',
  vite:config   base: '/',
  vite:config   publicDir: '/Users/.../vite/blog-template/public',
  vite:config   cacheDir: '/Users/.../vite/blog-template/node_modules/.vite',
  vite:config   command: 'build',
  vite:config   mode: 'production',
  vite:config   isWorker: false,
  vite:config   isProduction: true,
  vite:config   server: {
  vite:config     preTransformRequests: true,
  vite:config     fs: { strict: true, allow: [Array], deny: [Array] }
  vite:config   },
  vite:config   preview: {
  vite:config     port: undefined,
  vite:config     strictPort: undefined,
  vite:config     host: undefined,
  vite:config     https: undefined,
  vite:config     open: undefined,
  vite:config     proxy: undefined,
  vite:config     cors: undefined,
  vite:config     headers: undefined
  vite:config   },
  vite:config   env: { BASE_URL: '/', MODE: 'production', DEV: false, PROD: true },
  vite:config   assetsInclude: [Function: assetsInclude],
  vite:config   logger: {
  vite:config     hasWarned: false,
  vite:config     info: [Function: info],
  vite:config     warn: [Function: warn],
  vite:config     warnOnce: [Function: warnOnce],
  vite:config     error: [Function: error],
  vite:config     clearScreen: [Function: clearScreen],
  vite:config     hasErrorLogged: [Function: hasErrorLogged]
  vite:config   },
  vite:config   packageCache: Map(0) { set: [Function (anonymous)] },
  vite:config   createResolver: [Function: createResolver],
  vite:config   worker: {
  vite:config     format: 'iife',
  vite:config     plugins: [
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object]
  vite:config     ],
  vite:config     rollupOptions: {}
  vite:config   }
  vite:config } +257ms
vite v2.9.5 building for production...
✓ 3 modules transformed.
[vite:load-fallback] Could not load ./src/components/App/index.js (imported by src/main.ts): ENOENT: no such file or directory, open './src/components/App/index.js'
error during build:
Error: Could not load ./src/components/App/index.js (imported by src/main.ts): ENOENT: no such file or directory, open './src/components/App/index.js'
[!] Error: unfinished hook action(s) on exit:
(vite:tsconfig-paths) resolveId "preact/debug" "/Users/.../vite/blog-template/src/main.ts"
(vite:tsconfig-paths) resolveId "@mui/material" "/Users/.../vite/blog-template/src/main.ts"
(vite:tsconfig-paths) resolveId "htm/preact" "/Users/.../vite/blog-template/src/main.ts"
(vite:tsconfig-paths) resolveId "preact" "/Users/.../vite/blog-template/src/main.ts"
(vite:tsconfig-paths) resolveId "react-router-dom" "/Users/.../vite/blog-template/src/main.ts"
(vite:tsconfig-paths) resolveId "recoil" "/Users/.../vite/blog-template/src/main.ts"
(vite:load-fallback) load "./src/index.css"

Validations

@wight554
Copy link
Author

Was reported here as well: #6671 (comment)

@sapphi-red
Copy link
Member

It worked if I change the config like below.

/// <reference types="vitest" />

import path from 'path';

import preact from '@preact/preset-vite';
import { defineConfig } from 'vite';
import checker from 'vite-plugin-checker';
import typescript from 'vite-plugin-typescript';
import tsconfigPaths from 'vite-tsconfig-paths';
import { configDefaults } from 'vitest/config';

const isTest = process.env.NODE_ENV === 'test';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    preact({
      include: '{test/,}src/**/*.{ts,tsx}',
    }),
-    !isTest && tsconfigPaths(),
    !isTest &&
      checker({
        typescript: { tsconfigPath: 'src/tsconfig.json' },
        eslint: {
          lintCommand: 'eslint "./src/**/*.{ts,tsx}"',
        },
      }),
    isTest && typescript(),
  ],
  build: {
    outDir: path.join(__dirname, 'dist/public'),
    emptyOutDir: true,
  },
  test: {
    environment: 'jsdom',
    globals: true,
    coverage: {
      exclude: [...configDefaults.coverage.exclude, '**/schemas/**'],
    },
    setupFiles: ['test/testSetup.ts', 'test/recoilTestSetup.ts'],
  },
  resolve: {
-    alias: !isTest && [{ find: /^(@.*\/.*)\.js$/, replacement: '$1.ts' }],
+    alias: !isTest && [
+      {
+        find: '@src',
+        replacement: path.resolve(__dirname, 'src'),
+      },
+    ],
  },
});

It seems it's a bug in vite-tsconfig-paths since it works without it.
Also I don't think it will work if @src is handled by both resolve.alias and vite-tsconfig-paths.

Closing as it is not a bug in Vite. Please create a minimal reproduction if you think it is a bug in vite.

@wight554
Copy link
Author

wight554 commented May 6, 2022

It worked if I change the config like below.

/// <reference types="vitest" />

import path from 'path';

import preact from '@preact/preset-vite';
import { defineConfig } from 'vite';
import checker from 'vite-plugin-checker';
import typescript from 'vite-plugin-typescript';
import tsconfigPaths from 'vite-tsconfig-paths';
import { configDefaults } from 'vitest/config';

const isTest = process.env.NODE_ENV === 'test';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    preact({
      include: '{test/,}src/**/*.{ts,tsx}',
    }),
-    !isTest && tsconfigPaths(),
    !isTest &&
      checker({
        typescript: { tsconfigPath: 'src/tsconfig.json' },
        eslint: {
          lintCommand: 'eslint "./src/**/*.{ts,tsx}"',
        },
      }),
    isTest && typescript(),
  ],
  build: {
    outDir: path.join(__dirname, 'dist/public'),
    emptyOutDir: true,
  },
  test: {
    environment: 'jsdom',
    globals: true,
    coverage: {
      exclude: [...configDefaults.coverage.exclude, '**/schemas/**'],
    },
    setupFiles: ['test/testSetup.ts', 'test/recoilTestSetup.ts'],
  },
  resolve: {
-    alias: !isTest && [{ find: /^(@.*\/.*)\.js$/, replacement: '$1.ts' }],
+    alias: !isTest && [
+      {
+        find: '@src',
+        replacement: path.resolve(__dirname, 'src'),
+      },
+    ],
  },
});

It seems it's a bug in vite-tsconfig-paths since it works without it. Also I don't think it will work if @src is handled by both resolve.alias and vite-tsconfig-paths.

Closing as it is not a bug in Vite. Please create a minimal reproduction if you think it is a bug in vite.

please check config example from bug description, it's broken when used with relative paths, eg if i change your example this way:

--- a/vite.config.ts
+++ b/vite.config.ts
@@ -43,7 +43,7 @@ export default defineConfig({
     alias: !isTest && [
       {
         find: '@src',
-        replacement: path.resolve(__dirname, 'src'),
+        replacement: './src',
       },
     ],
   },

according to rollup alias plugin I can use relative paths:
image

@sapphi-red
Copy link
Member

@rollup/plugin-alias simply replaces id.
https://github.com/rollup/plugins/blob/556837f0b7e7323f237370e36394569abc2b1ef9/packages/alias/src/index.ts#L88

So if there is import '@src/foo' in /path/deep/bar.ts. It becomes import './src/foo' which means import '/path/deep/src/foo'.
Relative path is not relative to config file. It is relative to the importer file.

The error is a bit confusing though (related: #5813).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants