Skip to content

[Feature] Transform paths of svg files #144

@axedre

Description

@axedre

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions