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

[Feature] Transform paths of svg files #144

Open
axedre opened this issue Oct 14, 2021 · 1 comment
Open

[Feature] Transform paths of svg files #144

axedre opened this issue Oct 14, 2021 · 1 comment

Comments

@axedre
Copy link

axedre commented Oct 14, 2021

Hi, and thanks for your typescript-transform-paths plugin, it's really helpful in a monorepo context to resolve imports specified as import Something from '@namespace/some/path/Something' while compiling.
However, it would be even more helpful if it could resolve default imports of svg files, and I'll elaborate.
Currently in my source code I can import svgs like so:

// in `/home/axedre/repo/projects/sdk/src/Component/index.tsx`, for instance:
import Warning from '@namespace/some/path/icons/alert/warning.svg';
import SomeOtherComponent from '@namespace/some/other/path/SomeOtherComponent';
// ...

Now, while the second import gets correctly compiled to require('<relative_path_to>/SomeOtherComponent'), the former remains untouched (i.e. require('@namespace/...')) and if I publish the library to npm for use in a third-party application outside of the monorepo context it was developed in, it will of course complain that it cannot resolve '@namespace/...'.
Regarding my setup I have this in my tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@namespace/some/path/*": ["./actual/path/*"]
    },
    "plugins": [
      { "transform": "typescript-transform-paths" },
      { "transform": "typescript-transform-paths", "afterDeclarations": true }
    ]
  }
}

And this is the ouput of ttsc --traceResolution:

======== Resolving module '@namespace/some/path/icons/alert/warning.svg' from '/home/axedre/repo/projects/sdk/src/Component/index.tsx'. ========
Module resolution kind is not specified, using 'NodeJs'.
'baseUrl' option is set to '/home/axedre/repo/projects/sdk/src', using this value to resolve non-relative module name '@namespace/some/path/icons/alert/warning.svg'.
'paths' option is specified, looking for a pattern to match module name '@namespace/some/path/icons/alert/warning.svg'.
Module name '@namespace/some/path/icons/alert/warning.svg', matched pattern '@namespace/some/path/*'.
Trying substitution './actual/path/*', candidate module location: './actual/path/icons/alert/warning.svg'.
Loading module as file / folder, candidate module location '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg', target file type 'TypeScript'.

☝️ THAT is actually the correct path, so if the resolution stopped there and actually transformed '@namespace/some/path/icons/alert/warning.svg' to '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg' (aside from the fact it mistakenly says target file type 'TypeScript') I would be a very happy developer. But alas it thinks warning.svg is a typescript file or a folder name, so it proceeds on trying 👇

File '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg.ts' does not exist.
File '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg.tsx' does not exist.
File '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg.d.ts' does not exist.
Directory '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg' does not exist, skipping all lookups in it.
Loading module '@namespace/some/path/icons/alert/warning.svg' from 'node_modules' folder, target file type 'TypeScript'.
Directory '/home/axedre/repo/projects/sdk/src/Component/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
Directory '/home/axedre/repo/projects/sdk/src/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
Directory '/home/axedre/repo/projects/sdk/node_modules/@types' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
Directory '/home/axedre/repo/projects/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
Found 'package.json' at '/home/axedre/repo/node_modules/@namespace/some/path/package.json'.
'package.json' does not have a 'typesVersions' field.
File '/home/axedre/repo/node_modules/@namespace/some/path/icons/alert/warning.svg.ts' does not exist.
File '/home/axedre/repo/node_modules/@namespace/some/path/icons/alert/warning.svg.tsx' does not exist.
File '/home/axedre/repo/node_modules/@namespace/some/path/icons/alert/warning.svg.d.ts' does not exist.
'package.json' does not have a 'typings' field.
'package.json' does not have a 'types' field.
'package.json' does not have a 'main' field.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
Directory '/home/axedre/projects/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
Directory '/home/axedre/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
Directory '/home/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
Directory '/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'actual/path/icons/alert/warning.svg'
'baseUrl' option is set to '/home/axedre/repo/projects/sdk/src', using this value to resolve non-relative module name '@namespace/some/path/icons/alert/warning.svg'.
'paths' option is specified, looking for a pattern to match module name '@namespace/some/path/icons/alert/warning.svg'.
Module name '@namespace/some/path/icons/alert/warning.svg', matched pattern '@namespace/some/path/*'.
Trying substitution './actual/path/*', candidate module location: './actual/path/icons/alert/warning.svg'.
Loading module as file / folder, candidate module location '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg', target file type 'JavaScript'.
File '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg.js' does not exist.
File '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg.jsx' does not exist.
Directory '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg' does not exist, skipping all lookups in it.
Loading module '@namespace/some/path/icons/alert/warning.svg' from 'node_modules' folder, target file type 'JavaScript'.
Directory '/home/axedre/repo/projects/sdk/src/Component/node_modules' does not exist, skipping all lookups in it.
Directory '/home/axedre/repo/projects/sdk/src/node_modules' does not exist, skipping all lookups in it.
Directory '/home/axedre/repo/projects/node_modules' does not exist, skipping all lookups in it.
File '/home/axedre/repo/node_modules/@namespace/some/path/package.json' exists according to earlier cached lookups.
File '/home/axedre/repo/node_modules/@namespace/some/path/icons/alert/warning.svg.js' does not exist.
File '/home/axedre/repo/node_modules/@namespace/some/path/icons/alert/warning.svg.jsx' does not exist.
'package.json' does not have a 'main' field.
Directory '/home/axedre/projects/node_modules' does not exist, skipping all lookups in it.
Directory '/home/axedre/node_modules' does not exist, skipping all lookups in it.
Directory '/home/node_modules' does not exist, skipping all lookups in it.
Directory '/node_modules' does not exist, skipping all lookups in it.
'baseUrl' option is set to '/home/axedre/repo/projects/sdk/src', using this value to resolve non-relative module name '@namespace/some/path/icons/alert/warning.svg'.
'paths' option is specified, looking for a pattern to match module name '@namespace/some/path/icons/alert/warning.svg'.
Module name '@namespace/some/path/icons/alert/warning.svg', matched pattern '@namespace/some/path/*'.
Trying substitution './actual/path/*', candidate module location: './actual/path/icons/alert/warning.svg'.
Loading module as file / folder, candidate module location '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg', target file type 'Json'.
Directory '/home/axedre/repo/projects/sdk/src/actual/path/icons/alert/warning.svg' does not exist, skipping all lookups in it.
Loading module '@namespace/some/path/icons/alert/warning.svg' from 'node_modules' folder, target file type 'Json'.
Directory '/home/axedre/repo/projects/sdk/src/Component/node_modules' does not exist, skipping all lookups in it.
Directory '/home/axedre/repo/projects/sdk/src/node_modules' does not exist, skipping all lookups in it.
Directory '/home/axedre/repo/projects/node_modules' does not exist, skipping all lookups in it.
File '/home/axedre/repo/node_modules/@namespace/some/path/package.json' exists according to earlier cached lookups.
'package.json' does not have a 'main' field.
Directory '/home/axedre/projects/node_modules' does not exist, skipping all lookups in it.
Directory '/home/axedre/node_modules' does not exist, skipping all lookups in it.
Directory '/home/node_modules' does not exist, skipping all lookups in it.
Directory '/node_modules' does not exist, skipping all lookups in it.
======== Module name '@namespace/some/path/icons/alert/warning.svg' was not resolved. ========

😞

Before you ask, I've already tried all the widely-suggested approach of creating a custom.d.ts file with roughly this content:

declare module '*.svg' {
  const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
  export default content;
}

and include it both in tsconfig.json's "include" (also in "compilerOptions.typeRoots") and in package.json's types/typings field, but to no avail.
I think this might call for a specific typescript-transform-svg-paths plugin, but open to any suggestion.
Cheers!

@nonara
Copy link
Collaborator

nonara commented Oct 14, 2021

This is an interesting one. Thank you for the thorough explanation and resolution log detail. I've re-engineered quite a bit for the upcoming major release. We still rely on the compiler's resolution API, however, we're also getting a lot more information via other means, to support the new middleware custom resolver option.

Part of that is to get the full range of path match possibilities, which means we might be able to do a post-resolution fail check for files with non-resolvable extensions.

I'll look into this!

In the mean time, you can use a @transform-path comment above those lines to explicitly transform until the feature is added.

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

No branches or pull requests

2 participants