Typescript import relative path

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

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] absolute->relative module path transformation #15479

[FEATURE] absolute->relative module path transformation #15479

Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript

Comments

Problem

tsc does not support transforming absolute module paths into relative paths for modules located outside node_modules. In client side apps, this is often not an issue because people tend to use Webpack or similar tool for transformations and bundling, but for TypeScript apps targeting Node.js, this is an issue because there is usually no need for complex transformations and bundling, and adding additional build steps and tools on top of tsc only for path transformation is cumbersome.

Example input (es2015 style):

import  myModule > from 'myModuleRoot/a/b/my_module';

Example output (CommonJS style):

const myModule = require('./a/b/my_module');

My personal opinion is that relative module paths ( import < . >from ‘../../xxx/yyy’; ) are an abomination and make it difficult to figure out and change application structure. The possibility of using absolute paths would also be a major benefit of using TypeScript for Node.js apps.

Solution

Could this be achieved for example with existing baseUrl and paths options and adding a new —rewriteAbsolute option?

The text was updated successfully, but these errors were encountered:

This issue can be solved if add node_modules directory with symlink to src directory:

project_root/ node_modules/ ../src  

In this case you can use the following import in c.ts :

All will work in typescript and commonjs. You just need to add exclude field in tsconfig.json :

@aluanhaddad I've been using path rewrite (Webpack) on client-side since I began writing React apps. How would it cause problems on the server side if it doesn't cause problems on the client side? Editors already support setting module roots, and linters (ESLint, TSLint) seem to be fine also.

To the maintainers of TypeScript: Please add support for custom module roots so that we can get rid of the awful and unmaintainable import paths.

@ikokostya Many tools have special treatment for node_modules, and it is always treated as a folder for external code. Putting app code into node_modules may solve the import path problem, but introduces potential other problems. It is also ugly solution that shouldn't, in my opinion, be recommended to anyone.

Many tools have special treatment for node_modules, and it is always treated as a folder for external code.

Could you provide example of such tools? In my example all external code are placed in node_modules in project_root .

Putting app code into node_modules may solve the import path problem, but introduces potential other problems.

It is also ugly solution that shouldn't, in my opinion, be recommended to anyone.

Maybe you should read this

And why it's ugly? It uses standard way for loading from node_modules .

@Kitanotori perhaps I misunderstood your suggestion, TypeScript supports this feature with the --baseUrl flag.
My point was that NodeJS doesn't support it and that TypeScript should not attempt to provide the future on top of NodeJS by rewriting paths in output code.

Could you provide example of such tools?

There are too many to count but TypeScript is definitely an example of such a tool.

I think putting application code in a node_modules folder is a very ill-advised hack.

@aluanhaddad --baseUrl setting enables to transpile the app, but what's the point of being able to transpile successfully if you can't execute it? ts-node does not seem to support --baseUrl, so I think it is inaccurate to say that TypeScript supports custom absolute paths.

@ikokostya Thanks for the links. It seems that setting NODE_PATH in the startup script is the best way currently. I think I will go with that approach.

@aluanhaddad --baseUrl setting enables to transpile the app, but what's the point of being able to transpile successfully if you can't execute it? ts-node does not seem to support --baseUrl, so I think it is inaccurate to say that TypeScript supports custom absolute paths.

The point is that it does execute perfectly in environments that support that. RequireJS, SystemJS, and even Webpack support setting a base URL.

What I'm trying to say is that the issue is on the NodeJS side. TypeScript provides base URL configuration to integrate with and take advantage of those other tools.

RyanCavanaugh added Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds labels May 9, 2017

Our general take on this is that you should write the import path that works at runtime, and set your TS flags to satisfy the compiler's module resolution step, rather than writing the import that works out-of-the-box for TS and then trying to have some other step "fix" the paths to what works at runtime.

We have about a billion flags that affect module resolutions already (baseUrl, path mapping, rootDir, outDir, etc). Trying to rewrite import paths "correctly" under all these schemes would be an endless nightmare.

