VS Code: “Cannot find module” from root path The Next CEO of Stack OverflowHow do I hide certain files from the sidebar in Visual Studio Code?Gulp sourcemaps with TypeScript and BabelImporting lodash into angular2 + typescript applicationTypescript compiler cannot find locally installed npm moduleAngular 2 TypeScript ErrorsPaths property in tsconfig doesn't workWebpack + React + TypeScript: Module not found … in … node_modules/react/Typescript does not resolve definition file for npm packageVSCode typescript importing json file highlighting issueVisual Studio Code not finding any TS or node packages

What do "high sea" and "carry" mean in this sentence?

WOW air has ceased operation, can I get my tickets refunded?

If I blow insulation everywhere in my attic except the door trap, will heat escape through it?

Unreliable Magic - Is it worth it?

I believe this to be a fraud - hired, then asked to cash check and send cash as Bitcoin

Why Were Madagascar and New Zealand Discovered So Late?

Science fiction novels about a solar system spanning civilisation where people change their bodies at will

Can the Reverse Gravity spell affect the Meteor Swarm spell?

Would this house-rule that treats advantage as a +1 to the roll instead (and disadvantage as -1) and allows them to stack be balanced?

What makes a siege story/plot interesting?

Is a stroke of luck acceptable after a series of unfavorable events?

Why didn't Theresa May consult with Parliament before negotiating a deal with the EU?

Term for the "extreme-extension" version of a straw man fallacy?

What's the point of interval inversion?

Trouble understanding the speech of overseas colleagues

Only print output after finding pattern

Rotate a column

Can a single photon have an energy density?

How do we know the LHC results are robust?

What is the purpose of the Evocation wizard's Potent Cantrip feature?

Why do remote companies require working in the US?

Fastest way to shutdown Ubuntu Mate 18.10

Anatomically Correct Strange Women In Ponds Distributing Swords

Inappropriate reference requests from Journal reviewers



VS Code: “Cannot find module” from root path



The Next CEO of Stack OverflowHow do I hide certain files from the sidebar in Visual Studio Code?Gulp sourcemaps with TypeScript and BabelImporting lodash into angular2 + typescript applicationTypescript compiler cannot find locally installed npm moduleAngular 2 TypeScript ErrorsPaths property in tsconfig doesn't workWebpack + React + TypeScript: Module not found … in … node_modules/react/Typescript does not resolve definition file for npm packageVSCode typescript importing json file highlighting issueVisual Studio Code not finding any TS or node packages










1















I cannot seem to solve a module import issue with Visual Studio Code:



Cannot find module



I've a setup a sample repo to illustrate this problem, with a directory structure like this:



➜ tree -I node_modules
.
├── README.md
├── packages
│   ├── jsx
│   │   └── jsx.jsx
│   ├── tjs
│   │   └── tjs.js
│   ├── tscript
│   │   └── tscript.js
│   └── tsx
│   └── tsx.tsx
├── src
│   ├── entry.ts
│   └── localjs.js
└── tsconfig.json


I'd like to have this setup work with babel-typescript, but my investigation indicates that the problem seems to be intrinsic to VSCode, so I've left it out of the sample.



I've tried all the permutations of the paths for tsconfig.json that I've seen i.e.



 "paths": 
"*": [
"*",
"packages/*",
"packages/*/index.tsx",
"packages/*/index.jsx",
"packages/*/index.js"
],
"$1": [
"packages/$1/$1"
],
"~/*": [
"packages/*"
],
"~/$1": [
"packages/$1/$1"
],
"*/$1": [
"*/$1/$1",
"packages/$1/$1",
"*/packages/$1/$1"
]



The handbook doesn't offer much insight.










