leddgroup / typescript-transform-paths Goto Github PK
View Code? Open in Web Editor NEWTransforms module resolution paths using TypeScript path mapping and/or custom paths
License: MIT License
Transforms module resolution paths using TypeScript path mapping and/or custom paths
License: MIT License
In Jest, you can mock an entire module with something like
jest.mock('../../path/to/code');
However, unlike my import statements, the transformer here doesn't recognize these nor transform them.
It would be really great if it did. Then I wouldn't have to separately manipulate paths via Jest's aliases and just use the transpiled code everywhere; I can trigger this transformation as part of ts-jest/ttypsecript and it works for all my module resolution except this case.
Is there a way to support this? Does it already?
Projects using rootDirs
define virtual directories. The output source code does not respect the rootDirs
setting, meaning that it outputs paths relative to the original directories. This is problematic for code which uses rootDirs
, as the build process merges directories which breaks the output path.
Will create a fix now.
Bumping into a strange issue with Travis. It says it can't download package.json for typescript transform paths. It works fine for me locally. This is the build page:
https://travis-ci.org/fireflysemantics/validator
25.56s$ npm ci
npm ERR! path /home/travis/build/fireflysemantics/validator/node_modules/typescript-transform-paths/package.json
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! syscall open
npm ERR! enoent ENOENT: no such file or directory, open '/home/travis/build/fireflysemantics/validator/node_modules/typescript-transform-paths/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
***/node_modules/typescript/lib/typescript.js:14332
:ts.skipTrivia(sourceFile.text, errorNode.pos);
TypeError: Cannot read property 'text' of undefined
Operating procedures:
ttsc --watch
I tried out this plugin and it works great for normal es6 import statements with default or named exports. Unfortunately it doesn't work on files with the legacy commonJS export shape.
A workaround is to change the import to es6 and use something like the esModuleInterop
compiler flag. That requires modification of the source code though, and therefore is a heavy handed.
export = 3;
import d = require('Dependency');
import d = require('./Dependency');
No transform was performed
Import of types error (cyclic import is imported, cause it does breaks functionality):
// a.js
import { B } from '@/b';
import { NotRuntime } from '@/c';
export class A {
constructor(public name: NotRuntime) {}
}
export const b = new B();
b.print(new A('This is a random name'));
// b.ts
import { A } from '@/a';
export class B {
print(a: A) {
console.log(a.name);
}
}
// c.ts
export type NotRuntime = string;
throw new Error('Should never happen, until `import "@/c"`');
Produces invalid code with circular dependencies. When without paths and this plugin, resulting b.js does not content require('./a.js')
, which resolves circular dependency error.
probably with github actions
ObjectErrors
import ValidationError
.
When the projects build is run, the import is not generated. I think it's because ObjectErrors
and ValidationError
both reside in the same directory.
If I do not use a paths
import, but instead switch it to a relative import, then the build generates the import.
To see the current behavior:
git clone [email protected]:fireflysemantics/validator.git
npm run dist
Look at dist/container/error/ObjectErrors.d.ts
. It will be missing the ValidationError
import.
Given:
file1.ts:
export type Foo = 'bar';
export const baz = 'inga'; // ;)
file2.ts:
import { Foo, baz } from '@custom/scope/file1';
[...]
When the code is compiled, the Javascript import will read something like this:
file2.js:
import { Foo, baz } from '@custom/scope/file1';
but Foo
will be undefined and cause errors.
Thanks for this plugin!
I noticed that I have to add a dummy "paths": { "*": ["*"] }
entry to tsconfig to make the transformer work. Without it, the module does nothing:
// tsconfig.json (no "paths" at all)
"baseUrl": "src"
"plugins": [{ "transform": "typescript-transform-paths" }],
// src/main.ts
import { app } from "electron"; // a module in node_modules
import { setMenu } from "main/menu"; // src/main/menu.ts; no syntax errors for tsc/vscode
// output:
const electron_1 = require("electron"); // correct
const menu_1 = require("main/menu"); // <-- INCORRECT, NOT ./main/menu
Adding a dummy entry "paths": { "*": ["*"] }
solves the problem.
My IMHO is following: it's a little strange to require "paths" to be present in tsconfig.json. I think in an ideal world, the transform plugin should do exactly the same as TS does when it interprets the entire configuration. If TS understands just baseUrl and shows no syntax errors in both tsc and in VSCode, if it allows to do import from "xyz/abc" where xyz is located in baseUrl, then the transform plugin should do no worse than that. (And I also think that in an ideal world, tsc should have a config option to alter paths natively; although I read their arguments, they still look very weak to me.)
Probably more of a limitation than a bug really...
If you have a directory in your project with the same name as an external module, typescript-transform-paths will replace the import for the external module with a relative path to the directory, instead of importing the external module.
For example, if you have a file graphql/types/scalar.ts
which includes something like import { GraphQLScalarType } from 'graphql'
, the import will be transpiled to const GraphQLScalarType = require("..")
.
I guess you could check whether there's a package with the same name as the import before converting the path.
I changed the example a little bit so that it consumes the sum module within the same project and does the for other modules through index.ts
. However now index.d.ts
and index.js
do not have their paths converted. Any ideas? I pushed the target
directory (Compiled directory) to the github repository,
I noticed a bug with my setup.
I use ttsc to compile a TS library to a JS one.
There are paths
in my tsconfig.json
that point to specific *.ts
files.
For example: "@my-app/lib1": "./path/to/index.ts"
The transformer changes these to require('.../path/to/index.ts')
- the file extension remains the same in the compiled version, even though tsc
would normally convert these to .js
or no extension at all.
snippet from tsconfig.json file
{ "transform": "typescript-transform-paths", "afterDeclarations": true }
replacing path aliases in decleration files does not work in (current) version 2.2.3 (i reverted back to 2.2.1 and it works with this version)
Thanks for the previous fix in PR #41! It works perfectly when no paths
key is defined in tsconfig.
But actually I think that const { baseUrl = "", paths = { "*": ["*"] } } = compilerOptions;
still doesn't cover all the cases. Here is another example which makes the TS compiler totally happy, but ttsc (with this plugin) doesn't resolve paths in the compiled output:
{
"compilerOptions": {
"paths": {
"shared/*": ["../../shared/src/*"]
}
}
}
Adding a dummy "*": ["*"]
here helps again:
{
"compilerOptions": {
"paths": {
"*": ["*"],
"shared/*": ["../../shared/src/*"]
}
}
}
Looks like the full fix would be to search for "*" occurrence in compilerOptions.paths and, if it's there, add "*"
as the last option (if it's not there yet). If it's not there, add the dummy paths
key as it's done in the current PR #41.
I'm seeing something really strange that I can't reproduce in a the MVCE that I created earlier, so I'm just reporting it in case I'm triggering some sort of edge case.
I'm exporting an IDistribution
interface from a module like this:
export { IDistribution } from "@fs/distributions";
export { sales } from "@fs/sales";
export { variance } from "@fs/statistics";
...
Everything exports fine and shows up in the compiled index.d.ts
except for the IDistribution
. Now if I change the IDistribution
export to resolve from a local path ./distributions
then it works.
So really strange. I've tried all sorts of monkeying around with it like deleting all the exports except for that one export, and none of it works. I also tried examining the same type of scenario in the MVCE and it works there ... so odd. Anyways just wanted to put it on the radar in case anyone else comes across something similar in the future. It's not a deal breaker or anything, since I can just use a local path for that one item.
Cheers,
Ole
I have success with tsconfig.json paths:
"vue": ["https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.esm.browser.js"]
path is transformed to import from 'url...'
but if I use (for fixing vue-class-component.esm.js import vue from 'vue'
to import vue from 'url...'
resolving es6 modules without importmap)
"vue-class-component": ["../dist/vue-class-component.esm.js"],
nothing happens with import from 'vue-class-component'
# src/page.ts
import(/* webpackChunkName: "Some" */ "../pages/Some")
Without typescript-transform-paths, this correctly transpiles to the exactly same JS code, the comments remained.
With typescript-transform-paths, it transpiles to:
# dist/page.js
import("../pages/Some")
I.e. the plugin removes comments even when removeComments=false in tsconfig.json's compilerOptions.
This issue doesn't allow to use custom chunk names when e.g. using webpack to bundle the content of dist/ folder (which webpack does way way faster than ts-loader, especially in monorepo- composite- projects).
Hi.
I'll try to explain the issue I'm facing...
In TS 4.x, they started addressing different monorepo related feature requests and issues. For instance, they implemented "IntelliSense auto-import mapping customization" which allows people to auto-import modules from other project's dist/ folders (not from their src/ folders) and thus dramatically improve the compilation speed (because the generated *.d.ts files can be omitted in typechecking with skipLibCheck=true, and in general, they are way more lightweight than *.ts files).
Here is an example of one of the configurations:
I'm also showing a screenshot of a sandbox project to illustrate, what's going on.
In a monorepo setup (e.g. lerna or yarn workspaces), for each project in packages/, lerna/yarn create a symlink in the top-level node_modules. It lets people import from other monorepo projects as if they're importing from a regular node_modules module downloaded from npmjs (although the module itself lives in packages/).
In TS 4.x, paths
is also used to tell TSC, what should IntelliSense auto-import when a symbol is found. I.e. on the screenshot above, TS recognizes that there is a Dinosaur
symbol in packages/shared/src/Dinosaur.ts file, and when suggesting an auto-import, it traverses it back to paths
key, and finally it proposes to import it from shared/dist/Dinosaur
module (which is in another monorepo project) - nice and clean. Also, TS is smart enough to prefer using .d.ts files in such cases under the hood (speed gain) and not include src/.ts (although src/ is mentioned in paths
) - this is due to -b
flag and composite=true.
The problem is that typescript-transform-paths also tries to resolve such a path, and in the generated *.js file, we see ../../shared/src/Dinosaur.js
reference - which is wrong, the JS file should be included from node_modules/shared/dist/Dinosaur.js (i.e. we should let Node or other runtime resolve an absolute module path according to the standard node_module rules).
And here comes the proposal. If typescript-transform-paths detects a path which looks like relative to node_modules folder, it would be cool if it just didn't touch it and live it as it is. Because if someone imports from a module in node_modules, they don't want any path translation for sure.
What's challenging here is how to detect if some path is about a node_modules module or not. I don't have a good answer to this... maybe allow configuring the list of exclusions which are never translated (I would then be able to pass "shared" in this list and disable path translation for it). I.e. it's about ignoring of some of entries in paths
.
Unfortunately I also can't do this:
Because if I do, then IntelliSense will open a wrong path (inside node_modules and not in src/) on Cmd+Click.
The plugin treats the paths in the tsconfig as gospel for adjusting the resolution path. It should instead use it as the primary search folder for determining where the module is located before falling back to the default module resolution strategies.
tsconfig:
"baseUrl": ".",
"paths": {
"*": ["*"]
},
foo/IFoo
export interface IFoo {}
foo/File2
import {IFoo} from './IFoo';
The plugin to not transform the relative imports (since they aren't available of the root). Paths should be performed first and only applied if the module can be loaded from that location. Then it should fallback to the module resolution strategy defined for the project https://www.typescriptlang.org/docs/handbook/module-resolution.html#module-resolution-strategies
foo/File2.d.ts
import {IFoo} from '../IFoo';
Hi.
The library uses createLiteral()
(which is deprecated in the last TS BTW) which creates a token with parent=undefined. And other transformers (like typescript-is) may not like this: they expect parent
to always be defined.
Steps to repro:
a.ts:
import b from "b"; //
import { assertType } from "typescript-is";
interface A {
a: number;
}
console.log(b);
console.log(assertType<A>({ a: 10 }));
package.json:
{
"name": "typescript-transform-paths-bug",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"ttypescript": "*",
"typescript": "*",
"typescript-is": "*",
"typescript-transform-paths": "*"
}
}
tsconfig.json:
{
"compilerOptions": {
"skipLibCheck": true,
"jsx": "react",
"moduleResolution": "node",
"experimentalDecorators": true,
"pretty": true,
"resolveJsonModule": true,
"target": "esnext",
"esModuleInterop": true,
"noImplicitReturns": true,
"strict": true,
"paths": { "*": ["*"] },
"plugins": [
{ "transform": "typescript-transform-paths" },
{ "transform": "typescript-is/lib/transform-inline/transformer" },
],
"rootDir": "src",
"outDir": "dist",
"baseUrl": "src"
}
}
It crashes TS with the following error:
Caused By: TypeError: Cannot read property 'kind' of undefined
at Object.isImportDeclaration (node_modules/typescript/lib/typescript.js:26795:21)
- or -
Caused By: Error: start < 0
at createTextSpan
I printed what's in the original node.moduleSpecifier
and what's in p
here: https://github.com/LeDDGroup/typescript-transform-paths/blob/master/src/index.ts#L228 - and here is the result:
If I manually set p.parent = node.moduleSpecifier.parent
prior to calling Object.assign(), the crash disappears (but only for some cases).
Potential solution
I think that createLiteral() creates a "too raw" literal; the screenshot above shows that the properties of the "original" moduleSpecifier is very different from the new one (e.g. parent
, pos
, flags
etc.). I tried to use factory.cloneNode()
, but it's not for these purposes and didn't work, there must be something else to replace string literals in the code inplace.
P.S.
I think this topic is related to typescript-transform-paths and not to e.g. typescript-is, because it's typescript-transform-paths who generates a "slightly non native" AST. Thus, other transformers which reasonably expect to receive a "native" AST will break.
I have code which compiles without issue using tsc
and used to work fine with ttsc
and in Rollup with the ttypscript
replacement and using the "typescript-transform-paths" plugin.
For context, my tsconfig.json
file is:
{
"compilerOptions": {
"declaration": false,
"module": "esnext",
"target": "es2018",
"lib": ["es2015.reflect", "DOM"],
"moduleResolution": "node",
"sourceMap": true,
"noImplicitAny": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"noEmit": true,
"removeComments": false,
"strictNullChecks": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"plugins": [
{ "transform": "typescript-transform-paths" },
{ "transform": "typescript-transform-paths", "afterDeclarations": true }
]
},
"include": ["src"]
}
This same repo and tsconfig used to compile but after updating a number of requirements (including Typescript to 4.1.3) it now fails with:
Error: Debug Failure. False expression: Node must have a real position for this operation
at NodeObject.assertHasRealPosition (/Volumes/Coding/forest-fire/vuex-plugin-firemodel/node_modules/typescript/lib/typescript.js:146074:22)
at NodeObject.getFullText (/Volumes/Coding/forest-fire/vuex-plugin-firemodel/node_modules/typescript/lib/typescript.js:146104:18)
at getStatementTags (/Volumes/Coding/forest-fire/vuex-plugin-firemodel/node_modules/typescript-transform-paths/dist/utils/resolve-path-update-node.js:96:35)
at Object.resolvePathAndUpdateNode (/Volumes/Coding/forest-fire/vuex-plugin-firemodel/node_modules/typescript-transform-paths/dist/utils/resolve-path-update-node.js:17:18)
at Object.nodeVisitor (/Volumes/Coding/forest-fire/vuex-plugin-firemodel/node_modules/typescript-transform-paths/dist/visitor.js:76:24)
at visitNodes (/Volumes/Coding/forest-fire/vuex-plugin-firemodel/node_modules/typescript/lib/typescript.js:80382:48)
I have gone into Typescript's code and added code to pull out more information as I was completely confused by the message. When I hit an error condition, I now get a dump of the node's context which looks like this:
NodeObject {
pos: -1,
end: -1,
flags: 8,
modifierFlagsCache: 0,
transformFlags: 1,
parent: undefined,
kind: 195,
argument: NodeObject {
pos: -1,
end: -1,
flags: 8,
modifierFlagsCache: 0,
transformFlags: 1,
parent: undefined,
kind: 191,
literal: TokenObject {
pos: -1,
end: -1,
flags: 8,
modifierFlagsCache: 0,
transformFlags: 0,
parent: undefined,
kind: 10,
text: '@firebase/auth-types',
singleQuote: undefined,
hasExtendedUnicodeEscape: undefined
}
},
qualifier: IdentifierObject {
pos: -1,
end: -1,
flags: 8,
modifierFlagsCache: 0,
transformFlags: 0,
parent: undefined,
kind: 78,
originalKeywordKind: undefined,
escapedText: 'FirebaseAuth',
emitNode: { flags: 16777216 },
symbol: SymbolObject {
flags: 32,
escapedName: 'FirebaseAuth',
declarations: [Array],
exports: [Map],
members: [Map],
valueDeclaration: [NodeObject],
parent: [SymbolObject],
id: 24262,
isReferenced: 788968
},
typeArguments: undefined
},
typeArguments: undefined,
isTypeOf: false,
jsDocCache: []
}
With my someone low resolution understanding this seems to suggest it's taking some issue with the FirebaseAuth
symbol which is being imported from a package that does indeed export the given symbol but considering this repo hasn't changed at all i'm surprised its not working. Further, if I go into the assertion in Typescript's NodeObject.assertHasRealPosition
and just remove the assertion, it goes back to transpiling successfully.
Running this plugin on Window produce paths like ..\\..\\utils
instead of ../../utils
.
This is because node use environment specific path.
I recommend using something like slash to convert the path to posix path.
typescript-transform-paths/src/index.ts
Line 28 in de7d3d8
Example
./index.ts
import { v1 } from "#path/b" // Resolves to ./a.ts
import { v2 } from "#path/a" // Resolves to ./dir2/b.ts
export { v1, v2 }
./tsconfig.json
{
"compilerOptions": {
// ...
"baseUrl": ".",
"paths": {
"#path/*": [ "./*", "./dir2/*" ]
},
"plugins": [
{
"transform": "typescript-transform-paths"
}
]
}
}
Output: index.js
(I used ESNext for readability, but happens with CommonJS as well)
import { gg } from "#path/b"; // Does not transform because it's the second path in the array
import { ga } from "./a";
export { gg, ga };
Hi - Nice work!
I'm considering putting it to use in:
https://www.npmjs.com/package/@fireflysemantics/slice
Right now I'm creating a dist folder with *.d.ts files and *.js files. I see that typescript-transform-paths converts the *.js files, but the paths still appear in the *.d.ts files. Is there a setting that will convert the *.d.ts files as well?
Also right now in the root of the Slice project I have a createdist.js
script that performs the path conversion. It uses globby to find the resources and replaces the path
configured proxies with relative paths.
I tried configuring typescript-transform-paths
and running npm compile
(Which compiles to the target
directory, but it does not look like the paths are being replaced. Any ideas?
As soon as I have all imports in the public/
folder defined to be transformed does it no longer work. Means tsc
isn't able to give out any result.
See: aragon/govern#77
Hi
likely my mistake, but I did not get it to work.
I have the following configuration (just keep relevant fields)
{
"include": [
"../../eikon-framework/src/**/*.ts"
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"df-core/*": ["./build/df-core/*"],
"*": [
"./node_modules/*",
"./node_modules/@types/*"
]
},
"rootDir": "../../eikon-framework/src",
"outDir": "./build/eikon-framework"
}
}
I have the following file:
../../src/eikon-framework/src/auth/auth-impl.ts
import { GetElectronEnvironment } from 'df-core/env';
after the compilation in the outDir folder I have
[outDir]/eikon-framework/auth/auth-impl.js
const env_1 = require("../../../products/workspace/build/df-core/env/index");
It seems the resolution has been done from the original location of TS file and not from the output location of JS file.
With "df-core/": ["./build/df-core/"] and outDir = ./build/eikon-framework/auth/auth-impl.js
I would expect
const env_1 = require("../../df-core/env/index");
Could you help me please
Thanks
Sorry but I open this issue just to say: thanks for your work and this package.
Hi,
I started work on a project with Papaparse included and when I run the build it does perform the conversions, but includes the following compile errors:
ole@mki:~/Temp/typescript-path-transform-demo$ npm run compile
> [email protected] compile /home/ole/Temp/typescript-path-transform-demo
> del-cli target && ttsc
node_modules/@types/papaparse/index.d.ts:23:29 - error TS2304: Cannot find name 'File'.
23 export function parse(file: File, config?: ParseConfig): ParseResult;
~~~~
node_modules/@types/papaparse/index.d.ts:112:44 - error TS2304: Cannot find name 'File'.
112 complete?(results: ParseResult, file?: File): void; // default: undefined
~~~~
node_modules/@types/papaparse/index.d.ts:113:38 - error TS2304: Cannot find name 'File'.
113 error?(error: ParseError, file?: File): void; // default: undefined
~~~~
Found 3 errors.
I created a demo project here. Thoughts?
[email protected]
[email protected]
typescript-transform-paths/lib/index.js:106
return updaterFn(typescript_1.default.createLiteral(p));
^
TypeError: typescript_1.default.updateNode is not a function
Basically, the question. Node-level solutions I've seen (tsconfig-paths, module-alias) only work on the current project, but not referenced ones that are transitively compiled using tsc --build
.
For reference:
https://www.typescriptlang.org/docs/handbook/project-references.html
I've been struggling with the generated declaration files paths not being transformed to relative paths and I was using i.e import type { Type } from '@/common/types'
.
I removed all import type {}
and replaced with the standard import { Type } from '@/common/types'
and it transformed correctly in the declaration files, so there seems to be a problem resolving the import type
syntax π€
Hi, this plugin stopped working after upgrading from 1.1.14 to 2.0.1.
Here's my config.
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": [
"ES2020",
"ESNext",
"ES7",
"ES6"
],
"outDir": "./prod",
"skipLibCheck": true,
"noImplicitAny": true,
"baseUrl": "./src",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"plugins": [
{
"transform": "typescript-transform-paths"
}
]
},
"include": [
"src"
]
}
I use it with ttsc (ttypescript).
Wrote up a blog post with MVCE example from the last issue showing how to put the plugin to use. Thanks again for this awesome plugin!
I have a monorepo setup with a package that contains React Native components. The naming convention for React Native files is to have .native
in the extension, for example utils.native.ts
.
Import paths referring to files with multiple .
extensions do not get transformed into relative paths.
This will break the compatibility of esmodule, and inconsistent with tsc
There are 4 files in totalοΌ
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"outDir": "./dist/",
"strict": true,
"baseUrl": "./",
"paths": {
"@shared/*": [
"src/shared/*"
]
},
"esModuleInterop": true,
"plugins": [
// {
// "transform": "typescript-transform-paths"
// }
],
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
// src/index.ts
import { value } from './value.js'; // <-- './value.js' is not an error
console.log(value);
// src/value.ts
export const value = 12;
<!-- index.html -->
<body>
<script src="dist/index.js" type="module"></script>
</body>
typescript-transform-paths
typescript-transform-paths
The library is correctly changing paths in normal js files, however after compilation .d.ts files still have custom paths in names
Update: #4 (comment)
Sorry I did not find it before creating a new issue
Description
Using "resolveJsonModule": true
in tsconfig.json
results in import error after compilation.
The reason is that the .json
extension is removed.
Expected Behavior
import data from './src/data.json'
=> import data from './src/data.json'
import data from '@src/data.json'
=> import data from './src/data.json'
Actual Behavior
import data from './src/data.json'
=> import data from './src/data'
import data from '@src/data.json'
=> import data from './src/data'
Version
ββ [email protected]
ββ [email protected]
ββ [email protected]
Config
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"baseUrl": ".",
"paths": {
"@*": ["src/*"]
},
"plugins": [
{ "transform": "typescript-transform-paths" },
{ "transform": "typescript-transform-paths", "afterDeclarations": true }
]
},
"files": ["src/index.ts"]
}
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html
Hey, i'm using the dynamic import if i'm only importing a type, to prevent import cycles.
But it seems, that these import aliases won't get transformed.
declare type QuestionModel = import('@/models/Question/model').QuestionModel;
Just stays the same, the other, es6-style imports are transformed just fine.
I create an repository for the bug.
https://github.com/joshuaavalon/typescript-transform-paths-bug
After npm run build
, lib\foo\index.js
has
const a_1 = require("..\\a");
but lib\foo\index.d.ts
has
import { A } from "@/a";
export declare type B = {
b: A;
};
Edit:
{ "transform": "typescript-transform-paths", "afterDeclarations": true }
It transforms *.d.ts but it does not tranform .js
Any files emitted at the root of ./dist/*.js
do not include the ./
path at the beginning of modules.
tsconfig.json
{
"baseUrl": ".",
"outDir": "dist",
"target": "es5",
"paths": {
"@/*": ["src/*"]
},
"plugins": [
{ "transform": "typescript-transform-paths" },
]
}
Currently ./dist/index.js
looks like:
var http = require("adapters/http");
When it should be:
var http = require("./adapters/http");
In cases where a custom instance of ts is used (one which differs from what resolves from require('typescript')), the plugin uses the local copy. This can cause various issues.
A transformer should always use the version passed to it by ttypescript
or ts-patch
Note: I have this fixed and will be submitting a PR which closes this and other open issues shortly
tsconfig.base.json compilerOptions:
"paths": {
"vue": ["https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"]
}
subfolder/tsconfig.json:
"extends": "../tsconfig.base.json",
"compilerOptions": {
"baseUrl": ".",
"plugins": [{ "transform": "typescript-transform-paths" }]
}
ttsc generated module file:
import Vue from "../https:/cdn.jsdelivr.net/npm/[email protected]/dist/vue.js";
This is related to #9 (and associated PR #10).
It seems like (for versions > v1.1.0) typescript-transform-paths erases type information from declaration files which is a problem when you're trying to create a library that exposes functions that use that type information. I created a simple repo to show this: https://github.com/travigd/ts-transform-paths-bug-repro
Short version, index.ts
is
import {Foo, logFoo} from "@/foo";
export function bar(f: Foo) {
logFoo(f);
}
The resulting index.d.ts
for recent versions (this is in the dist-bug
directory in that repo) is
export declare function bar(f: Foo): void;
For older versions (I specifically install v1.1.0 since it was released before #10), I get this (which is correct for the declarations file):
import { Foo } from "./foo";
export declare function bar(f: Foo): void;
Hi, thanks for this excellent plugin.
Unfortunately something seems to have stopped working (for me at least) in v1.1.2.
I've played around with incremental updates and believe the issue is in 73dd832 / "fix: type only import not deleted from result file"
Specifically this change:
My paths are set as follows:
"paths": {
"me/*": ["src/*"]
},
An import looks like:
import { FooViewModel } from "me/viewModels/fooViewModel";
For now I can just use 1.1.0. Please let me know if there's any further info I can provide.
I typically have index.ts with content:
export * from '@/A';
export * from '@/B';
This syntax does not work with your transformer.
Original Code:
// myfile.ts
import { Middleware } from 'koa'
import { Permissions } from './permission'
import { PermissionManager } from '@/permission-manager'
import { DefaultPermissions } from '@/default'
[email protected]/2.0.4
is working:
// myfile.d.ts
import { Middleware } from 'koa';
import { Permissions } from "./permission";
import { PermissionManager } from "./index";
import { DefaultPermissions } from "../default";
[email protected]/1.1.15
isn't working:
// myfile.d.ts
import { Middleware } from 'koa';
import { Permissions } from './permission';
import { PermissionManager } from '@/permission-manager';
import { DefaultPermissions } from '@/default';
My tsconfig.json
:
{
"compilerOptions": {
"outDir": "./lib",
"moduleResolution": "node",
"module": "commonjs",
"target": "ESNext",
"strict": true,
"noImplicitAny": false,
"declaration": true,
"resolveJsonModule": true,
"baseUrl": "./",
"noEmitOnError": true,
"paths": {
"@/*": ["src/*"],
"@root/*": ["./*"]
},
"plugins": [{ "transform": "typescript-transform-paths" }]
},
"exclude": ["node_modules"],
"files": ["index.ts"],
"include": ["src/**/*.ts"]
}
Test in typescript@3
And typescript@4
The bug can only be found in .d.ts
.
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": ["ES2015"],
"outDir": "lib",
"strict": true,
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"@@/*": ["./*"], // root alias
"@/*": ["./src/*"], // src alias
},
"plugins": [{ "transform": "typescript-transform-paths" }],
"pretty": true,
"esModuleInterop": true,
// "resolveJsonModule": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"removeComments": true
},
"include": ["src/**/*", "typings.d.ts","package.json"],
"exclude": [
"node_modules",
"**/test/*",
"__test__",
"**/*.spec.ts",
"lib",
"es",
"dist",
"build"
]
}
Some import and export declarations get improperly elided.
Example:
export * as name from 'module'
The elision logic should be updated to only process if named bindings are present in the import / export clause
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.