@RyanCavanaugh Sorry to hear that. If Webpack team was able to deliver such feature, I thought TypeScript team could also - considering that TypeScript even has major corporate backing. It's a shame that people are forced to add another build step on top of tsc for such a widely needed feature.

Still hope TypeScript could support this.
Or Just make it easy to create a plugin, so we can build something like babel-plugin-module-resolver to make it work. (ref: #11441)

So anyone got any solution or a really nice workaround without babel to make this happen ?

Edit
I've ended up with a custom transform script using gulp & tsify & gulp-typescript
https://gist.github.com/azarus/f369ee2ab0283ba0793b0ccf0e9ec590
Browserify & Gulp samples included.
So anyone got any solution or a really nice workaround without babel to make this happen ?

@azarus I went with the solution of adding this to my top level file:

import * as AppModulePath from 'app-module-path'; AppModulePath.addPath(__dirname);

The downside is that if the loading order differs from expected, the app crashes. Better solution would be to have a compiler plugin for converting absolute paths to relative paths. However, I'm not sure if TypeScript has any kind of plugin feature.

I created a post-build script for converting absolute paths to relative (doesn't yet have way to set the module root paths, but one can easily implement such): https://gist.github.com/Kitanotori/86c906b2c4032d4426b750d232a4133b

I was thinking of having the module roots being set in package.json via moduleRoots array containing path strings relative to package.json. I wonder what kind of risks there are in this kind of approach?

I've ended up with my own post build script too,
https://gist.github.com/azarus/f369ee2ab0283ba0793b0ccf0e9ec590
Browserify & Gulp samples included.

It acutally uses the tsconfig.json paths and baseUrl setup 🙂
I am gonna make a npm package from this during the weekend, i just haven't had time to properly test the script.

I have this in my tsconfig:

I can't remember if the other options above are necessary, but "paths" will allow this:

import from "~/core/api/fund-managers.api"; 

The core directory is at src/core .

And then I use the npm package "module-alias" and do:

require('module-alias').addAlias("~", __dirname + "/src");

At the top of my top level file.

Webstorm understands the paths option and will auto-import correctly even.

I use tsconfig-paths to handle this during runtime. I'm not aware of any performance implications or issues otherwise. The one objection I could see is monkey-patching Node's module resolution strategy.

@kayjtea I don't think module and moduleResolution are related. Here's a slightly simpeler version that seems to work:

Personally, I prefer writing @src, and for this you can use:

In VSCode I don't seem to have to do anything with my top-level files or npm module-alias.

--- edit ---
Ah damn it. I see now that the paths don't work at runtime work if you don't do more then make the compiler and VSCode happy.

Well i solved this sort of problem by splitting my apllication into npm modules and linking them during development. Symlinks are generated and i find it much easier to solve the relative path hell. However theres still a great need to properly support importing modules by absolute/root path! Any other solution just seems to be band-aid for a pain that needs pain killer.

On Jan 6, 2018 22:21, "Thijs Koerselman" ***@***.***> wrote: @kayjtea I don't think module and moduleResolution are related. Here's a slightly simpeler version that seems to work: "baseUrl": "./", "paths": < "~/*": [ "src/*" ] >, — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub , or mute the thread .

@azarus I think I might have to go that route too.

I have two repo's that are also depending on roughly the same set of helpers and services. And I am getting tired of copying code between the two.

@0x80 i ran into a similar problem when had to share model definitions between 5 different services. I solved this by creating a shared folder that everyone were able to access if needed.
Setting up an NPM link is also easy and less hassle than you would think.
But i am sad that proper solution is still not in place.

Use tspath (https://www.npmjs.com/package/tspath) run it in the project folder after compile, no config needed, it uses the tsconfig to figure things out (a recent version of node is needed)

@duffman Thanks for the tip! I'll check it out 👍

In case you want to configure create-react-app project add:

Is equivalent to NODE_PATH=./ in .env in standard c-r-a project.

Источник

Читайте также:  Отступы от экрана html css
Оцените статью