share|improve this question


























    1















    I cannot seem to solve a module import issue with Visual Studio Code:



    Cannot find module



    I've a setup a sample repo to illustrate this problem, with a directory structure like this:



    ➜ tree -I node_modules
    .
    ├── README.md
    ├── packages
    │   ├── jsx
    │   │   └── jsx.jsx
    │   ├── tjs
    │   │   └── tjs.js
    │   ├── tscript
    │   │   └── tscript.js
    │   └── tsx
    │   └── tsx.tsx
    ├── src
    │   ├── entry.ts
    │   └── localjs.js
    └── tsconfig.json


    I'd like to have this setup work with babel-typescript, but my investigation indicates that the problem seems to be intrinsic to VSCode, so I've left it out of the sample.



    I've tried all the permutations of the paths for tsconfig.json that I've seen i.e.



     "paths": 
    "*": [
    "*",
    "packages/*",
    "packages/*/index.tsx",
    "packages/*/index.jsx",
    "packages/*/index.js"
    ],
    "$1": [
    "packages/$1/$1"
    ],
    "~/*": [
    "packages/*"
    ],
    "~/$1": [
    "packages/$1/$1"
    ],
    "*/$1": [
    "*/$1/$1",
    "packages/$1/$1",
    "*/packages/$1/$1"
    ]



    The handbook doesn't offer much insight.










    share|improve this question
























      1












      1








      1








      I cannot seem to solve a module import issue with Visual Studio Code:



      Cannot find module



      I've a setup a sample repo to illustrate this problem, with a directory structure like this:



      ➜ tree -I node_modules
      .
      ├── README.md
      ├── packages
      │   ├── jsx
      │   │   └── jsx.jsx
      │   ├── tjs
      │   │   └── tjs.js
      │   ├── tscript
      │   │   └── tscript.js
      │   └── tsx
      │   └── tsx.tsx
      ├── src
      │   ├── entry.ts
      │   └── localjs.js
      └── tsconfig.json


      I'd like to have this setup work with babel-typescript, but my investigation indicates that the problem seems to be intrinsic to VSCode, so I've left it out of the sample.



      I've tried all the permutations of the paths for tsconfig.json that I've seen i.e.



       "paths": 
      "*": [
      "*",
      "packages/*",
      "packages/*/index.tsx",
      "packages/*/index.jsx",
      "packages/*/index.js"
      ],
      "$1": [
      "packages/$1/$1"
      ],
      "~/*": [
      "packages/*"
      ],
      "~/$1": [
      "packages/$1/$1"
      ],
      "*/$1": [
      "*/$1/$1",
      "packages/$1/$1",
      "*/packages/$1/$1"
      ]



      The handbook doesn't offer much insight.










      share|improve this question














      I cannot seem to solve a module import issue with Visual Studio Code:



      Cannot find module



      I've a setup a sample repo to illustrate this problem, with a directory structure like this:



      ➜ tree -I node_modules
      .
      ├── README.md
      ├── packages
      │   ├── jsx
      │   │   └── jsx.jsx
      │   ├── tjs
      │   │   └── tjs.js
      │   ├── tscript
      │   │   └── tscript.js
      │   └── tsx
      │   └── tsx.tsx
      ├── src
      │   ├── entry.ts
      │   └── localjs.js
      └── tsconfig.json


      I'd like to have this setup work with babel-typescript, but my investigation indicates that the problem seems to be intrinsic to VSCode, so I've left it out of the sample.



      I've tried all the permutations of the paths for tsconfig.json that I've seen i.e.



       "paths": 
      "*": [
      "*",
      "packages/*",
      "packages/*/index.tsx",
      "packages/*/index.jsx",
      "packages/*/index.js"
      ],
      "$1": [
      "packages/$1/$1"
      ],
      "~/*": [
      "packages/*"
      ],
      "~/$1": [
      "packages/$1/$1"
      ],
      "*/$1": [
      "*/$1/$1",
      "packages/$1/$1",
      "*/packages/$1/$1"
      ]



      The handbook doesn't offer much insight.







      typescript visual-studio-code






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 8 at 12:47









      Brian M. HuntBrian M. Hunt

      36.6k59177298




      36.6k59177298






















          2 Answers
          2






          active

          oldest

          votes


















          1





          +500









          You already got an answer from Wex suggesting that you rename your files to have the basename index plus the appropriate extension and use the mapping "*"*: ["*", "packages/*"]. You mentioned in a comment that you'd rather avoid renaming the files. Besides avoiding renames, I'm not a fan of having a lot of files be named index.<some_extension>. When working, my eyes are naturally drawn to the basename of the files I'm working on or getting reports about. Having to distinguish files that have near-identical basenames by directory is possible but requires more cognitive work on my part to look away from the basename and at the path, or more work at the keyboard for completion. (It takes longer to type. There's only so much help the IDE can provide.) It is enough to be annoying.



          First, let's deal with the dead ends. I see no evidence that ~ and $1 are treated specially in paths. I went to check tsc's code and see nothing there that handles such patterns. It could be that I missed it, but I think they are just not special. Also, ignoring extensions for the moment, your desired mapping is something packages/<package_name>/<package_name>.ext The package name appears twice. So it would be tempting to set a mapping like "*": ["packages/*/*.ext"] but that's explicitly not allowed by TypesScript: tsc will give you an error about the two asterisks appearing in the desired mapping. So that's not an option either.



          Use package.json



          You could dodge the renaming issue by adding a package.json to each package with a "main" field that points to the file you want to be considered the entry point of your package. For instance, packages/jsx/package.json could contain this:




          "main": "jsx.jsx"



          By providing similar files for all other packages, you can reduce the relevant configuration to:



          "baseUrl": "",
          "paths":
          "*": ["packages/*", "*"]
          ,


          Or you can use "baseUrl" to point to your packages and omit "paths" entirely:



          "baseUrl": "packages/",


          Make sure that you lint the package.json files because tsc will simply ignore them silently if there's any syntactic mistake in these files.



          Add index Files that Reexport your Entry Module



          Another method would be to use index files that simply reexport all of the file you'd otherwise want to be the entry point of your package. The files you currently have would remain there but would be referenced by appropriately designed index files. For instance, packages/tsx/index.ts could be:



          export default from "./tsx";


          If all your packages just provide a default export, they could all follow the pattern above. Otherwise, if a package exports multiple symbols and just want to reexport everything, you can do:



          export * from "./myModule"; 


          If you do this for all your packages, you don't need to rename anything but you'd have additional index files to satisfy the "*": ["*", "packages/*"] mapping.



          In a comment, you mentioned using a tool like Barrelsby to generate index files. I'd be concerned about the impact on development. I can see generating an index file acting as a facade as part of publishing your project. So people consuming the published project deal with a file generated by Barrelsby or some other tool. However, your index files appear to me to be internal to your project. So in order to get proper IDE support while developing the index files will have to already exist before contributors start contributing. So contributors would have to run something that generates the index files before they start contributing. You would also have generated files that live side by side with files that are authored directly by developers. I try to avoid this in my projects.



          If it were my project and I decided to add index files to satisfy the tsconfig.json mapping, I'd aim to structure my project so that the index files boil down to one of the two cases above, and skip using a code generator. (Actually, I'd aim for the 2nd of the two cases above, because I prefer to avoid default exports. See here for a discussion of the issues with default exports.)



          Individually Map The Packages



          If the other solutions are problematic for your specific project, you can provide one mapping per package:



          "paths": 
          "jsx": ["packages/jsx/jsx.jsx"],
          "tjs": ["packages/tjs/tjs.js"],
          "tscript": ["packages/tscript/tscript.js"],
          "tsx": ["packages/tsx/tsx.tsx"],
          ,


          This means adding a mapping each time you add a new package. Whether or not this is viable depends on your specific project. You could also use a baseUrl set to "packages/" and remove packages/ from all the paths above:



          "baseUrl": "packages/",
          "paths":
          "jsx": ["jsx/jsx.jsx"],
          "tjs": ["tjs/tjs.js"],
          "tscript": ["tscript/tscript.js"],
          "tsx": ["tsx/tsx.tsx"],
          ,


          This makes the whole thing less verbose though you still have to provide one mapping per package.






          share|improve this answer

























          • Thank you very much, @Louis. Editing the tsconfig for each module would be madness (we add/remove/edit 2-3 a week, we'd be clobbering git commits routinely, and our tsconfig would be thousands of lines long). So that's not very practical. However I stumbled across a plugin — module-plugin-d-ts? Do you think this or perhaps another TS plugin might assist in solving this problem?

            – Brian M. Hunt
            Mar 10 at 16:23











          • Sounds like you've got a special case. I don't see module-plugin.d.ts as pertaining to your problem. It illustrates how you can augment a module. For instance, when you load a jQuery plugin, jQuery itself gains new methods. e.g If you load Bootstrap, then jQuery gets $().modal, $().dropdown, ... which are not on the stock jQuery. It is puzzling at first to figure how to declare the interface for such a plugin. Search for "module plugin" on this page for the context to module-plugin.d.ts.

            – Louis
            Mar 10 at 16:56






          • 1





            @BrianM.Hunt Comments are too small to respond to your Barrelsby idea, so I've added a new section to my answer.

            – Louis
            Mar 10 at 20:31






          • 1





            I actually tried putting package.json into the packages/*/ subdirectories... but it did not work. I still have that trial on disk, so I went back to it just now and looked again. Sigh I had an errant trailing comma in the JSON, which caused tsc to silently pretend that the package.json is absent. Once I removed the comma, it worked. If I had not made that mistake, I would have mentioned it in the first place. I'm going to edit my answer to include that possibility.

            – Louis
            Mar 13 at 17:46







          • 1





            And thanks for the bounty!

            – Louis
            Mar 13 at 17:48


















          2














          Part of the issue with your current tsconfig.json is that you are using include: [], so no code will actually be matched by your config!



          I couldn't find any examples of using the $1 pattern the way you have it in your sample config, nor do I think what you are trying to do is possible based on some research (see also: #5039). Are you able to rename package/package.jsx to package/index.jsx? Then your paths config could trivially be changed to:



           "paths": 
          "*": ["*", "packages/*"]
          ,





          share|improve this answer























          • Thanks @wex. I copied the $1 code from a comment on #24116, though that's it. That's a great link to #5039, I'll dig into it more. Thanks for the suggestion to rename packages to package/index.js. It'd involve a huge number lot of file changes, so we'd prefer to avoid it, but it's good to know it's a backstop.

            – Brian M. Hunt
            Mar 9 at 1:42











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55063550%2fvs-code-cannot-find-module-from-root-path%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1





          +500









          You already got an answer from Wex suggesting that you rename your files to have the basename index plus the appropriate extension and use the mapping "*"*: ["*", "packages/*"]. You mentioned in a comment that you'd rather avoid renaming the files. Besides avoiding renames, I'm not a fan of having a lot of files be named index.<some_extension>. When working, my eyes are naturally drawn to the basename of the files I'm working on or getting reports about. Having to distinguish files that have near-identical basenames by directory is possible but requires more cognitive work on my part to look away from the basename and at the path, or more work at the keyboard for completion. (It takes longer to type. There's only so much help the IDE can provide.) It is enough to be annoying.



          First, let's deal with the dead ends. I see no evidence that ~ and $1 are treated specially in paths. I went to check tsc's code and see nothing there that handles such patterns. It could be that I missed it, but I think they are just not special. Also, ignoring extensions for the moment, your desired mapping is something packages/<package_name>/<package_name>.ext The package name appears twice. So it would be tempting to set a mapping like "*": ["packages/*/*.ext"] but that's explicitly not allowed by TypesScript: tsc will give you an error about the two asterisks appearing in the desired mapping. So that's not an option either.



          Use package.json



          You could dodge the renaming issue by adding a package.json to each package with a "main" field that points to the file you want to be considered the entry point of your package. For instance, packages/jsx/package.json could contain this:




          "main": "jsx.jsx"



          By providing similar files for all other packages, you can reduce the relevant configuration to:



          "baseUrl": "",
          "paths":
          "*": ["packages/*", "*"]
          ,


          Or you can use "baseUrl" to point to your packages and omit "paths" entirely:



          "baseUrl": "packages/",


          Make sure that you lint the package.json files because tsc will simply ignore them silently if there's any syntactic mistake in these files.



          Add index Files that Reexport your Entry Module



          Another method would be to use index files that simply reexport all of the file you'd otherwise want to be the entry point of your package. The files you currently have would remain there but would be referenced by appropriately designed index files. For instance, packages/tsx/index.ts could be:



          export default from "./tsx";


          If all your packages just provide a default export, they could all follow the pattern above. Otherwise, if a package exports multiple symbols and just want to reexport everything, you can do:



          export * from "./myModule"; 


          If you do this for all your packages, you don't need to rename anything but you'd have additional index files to satisfy the "*": ["*", "packages/*"] mapping.



          In a comment, you mentioned using a tool like Barrelsby to generate index files. I'd be concerned about the impact on development. I can see generating an index file acting as a facade as part of publishing your project. So people consuming the published project deal with a file generated by Barrelsby or some other tool. However, your index files appear to me to be internal to your project. So in order to get proper IDE support while developing the index files will have to already exist before contributors start contributing. So contributors would have to run something that generates the index files before they start contributing. You would also have generated files that live side by side with files that are authored directly by developers. I try to avoid this in my projects.



          If it were my project and I decided to add index files to satisfy the tsconfig.json mapping, I'd aim to structure my project so that the index files boil down to one of the two cases above, and skip using a code generator. (Actually, I'd aim for the 2nd of the two cases above, because I prefer to avoid default exports. See here for a discussion of the issues with default exports.)



          Individually Map The Packages



          If the other solutions are problematic for your specific project, you can provide one mapping per package:



          "paths": 
          "jsx": ["packages/jsx/jsx.jsx"],
          "tjs": ["packages/tjs/tjs.js"],
          "tscript": ["packages/tscript/tscript.js"],
          "tsx": ["packages/tsx/tsx.tsx"],
          ,


          This means adding a mapping each time you add a new package. Whether or not this is viable depends on your specific project. You could also use a baseUrl set to "packages/" and remove packages/ from all the paths above:



          "baseUrl": "packages/",
          "paths":
          "jsx": ["jsx/jsx.jsx"],
          "tjs": ["tjs/tjs.js"],
          "tscript": ["tscript/tscript.js"],
          "tsx": ["tsx/tsx.tsx"],
          ,


          This makes the whole thing less verbose though you still have to provide one mapping per package.






          share|improve this answer

























          • Thank you very much, @Louis. Editing the tsconfig for each module would be madness (we add/remove/edit 2-3 a week, we'd be clobbering git commits routinely, and our tsconfig would be thousands of lines long). So that's not very practical. However I stumbled across a plugin — module-plugin-d-ts? Do you think this or perhaps another TS plugin might assist in solving this problem?

            – Brian M. Hunt
            Mar 10 at 16:23











          • Sounds like you've got a special case. I don't see module-plugin.d.ts as pertaining to your problem. It illustrates how you can augment a module. For instance, when you load a jQuery plugin, jQuery itself gains new methods. e.g If you load Bootstrap, then jQuery gets $().modal, $().dropdown, ... which are not on the stock jQuery. It is puzzling at first to figure how to declare the interface for such a plugin. Search for "module plugin" on this page for the context to module-plugin.d.ts.

            – Louis
            Mar 10 at 16:56






          • 1





            @BrianM.Hunt Comments are too small to respond to your Barrelsby idea, so I've added a new section to my answer.

            – Louis
            Mar 10 at 20:31






          • 1





            I actually tried putting package.json into the packages/*/ subdirectories... but it did not work. I still have that trial on disk, so I went back to it just now and looked again. Sigh I had an errant trailing comma in the JSON, which caused tsc to silently pretend that the package.json is absent. Once I removed the comma, it worked. If I had not made that mistake, I would have mentioned it in the first place. I'm going to edit my answer to include that possibility.

            – Louis
            Mar 13 at 17:46







          • 1





            And thanks for the bounty!

            – Louis
            Mar 13 at 17:48















          1





          +500









          You already got an answer from Wex suggesting that you rename your files to have the basename index plus the appropriate extension and use the mapping "*"*: ["*", "packages/*"]. You mentioned in a comment that you'd rather avoid renaming the files. Besides avoiding renames, I'm not a fan of having a lot of files be named index.<some_extension>. When working, my eyes are naturally drawn to the basename of the files I'm working on or getting reports about. Having to distinguish files that have near-identical basenames by directory is possible but requires more cognitive work on my part to look away from the basename and at the path, or more work at the keyboard for completion. (It takes longer to type. There's only so much help the IDE can provide.) It is enough to be annoying.



          First, let's deal with the dead ends. I see no evidence that ~ and $1 are treated specially in paths. I went to check tsc's code and see nothing there that handles such patterns. It could be that I missed it, but I think they are just not special. Also, ignoring extensions for the moment, your desired mapping is something packages/<package_name>/<package_name>.ext The package name appears twice. So it would be tempting to set a mapping like "*": ["packages/*/*.ext"] but that's explicitly not allowed by TypesScript: tsc will give you an error about the two asterisks appearing in the desired mapping. So that's not an option either.



          Use package.json



          You could dodge the renaming issue by adding a package.json to each package with a "main" field that points to the file you want to be considered the entry point of your package. For instance, packages/jsx/package.json could contain this:




          "main": "jsx.jsx"



          By providing similar files for all other packages, you can reduce the relevant configuration to:



          "baseUrl": "",
          "paths":
          "*": ["packages/*", "*"]
          ,


          Or you can use "baseUrl" to point to your packages and omit "paths" entirely:



          "baseUrl": "packages/",


          Make sure that you lint the package.json files because tsc will simply ignore them silently if there's any syntactic mistake in these files.



          Add index Files that Reexport your Entry Module



          Another method would be to use index files that simply reexport all of the file you'd otherwise want to be the entry point of your package. The files you currently have would remain there but would be referenced by appropriately designed index files. For instance, packages/tsx/index.ts could be:



          export default from "./tsx";


          If all your packages just provide a default export, they could all follow the pattern above. Otherwise, if a package exports multiple symbols and just want to reexport everything, you can do:



          export * from "./myModule"; 


          If you do this for all your packages, you don't need to rename anything but you'd have additional index files to satisfy the "*": ["*", "packages/*"] mapping.



          In a comment, you mentioned using a tool like Barrelsby to generate index files. I'd be concerned about the impact on development. I can see generating an index file acting as a facade as part of publishing your project. So people consuming the published project deal with a file generated by Barrelsby or some other tool. However, your index files appear to me to be internal to your project. So in order to get proper IDE support while developing the index files will have to already exist before contributors start contributing. So contributors would have to run something that generates the index files before they start contributing. You would also have generated files that live side by side with files that are authored directly by developers. I try to avoid this in my projects.



          If it were my project and I decided to add index files to satisfy the tsconfig.json mapping, I'd aim to structure my project so that the index files boil down to one of the two cases above, and skip using a code generator. (Actually, I'd aim for the 2nd of the two cases above, because I prefer to avoid default exports. See here for a discussion of the issues with default exports.)



          Individually Map The Packages



          If the other solutions are problematic for your specific project, you can provide one mapping per package:



          "paths": 
          "jsx": ["packages/jsx/jsx.jsx"],
          "tjs": ["packages/tjs/tjs.js"],
          "tscript": ["packages/tscript/tscript.js"],
          "tsx": ["packages/tsx/tsx.tsx"],
          ,


          This means adding a mapping each time you add a new package. Whether or not this is viable depends on your specific project. You could also use a baseUrl set to "packages/" and remove packages/ from all the paths above:



          "baseUrl": "packages/",
          "paths":
          "jsx": ["jsx/jsx.jsx"],
          "tjs": ["tjs/tjs.js"],
          "tscript": ["tscript/tscript.js"],
          "tsx": ["tsx/tsx.tsx"],
          ,


          This makes the whole thing less verbose though you still have to provide one mapping per package.






          share|improve this answer

























          • Thank you very much, @Louis. Editing the tsconfig for each module would be madness (we add/remove/edit 2-3 a week, we'd be clobbering git commits routinely, and our tsconfig would be thousands of lines long). So that's not very practical. However I stumbled across a plugin — module-plugin-d-ts? Do you think this or perhaps another TS plugin might assist in solving this problem?

            – Brian M. Hunt
            Mar 10 at 16:23











          • Sounds like you've got a special case. I don't see module-plugin.d.ts as pertaining to your problem. It illustrates how you can augment a module. For instance, when you load a jQuery plugin, jQuery itself gains new methods. e.g If you load Bootstrap, then jQuery gets $().modal, $().dropdown, ... which are not on the stock jQuery. It is puzzling at first to figure how to declare the interface for such a plugin. Search for "module plugin" on this page for the context to module-plugin.d.ts.

            – Louis
            Mar 10 at 16:56






          • 1





            @BrianM.Hunt Comments are too small to respond to your Barrelsby idea, so I've added a new section to my answer.

            – Louis
            Mar 10 at 20:31






          • 1





            I actually tried putting package.json into the packages/*/ subdirectories... but it did not work. I still have that trial on disk, so I went back to it just now and looked again. Sigh I had an errant trailing comma in the JSON, which caused tsc to silently pretend that the package.json is absent. Once I removed the comma, it worked. If I had not made that mistake, I would have mentioned it in the first place. I'm going to edit my answer to include that possibility.

            – Louis
            Mar 13 at 17:46







          • 1





            And thanks for the bounty!

            – Louis
            Mar 13 at 17:48













          1





          +500







          1





          +500



          1




          +500





          You already got an answer from Wex suggesting that you rename your files to have the basename index plus the appropriate extension and use the mapping "*"*: ["*", "packages/*"]. You mentioned in a comment that you'd rather avoid renaming the files. Besides avoiding renames, I'm not a fan of having a lot of files be named index.<some_extension>. When working, my eyes are naturally drawn to the basename of the files I'm working on or getting reports about. Having to distinguish files that have near-identical basenames by directory is possible but requires more cognitive work on my part to look away from the basename and at the path, or more work at the keyboard for completion. (It takes longer to type. There's only so much help the IDE can provide.) It is enough to be annoying.



          First, let's deal with the dead ends. I see no evidence that ~ and $1 are treated specially in paths. I went to check tsc's code and see nothing there that handles such patterns. It could be that I missed it, but I think they are just not special. Also, ignoring extensions for the moment, your desired mapping is something packages/<package_name>/<package_name>.ext The package name appears twice. So it would be tempting to set a mapping like "*": ["packages/*/*.ext"] but that's explicitly not allowed by TypesScript: tsc will give you an error about the two asterisks appearing in the desired mapping. So that's not an option either.



          Use package.json



          You could dodge the renaming issue by adding a package.json to each package with a "main" field that points to the file you want to be considered the entry point of your package. For instance, packages/jsx/package.json could contain this:




          "main": "jsx.jsx"



          By providing similar files for all other packages, you can reduce the relevant configuration to:



          "baseUrl": "",
          "paths":
          "*": ["packages/*", "*"]
          ,


          Or you can use "baseUrl" to point to your packages and omit "paths" entirely:



          "baseUrl": "packages/",


          Make sure that you lint the package.json files because tsc will simply ignore them silently if there's any syntactic mistake in these files.



          Add index Files that Reexport your Entry Module



          Another method would be to use index files that simply reexport all of the file you'd otherwise want to be the entry point of your package. The files you currently have would remain there but would be referenced by appropriately designed index files. For instance, packages/tsx/index.ts could be:



          export default from "./tsx";


          If all your packages just provide a default export, they could all follow the pattern above. Otherwise, if a package exports multiple symbols and just want to reexport everything, you can do:



          export * from "./myModule"; 


          If you do this for all your packages, you don't need to rename anything but you'd have additional index files to satisfy the "*": ["*", "packages/*"] mapping.



          In a comment, you mentioned using a tool like Barrelsby to generate index files. I'd be concerned about the impact on development. I can see generating an index file acting as a facade as part of publishing your project. So people consuming the published project deal with a file generated by Barrelsby or some other tool. However, your index files appear to me to be internal to your project. So in order to get proper IDE support while developing the index files will have to already exist before contributors start contributing. So contributors would have to run something that generates the index files before they start contributing. You would also have generated files that live side by side with files that are authored directly by developers. I try to avoid this in my projects.



          If it were my project and I decided to add index files to satisfy the tsconfig.json mapping, I'd aim to structure my project so that the index files boil down to one of the two cases above, and skip using a code generator. (Actually, I'd aim for the 2nd of the two cases above, because I prefer to avoid default exports. See here for a discussion of the issues with default exports.)



          Individually Map The Packages



          If the other solutions are problematic for your specific project, you can provide one mapping per package:



          "paths": 
          "jsx": ["packages/jsx/jsx.jsx"],
          "tjs": ["packages/tjs/tjs.js"],
          "tscript": ["packages/tscript/tscript.js"],
          "tsx": ["packages/tsx/tsx.tsx"],
          ,


          This means adding a mapping each time you add a new package. Whether or not this is viable depends on your specific project. You could also use a baseUrl set to "packages/" and remove packages/ from all the paths above:



          "baseUrl": "packages/",
          "paths":
          "jsx": ["jsx/jsx.jsx"],
          "tjs": ["tjs/tjs.js"],
          "tscript": ["tscript/tscript.js"],
          "tsx": ["tsx/tsx.tsx"],
          ,


          This makes the whole thing less verbose though you still have to provide one mapping per package.






          share|improve this answer















          You already got an answer from Wex suggesting that you rename your files to have the basename index plus the appropriate extension and use the mapping "*"*: ["*", "packages/*"]. You mentioned in a comment that you'd rather avoid renaming the files. Besides avoiding renames, I'm not a fan of having a lot of files be named index.<some_extension>. When working, my eyes are naturally drawn to the basename of the files I'm working on or getting reports about. Having to distinguish files that have near-identical basenames by directory is possible but requires more cognitive work on my part to look away from the basename and at the path, or more work at the keyboard for completion. (It takes longer to type. There's only so much help the IDE can provide.) It is enough to be annoying.



          First, let's deal with the dead ends. I see no evidence that ~ and $1 are treated specially in paths. I went to check tsc's code and see nothing there that handles such patterns. It could be that I missed it, but I think they are just not special. Also, ignoring extensions for the moment, your desired mapping is something packages/<package_name>/<package_name>.ext The package name appears twice. So it would be tempting to set a mapping like "*": ["packages/*/*.ext"] but that's explicitly not allowed by TypesScript: tsc will give you an error about the two asterisks appearing in the desired mapping. So that's not an option either.



          Use package.json



          You could dodge the renaming issue by adding a package.json to each package with a "main" field that points to the file you want to be considered the entry point of your package. For instance, packages/jsx/package.json could contain this:




          "main": "jsx.jsx"



          By providing similar files for all other packages, you can reduce the relevant configuration to:



          "baseUrl": "",
          "paths":
          "*": ["packages/*", "*"]
          ,


          Or you can use "baseUrl" to point to your packages and omit "paths" entirely:



          "baseUrl": "packages/",


          Make sure that you lint the package.json files because tsc will simply ignore them silently if there's any syntactic mistake in these files.



          Add index Files that Reexport your Entry Module



          Another method would be to use index files that simply reexport all of the file you'd otherwise want to be the entry point of your package. The files you currently have would remain there but would be referenced by appropriately designed index files. For instance, packages/tsx/index.ts could be:



          export default from "./tsx";


          If all your packages just provide a default export, they could all follow the pattern above. Otherwise, if a package exports multiple symbols and just want to reexport everything, you can do:



          export * from "./myModule"; 


          If you do this for all your packages, you don't need to rename anything but you'd have additional index files to satisfy the "*": ["*", "packages/*"] mapping.



          In a comment, you mentioned using a tool like Barrelsby to generate index files. I'd be concerned about the impact on development. I can see generating an index file acting as a facade as part of publishing your project. So people consuming the published project deal with a file generated by Barrelsby or some other tool. However, your index files appear to me to be internal to your project. So in order to get proper IDE support while developing the index files will have to already exist before contributors start contributing. So contributors would have to run something that generates the index files before they start contributing. You would also have generated files that live side by side with files that are authored directly by developers. I try to avoid this in my projects.



          If it were my project and I decided to add index files to satisfy the tsconfig.json mapping, I'd aim to structure my project so that the index files boil down to one of the two cases above, and skip using a code generator. (Actually, I'd aim for the 2nd of the two cases above, because I prefer to avoid default exports. See here for a discussion of the issues with default exports.)



          Individually Map The Packages



          If the other solutions are problematic for your specific project, you can provide one mapping per package:



          "paths": 
          "jsx": ["packages/jsx/jsx.jsx"],
          "tjs": ["packages/tjs/tjs.js"],
          "tscript": ["packages/tscript/tscript.js"],
          "tsx": ["packages/tsx/tsx.tsx"],
          ,


          This means adding a mapping each time you add a new package. Whether or not this is viable depends on your specific project. You could also use a baseUrl set to "packages/" and remove packages/ from all the paths above:



          "baseUrl": "packages/",
          "paths":
          "jsx": ["jsx/jsx.jsx"],
          "tjs": ["tjs/tjs.js"],
          "tscript": ["tscript/tscript.js"],
          "tsx": ["tsx/tsx.tsx"],
          ,


          This makes the whole thing less verbose though you still have to provide one mapping per package.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 13 at 18:05

























          answered Mar 10 at 15:50









          LouisLouis

          98k22189238




          98k22189238












          • Thank you very much, @Louis. Editing the tsconfig for each module would be madness (we add/remove/edit 2-3 a week, we'd be clobbering git commits routinely, and our tsconfig would be thousands of lines long). So that's not very practical. However I stumbled across a plugin — module-plugin-d-ts? Do you think this or perhaps another TS plugin might assist in solving this problem?

            – Brian M. Hunt
            Mar 10 at 16:23











          • Sounds like you've got a special case. I don't see module-plugin.d.ts as pertaining to your problem. It illustrates how you can augment a module. For instance, when you load a jQuery plugin, jQuery itself gains new methods. e.g If you load Bootstrap, then jQuery gets $().modal, $().dropdown, ... which are not on the stock jQuery. It is puzzling at first to figure how to declare the interface for such a plugin. Search for "module plugin" on this page for the context to module-plugin.d.ts.

            – Louis
            Mar 10 at 16:56






          • 1





            @BrianM.Hunt Comments are too small to respond to your Barrelsby idea, so I've added a new section to my answer.

            – Louis
            Mar 10 at 20:31






          • 1





            I actually tried putting package.json into the packages/*/ subdirectories... but it did not work. I still have that trial on disk, so I went back to it just now and looked again. Sigh I had an errant trailing comma in the JSON, which caused tsc to silently pretend that the package.json is absent. Once I removed the comma, it worked. If I had not made that mistake, I would have mentioned it in the first place. I'm going to edit my answer to include that possibility.

            – Louis
            Mar 13 at 17:46







          • 1





            And thanks for the bounty!

            – Louis
            Mar 13 at 17:48

















          • Thank you very much, @Louis. Editing the tsconfig for each module would be madness (we add/remove/edit 2-3 a week, we'd be clobbering git commits routinely, and our tsconfig would be thousands of lines long). So that's not very practical. However I stumbled across a plugin — module-plugin-d-ts? Do you think this or perhaps another TS plugin might assist in solving this problem?

            – Brian M. Hunt
            Mar 10 at 16:23











          • Sounds like you've got a special case. I don't see module-plugin.d.ts as pertaining to your problem. It illustrates how you can augment a module. For instance, when you load a jQuery plugin, jQuery itself gains new methods. e.g If you load Bootstrap, then jQuery gets $().modal, $().dropdown, ... which are not on the stock jQuery. It is puzzling at first to figure how to declare the interface for such a plugin. Search for "module plugin" on this page for the context to module-plugin.d.ts.

            – Louis
            Mar 10 at 16:56






          • 1





            @BrianM.Hunt Comments are too small to respond to your Barrelsby idea, so I've added a new section to my answer.

            – Louis
            Mar 10 at 20:31






          • 1





            I actually tried putting package.json into the packages/*/ subdirectories... but it did not work. I still have that trial on disk, so I went back to it just now and looked again. Sigh I had an errant trailing comma in the JSON, which caused tsc to silently pretend that the package.json is absent. Once I removed the comma, it worked. If I had not made that mistake, I would have mentioned it in the first place. I'm going to edit my answer to include that possibility.

            – Louis
            Mar 13 at 17:46







          • 1





            And thanks for the bounty!

            – Louis
            Mar 13 at 17:48
















          Thank you very much, @Louis. Editing the tsconfig for each module would be madness (we add/remove/edit 2-3 a week, we'd be clobbering git commits routinely, and our tsconfig would be thousands of lines long). So that's not very practical. However I stumbled across a plugin — module-plugin-d-ts? Do you think this or perhaps another TS plugin might assist in solving this problem?

          – Brian M. Hunt
          Mar 10 at 16:23





          Thank you very much, @Louis. Editing the tsconfig for each module would be madness (we add/remove/edit 2-3 a week, we'd be clobbering git commits routinely, and our tsconfig would be thousands of lines long). So that's not very practical. However I stumbled across a plugin — module-plugin-d-ts? Do you think this or perhaps another TS plugin might assist in solving this problem?

          – Brian M. Hunt
          Mar 10 at 16:23













          Sounds like you've got a special case. I don't see module-plugin.d.ts as pertaining to your problem. It illustrates how you can augment a module. For instance, when you load a jQuery plugin, jQuery itself gains new methods. e.g If you load Bootstrap, then jQuery gets $().modal, $().dropdown, ... which are not on the stock jQuery. It is puzzling at first to figure how to declare the interface for such a plugin. Search for "module plugin" on this page for the context to module-plugin.d.ts.

          – Louis
          Mar 10 at 16:56





          Sounds like you've got a special case. I don't see module-plugin.d.ts as pertaining to your problem. It illustrates how you can augment a module. For instance, when you load a jQuery plugin, jQuery itself gains new methods. e.g If you load Bootstrap, then jQuery gets $().modal, $().dropdown, ... which are not on the stock jQuery. It is puzzling at first to figure how to declare the interface for such a plugin. Search for "module plugin" on this page for the context to module-plugin.d.ts.

          – Louis
          Mar 10 at 16:56




          1




          1





          @BrianM.Hunt Comments are too small to respond to your Barrelsby idea, so I've added a new section to my answer.

          – Louis
          Mar 10 at 20:31





          @BrianM.Hunt Comments are too small to respond to your Barrelsby idea, so I've added a new section to my answer.

          – Louis
          Mar 10 at 20:31




          1




          1





          I actually tried putting package.json into the packages/*/ subdirectories... but it did not work. I still have that trial on disk, so I went back to it just now and looked again. Sigh I had an errant trailing comma in the JSON, which caused tsc to silently pretend that the package.json is absent. Once I removed the comma, it worked. If I had not made that mistake, I would have mentioned it in the first place. I'm going to edit my answer to include that possibility.

          – Louis
          Mar 13 at 17:46






          I actually tried putting package.json into the packages/*/ subdirectories... but it did not work. I still have that trial on disk, so I went back to it just now and looked again. Sigh I had an errant trailing comma in the JSON, which caused tsc to silently pretend that the package.json is absent. Once I removed the comma, it worked. If I had not made that mistake, I would have mentioned it in the first place. I'm going to edit my answer to include that possibility.

          – Louis
          Mar 13 at 17:46





          1




          1





          And thanks for the bounty!

          – Louis
          Mar 13 at 17:48





          And thanks for the bounty!

          – Louis
          Mar 13 at 17:48













          2














          Part of the issue with your current tsconfig.json is that you are using include: [], so no code will actually be matched by your config!



          I couldn't find any examples of using the $1 pattern the way you have it in your sample config, nor do I think what you are trying to do is possible based on some research (see also: #5039). Are you able to rename package/package.jsx to package/index.jsx? Then your paths config could trivially be changed to:



           "paths": 
          "*": ["*", "packages/*"]
          ,





          share|improve this answer























          • Thanks @wex. I copied the $1 code from a comment on #24116, though that's it. That's a great link to #5039, I'll dig into it more. Thanks for the suggestion to rename packages to package/index.js. It'd involve a huge number lot of file changes, so we'd prefer to avoid it, but it's good to know it's a backstop.

            – Brian M. Hunt
            Mar 9 at 1:42















          2














          Part of the issue with your current tsconfig.json is that you are using include: [], so no code will actually be matched by your config!



          I couldn't find any examples of using the $1 pattern the way you have it in your sample config, nor do I think what you are trying to do is possible based on some research (see also: #5039). Are you able to rename package/package.jsx to package/index.jsx? Then your paths config could trivially be changed to:



           "paths": 
          "*": ["*", "packages/*"]
          ,





          share|improve this answer























          • Thanks @wex. I copied the $1 code from a comment on #24116, though that's it. That's a great link to #5039, I'll dig into it more. Thanks for the suggestion to rename packages to package/index.js. It'd involve a huge number lot of file changes, so we'd prefer to avoid it, but it's good to know it's a backstop.

            – Brian M. Hunt
            Mar 9 at 1:42













          2












          2








          2







          Part of the issue with your current tsconfig.json is that you are using include: [], so no code will actually be matched by your config!



          I couldn't find any examples of using the $1 pattern the way you have it in your sample config, nor do I think what you are trying to do is possible based on some research (see also: #5039). Are you able to rename package/package.jsx to package/index.jsx? Then your paths config could trivially be changed to:



           "paths": 
          "*": ["*", "packages/*"]
          ,





          share|improve this answer













          Part of the issue with your current tsconfig.json is that you are using include: [], so no code will actually be matched by your config!



          I couldn't find any examples of using the $1 pattern the way you have it in your sample config, nor do I think what you are trying to do is possible based on some research (see also: #5039). Are you able to rename package/package.jsx to package/index.jsx? Then your paths config could trivially be changed to:



           "paths": 
          "*": ["*", "packages/*"]
          ,






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 8 at 22:49









          WexWex

          11.6k95091




          11.6k95091












          • Thanks @wex. I copied the $1 code from a comment on #24116, though that's it. That's a great link to #5039, I'll dig into it more. Thanks for the suggestion to rename packages to package/index.js. It'd involve a huge number lot of file changes, so we'd prefer to avoid it, but it's good to know it's a backstop.

            – Brian M. Hunt
            Mar 9 at 1:42

















          • Thanks @wex. I copied the $1 code from a comment on #24116, though that's it. That's a great link to #5039, I'll dig into it more. Thanks for the suggestion to rename packages to package/index.js. It'd involve a huge number lot of file changes, so we'd prefer to avoid it, but it's good to know it's a backstop.

            – Brian M. Hunt
            Mar 9 at 1:42
















          Thanks @wex. I copied the $1 code from a comment on #24116, though that's it. That's a great link to #5039, I'll dig into it more. Thanks for the suggestion to rename packages to package/index.js. It'd involve a huge number lot of file changes, so we'd prefer to avoid it, but it's good to know it's a backstop.

          – Brian M. Hunt
          Mar 9 at 1:42





          Thanks @wex. I copied the $1 code from a comment on #24116, though that's it. That's a great link to #5039, I'll dig into it more. Thanks for the suggestion to rename packages to package/index.js. It'd involve a huge number lot of file changes, so we'd prefer to avoid it, but it's good to know it's a backstop.

          – Brian M. Hunt
          Mar 9 at 1:42

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55063550%2fvs-code-cannot-find-module-from-root-path%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to get text form Clipboard with JavaScript in Firefox 56?How to validate an email address in JavaScript?How do JavaScript closures work?How do I remove a property from a JavaScript object?How do you get a timestamp in JavaScript?How do I copy to the clipboard in JavaScript?How do I include a JavaScript file in another JavaScript file?Get the current URL with JavaScript?How to replace all occurrences of a string in JavaScriptHow to check whether a string contains a substring in JavaScript?How do I remove a particular element from an array in JavaScript?

          Can't initialize raids on a new ASUS Prime B360M-A motherboard2019 Community Moderator ElectionSimilar to RAID config yet more like mirroring solution?Can't get motherboard serial numberWhy does the BIOS entry point start with a WBINVD instruction?UEFI performance Asus Maximus V Extreme

          List of MPs elected to the English parliament in 1640 (April) Contents List of constituencies and members See also Notes References Navigation menueNational Archives – The Glynde Place ArchivesCobbett's Parliamentary history of England, from the Norman Conquest in 1066 to the year 1803'Aldermen in Parliament', The Aldermen of the City of London: Temp. Henry III – 1912onepage&q&f&#61, false 229