benyap / resolve-tspaths Goto Github PK
View Code? Open in Web Editor NEWTransform path mappings in your compiled Typescript code
Home Page: https://www.npmjs.com/package/resolve-tspaths
License: MIT License
Transform path mappings in your compiled Typescript code
Home Page: https://www.npmjs.com/package/resolve-tspaths
License: MIT License
I have a TS project that requires shared files with another project.
Running the module just deletes all of my files in this folder in my other project.
tsconfig paths:
"paths": { "@models/*": ["../Backend/src/shared/database/models/*"] }
baseUrl
is an optional field, even when paths
option is specified (microsoft/TypeScript#31869).
Currently, resolve-tspaths
returns this when baseUrl
is not provided:
Error during step 'resolvePaths'
compilerOptions.baseUrl is not set in tsconfig
Hi, we're migrating our codebase from Node 18 to 20 and one of the challenges is that Node 20 needs explicit import specifiers. I'm shopping around for a build step that resolves all paths to their explicit paths including relative imports and node_module imports.
From what I can tell, this package does what I need but only for imports that go through the absolute paths
in tsconfig. Any chance of this package expanding this to resolve relative + node_modules imports as well, including resolving folder imports to their index-file?
If not, do you know of any package that does this?
After running tsc to compile my app, the dist/app.js
imports look like this:
var calendar_edits_1 = __importDefault(require("@/routes/calendar-edits"));
var v2_1 = __importDefault(require("@/routes/calendar/v2"));
// import chatMessagesRoutes from "@/routes/chat-messages";
// import chatsRoutes from "@/routes/chats";
var client_meta_1 = __importDefault(require("@/routes/client-meta"));
var client_options_1 = __importDefault(require("@/routes/client-options"));
After running resolve-tspaths
, I get:
var calendar_edits_1 = __importDefault(require("@/routes/calendar-edits"));
var v2_1 = __importDefault(require("@/routes/calendar/v2"));
// import chatMessagesRoutes from "./routes/chat-messages.js";
// import chatsRoutes from "./routes/chats.js";
var client_meta_1 = __importDefault(require("./routes/client-meta"));
var client_options_1 = __importDefault(require("./routes/client-options"));
As you can see, for some reason it only transpiles the bottom-half of the imports list.
If i REMOVE the two commented imports:
var calendar_1 = __importDefault(require("@/routes/calendar"));
var v2_1 = __importDefault(require("@/routes/calendar/v2"));
var client_meta_1 = __importDefault(require("@/routes/client-meta"));
var client_options_1 = __importDefault(require("@/routes/client-options"));
then run resolve-tspaths
, I get:
var calendar_edits_1 = __importDefault(require("./routes/calendar-edits"));
var v2_1 = __importDefault(require("./routes/calendar/v2"));
var client_meta_1 = __importDefault(require("./routes/client-meta"));
var client_options_1 = __importDefault(require("./routes/client-options"));
Which is now correct, as all of the imports are changed. I was struggling to figure out why suddenly my builds were failing when none of my build process had changed, and this seems to be the culprit
I am not sure if this is a bug, something I overlooked in the documentation or an incorrect tsconfig configuration, but the situation is this. We have a typescript based project that consumes, via npm, a library of common components that we also maintain. We added resolve-tspaths to the component library. The projects that import the component library as a dependency recognize the aliases and run fine, but every jest test that involves an aliased component from the component library fails with an error like this:
Cannot find module 'hooks' from 'node_modules/@dmgtech/cc-shared/lib/cjs/components/InputField/styles.js'
package.json scripts used to build component library is this:
I assumed the problem was the build:cjs script so I tried this but got "changed 0 files"
To sum up, and restate the problem, the tests of the projects that use our aliased component library as a dependency are failing, and they are failing because the aliases in the component library are not getting mapped in the cjs files. My feeling is this is probably a configuration issue and not a bug, but any assistance you could provide would be greatly appreciated.
Running into an issue when resolving a file that has a sibling directory of the same name.
Example repo: https://github.com/ForestBeaver/replace-ts-paths-same-name-example
npm install
npm run build
cat dist/controller/a.js
npm run replace
cat dist/controller/a.js
node dist/index.js
When reexporting a style sheet from a typescript file, with a file extension of .scss?inline
, running resolve-tspaths
does not update the dynamic imports in the relevant type definition file.
import SelectField from "@/api/component.input/select-field/select-field.vue";
import { FormComponentWrapper } from "@/api/form-builder/core/component-wrapper";
export { SelectField, SelectField as default };
export const FormSelectField = FormComponentWrapper(SelectField);
import SelectFieldStyles from "./select-field.module.scss?inline";
export { SelectFieldStyles };
import SelectField from "./select-field.vue";
export { SelectField, SelectField as default };
export declare const FormSelectField: <Data>(options?: Omit<import("@/api/form-builder/core/component-wrapper").FormBuilderComponentOptions<import("vue").DefineComponent<{
Hi
First of all, thank you for your efforts. Working with tsconfig paths is very frustrating and your module is the closest one to work for me, out of 5 different ones I had to try.
But in order to compile to ES modules, we have to use relative paths, including a .js
extension.
Imagine I have two files:
src/
├ compiler/
│ └ index.ts
└ bin/
└ index.ts
And a tsconfig.json
like the following:
{
"compilerOptions": {
"module": "ESNext",
"baseUrl": ".",
"paths": {
"compiler/*": ["src/compiler/*"],
}
}
}
If I have an import like this
// src/bin/index.ts
import { compile } from "compiler/index.js"; // actual file is src/compiler/index.ts
It should resolve to this:
// src/bin/index.ts
import { compile } from "../compiler/index.js";
Basically we have to import the file with a .js
extension, even though the actual file has a .ts
extension.
This currently does not work because of the existsSync()
check in generateChanges.ts
, which adds ext
to the modulePath
that already has the .js
extension from the import.
resolve-tspaths/src/steps/generateChanges.ts
Line 143 in 5754ef5
Furthermore the file extension currently gets removed in the replaced path but the file extension should stay as it is in the original import.
Hello!
Just to let you know that I randomly tried your utility (according to your readme, it should serve as a replacement for tsc-alias), and unfortunately it didn't work ("build": "tsc && resolve-tspaths"
in package.json
) ended with the following output:
resolve-tspaths: changed 0 file(s)
My config is:
{
"extends": "_my_base_tsconfig_",
"compilerOptions": {
"incremental": true,
"paths": {
"@/Const": ["./src/Const/index.js"],
"@/Types": ["./src/Types/index.js"],
"@/Utils": ["./src/Utils/index.js"],
"@/Tests": ["./src/Tests/index.js"],
"@/*": ["./src/*"]
}
}
}
Same on the fresh new project with this tsconfig
:
{
"compilerOptions": {
"target": "ESNext",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"allowJs": true,
"outDir": "build",
"rootDirs": ["src"],
"strict": true,
"noImplicitAny": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"baseUrl": ".",
"removeComments": false,
"plugins": [
{
"transform": "typia/lib/transform"
}
],
"paths": {
"@/Types": ["./src/Types/index.js"],
"@/Modules": ["./src/Modules/index.js"],
"@/Constants": ["./src/Constants/index.js"],
"@/Utils": ["./src/Utils/index.js"],
"@/*": ["./src/*"],
"#/utils": ["./tests/utils/index.js"],
"#/*": ["./tests/*"]
},
"strictNullChecks": true
},
"include": ["src"],
"exclude": ["node_modules"]
}
I have no idea why it doesn't work and hope this issue helps you to debug the problem.
Also, if possible, please highlight in the readme how your tool is different from tsc-alias, which works really well for all of my projects.
When I was using resolve-tspaths
, I had my baseUrl set to src
. This produced filepaths like absolute\path\src\src\app\config
, where the src
directory gets incorrectly doubled in the filepath. Digging deeper, I found that the aliases were being stored relative to the baseUrl (ie. src\app\controllers\*
). However, when actually used, they were added to baseUrl file path (ie. absolute\path\src
).
I'm using aliases in require.resolve
statements. Previously I was using a Babel plugin to resolve my paths, but I switched to SWC and now I'd like to use your package to fix paths after compilation. However, require.resolve
is not supported.
Is there a way to run this in watch mode?
Currently, resolve-tspaths
resolves import paths for compiled JavaScript files, resulting in import paths with an extension E.g. .js
. However, it would be helpful to also resolve import paths for TypeScript files (.ts
and .tsx
).
This feature would be particularly useful for libraries designed for use with react-native
.
// package.json
{
"main": "lib/commonjs/index",
"module": "lib/module/index",
"types": "lib/typescript/index.d.ts",
"source": "lib/src/index", 👈
"react-native": "lib/src/index" 👈
}
await resolveTsPaths({ out: outPath, ext: ['ts', 'tsx'] });
.js
extension, which can result in a runtime error:import { styles } from '../../styles.js';
Hi,
thanks for your package. It's a shame tsc
doesn't compile its resolution behavior.
In my scenario, I generated JSON files from my TypeScript code (JSON schema from types).
In order to avoid import errors, I configured my path mappings so that JSON are preferred over source files:
{
"compilerOptions": {
"rootDir": "src/",
"baseUrl": "src/",
"outDir": "dist/",
"paths": {
"~/*": ["./*"],
"@schema/*": ["./schema/*.json", "./schema/*"],
},
}
}
The files are structured like this:
src/schema/
├── a.json
└── a.ts
and an import like this: import { definitions } from "@schema/a"
.
This setup works fine with TypeScript. Since I think this package aims to mimic TypeScript's resolution mechanism, just at compile time, I think, this setup should also work with your package.
The JSON file is not resolved. Instead the compiled JS file is resolved.
At first I thought, the reason is that I used --ext
incorrectly. But after some debugging, I found that the import is resolved to .../src/schema/*.json/a
and then disregarded. This result is produced by https://github.com/benyap/resolve-tspaths/blob/main/src/steps/generateChanges.ts#L143
resolve(aliasPath, importSpecifier.replace(prefix, ""))
In my understand, this code assumes that all aliasPaths
are pointing to directories, which is not necessarily true (as described above). I guess replacing "*"
in the path instead of appending to it (in case the alias is not a directory), could solve this issue.
(aliasPath) => isDirectory(aliasPath)
? resolve(aliasPath, importSpecifier.replace(prefix, ""))
: aliasPath.replace("*", importSpecifier.replace(prefix, ""))
Let me know what you think. 😉
I am using yarn workspaces for my project and some of my one of my workspaces imports from other work workspaces outside its root directory.
the relevant parts of my tsconfig
look like this:
"outDir": "./build",
"paths": {
"@app/db": ["../db"],
"@app/db/*": ["../db/*"],
"@app/redis": ["../redis"],
"@app/redis/*": ["../redis/*"],
"@app/emitter": ["../emitter"],
"@app/emitter/*": ["../emitter/*"],
"@app/dayjs": ["../dayjs"],
"@app/dayjs/*": ["../dayjs/*"],
"@app/utils": ["../utils"],
"@app/utils/*": ["../utils"],
"@app/values": ["../values"],
"@app/values/*": ["../values/*"]
},
with this config it transforms:
require("@app/redis");
to
require("../../../redis"); // seems to still think outside the outDir is the root
I am expecting it to be:
require("../redis"); // treating outDir (/build) as the new root
Currently the only package i've gotten to resolve paths as i expect is ts-alias but that has a bug and which idk if i'll be solved soon
I'm getting
Error during step 'loadTSConfig'
Error processing ...\tsconfig.json: Failed to parse JSON. Unexpected token } in JSON at position 771
when I run resolve-tspaths.
Here is the tsconfig I'm using (I'm passing in tsconfig.build.json
to resolve-tspaths
):
tsconfig.build.json
{
"extends": "./tsconfig.json",
"exclude": [
"**/*.spec.ts",
"**/*.fixture.ts",
"/tests"
]
}
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"baseUrl": "src",
"paths": {
"*": [
"../node_modules/*"
],
"@app/*": [ "app/*" ],
"@config/*": [ "app/config/*" ],
"@models/*": [ "app/models/*" ],
"@utils/*": [ "app/utils/*" ],
"@routes/*": [ "app/routes/*" ],
"@controllers/*": [ "app/controllers/*" ],
"@middlewares/*": [ "app/middlewares/*" ],
"@init/*": [ "app/init/*" ],
"@tests/*": [ "tests/*" ]
},
/* Advanced Options */
"plugins": [
{ "transform": "typescript-is/lib/transform-inline/transformer" },
{ "transform": "ts-transformer-keys/transformer" }
],
},
"include": [
"**/*"
]
}
I have the following tsconfig:
{
"compilerOptions": {
"target": "ES6",
"module": "ESNext",
"lib": ["ES6"],
"moduleResolution": "Node",
"rootDir": "./src",
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@tools/*": ["src/tools/*"],
"@types/*": ["src/types/*"],
"@server/*": ["src/server/*"],
"@routes/*": ["src/routes/*"],
"@models/*": ["src/models/*"],
"@schemas/*": ["src/schemas/*"],
"@constants/*": ["src/constants/*"],
"@middlewares/*": ["src/middlewares/*"]
},
"declaration": true,
"outDir": "./dist",
"removeComments": true,
"declarationDir": "./@types",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"strictPropertyInitialization": false,
"typeRoots": ["./src/@types"]
},
"exclude": ["./@types", "node_modules"],
"include": ["./src/**/*"]
}
My entry file is located inside src/main.ts
inside this file I have some imports, them I have the following line:
import "@tools/polyfills.js"
after building the project and running resolve-tspaths
, it resolves all the imports that have the @
successfully, and I can see that in the dist/
folder, but only this unnamed import import "@tools/polyfills.js"
is kept unresolved.
Hello, resolve-tscpaths
seems to be adding an extra ../
to my imports. I am using the default options. Why does this happen?
{
"compilerOptions": {
"incremental": true,
"composite": true,
"target": "ESNext",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"baseUrl": "./src",
"resolveJsonModule": true,
"allowJs": false,
"outDir": "build",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"paths": {
"@utils/*": ["Utils/*"]
}
},
"include": [
"src/**/*",
"src/**/*.json",
"package.json"
]
}
📦Root
┣ 📂build
┃ ┣ 📂 src
┃ ┃ ┗📜index.js
┃ ┣ 📂 util
┃ ┃ ┗ import.ts
┣ 📂src
┃ ┣ 📜index.ts
┃ ┣ 📂 util
┃ ┃ ┗ import.ts
┣ 📜package.json
┗ 📜tsconfig.json
const import = require('../util/import.js')
const import = require('../../util/import.js')
Hey! First of all, thanks for the package.
Just a suggestion/question: Would it make sense to have an export function that we could call programmatically?
For example, this is my use case: I'm using Esbuild to transpile my TS code, and just like tsc
it doesn't "fix" the import paths (that's why I'm using this package! 😛 ) but what I can do with Esbuild, is adding hooks on the build steps, including an end hook. Here I can call resolve-tspaths
.
const resolveTsPathsPlugin = {
name: 'resolve-tspaths',
setup(build) {
build.onEnd(result => {
// `spawnSync` is used so we can be sure that the process is finished before we continue
spawnSync('yarn', ['resolve-tspaths', '--out=dist'], {
stdio: 'inherit',
})
})
},
}
export const result = await build({
outdir: 'dist',
entryPoints: ['src/**/*.ts'],
platform: 'node',
plugins: [
globPlugin(),
resolveTsPathsPlugin
],
});
Instead of relying on the spawnSync
node child process functionality, I could call the function here, for example:
import { resolve } from 'resolve-tspaths';
const resolveTsPathsPlugin = {
name: 'resolve-tspaths',
setup(build) {
build.onEnd(async result => {
await resolve({ out: 'dist' });
})
},
}
When the exported symbol contains the same string as the filename, the symbol gets replaced instead of the filename. This probably only affects projects that use no prefix for their aliases.
tsconfig.json:
{ "compilerOptions": {
"paths": {
"*": ["./src/*"]
}
}}
src/sameName.ts:
export const sameName = "something"
src/test.ts:
export { sameName } from "sameName"
The generated test.d.ts
contains
export { sameName } from "./sameName"
The generated test.d.ts
contains
export { ./sameName } from "sameName"
Hi :)
Thanks again for the tool, very useful in our project.
There is one issue with .d.ts
generated files when we use "module": "NodeNext"
with "moduleResolution": "NodeNext"
in ts config (recommended module resolution in ESM mode).
Also consider the following paths
value:
...
"paths": {
"@server/*": [ "../../../server/*" ]
}
...
With NodeNext
module resolution, .js
extension is mandatory in ts source file:
export * from '@server/types/index.js'
export * from '@server/types/models/index.js'
Generated file dist/index.d.ts
also contains the extension:
export * from '@server/types/index.js';
export * from '@server/types/models/index.js';
And so imports are not updated in dist/index.d.ts
, because resolve-tspaths
tries to find [filename].js.d.ts
and not [filename].d.ts
.
(your test uses the node
module resolution which correctly works as we don't have to specify the file extension)
Thank you!
This is similar to #311.
To reproduce, build this commit of gristlabs/grist-electron. Make sure to use Node.js version 18.
git clone https://github.com/gristlabs/grist-electron
cd grist-electron
git checkout 6673928
git submodule init
git submodule update
yarn install
yarn run setup
yarn build
yarn run electron:preview
The last command should give the following error:
Error: Cannot find module 'app/common/gutil'
This is because resolve-tspaths failed to expand the import properly.
To take a closer look, go to core/_build/ext/app/electron/main.js
. This file is compiled from ext/app/electron/main.ts
. On line 38, there is a word "import" in the comments. All imports after that line will not be correctly expanded by resolve-tspaths. The problem goes away if the word "import" is removed.
The minimal commands to see the problem are tsc --build tsconfig-ext.json
, then resolve-tspaths
in the core
directory. You need to make core/ext
point to ext
in the grist-electron root before doing this.
Hi there! Thank you for maintaining this library. My colleagues and I recently stumbled onto a bug that left us scratching our heads for a while, until we figured out the specific reason our build process was failing for only one person on the team.
We concluded that resolve-tspaths
just doesn't handle paths with special characters well.
To reproduce this, have a path such as:
/home/user/Projects/MyProject (MP)/tsconfig.json
Then running resolve-tspaths --verbose
in that directory. This will result in resolve-tspaths
detecting no files to process, even though there are such files. We saw that filesToProcess
from the --verbose
output was just empty in this case. The fix for us was simply changing the path to something like:
/home/user/Projects/MyProject/tsconfig.json
Which works perfectly fine! Spaces didn't seem to be an issue in my tests.
Thanks again, and don't hesitate to reach out if you need further reproduction steps.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
Warning
These dependencies are deprecated:
Datasource | Name | Replacement PR? |
---|---|---|
npm | @vitest/coverage-c8 |
These updates are currently rate-limited. Click on a checkbox below to force their creation now.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@commitlint/cli
, @commitlint/config-conventional
)@commitlint/cli
, @commitlint/config-conventional
).github/workflows/publish.yml
actions/checkout v4
actions/setup-node v3
pnpm/action-setup v2.4.0
actions/cache v3
actions/github-script v6
.github/workflows/stale.yml
actions/stale v8
package.json
ansi-colors 4.1.3
commander 12.0.0
fast-glob 3.3.2
@commitlint/cli 18.0.0
@commitlint/config-conventional 18.0.0
@release-it/bumper 6.0.1
@release-it/conventional-changelog 8.0.1
@types/node 20.12.12
@vitest/coverage-c8 0.33.0
husky 9.0.11
prettier 3.2.5
release-it 17.2.1
rimraf 5.0.7
ts-node 10.9.2
tsconfig-paths 4.2.0
typescript 5.4.5
vite 5.2.11
vitest 1.6.0
typescript >=3.0.3
pnpm 8.9.2
Hi,
resolve-tspaths correctly handles tsconfig extends
, but does not resolve compilerOptions.paths
from tsconfig where it was defined. It means that paths
are resolved from the main tsconfig file resulting in invalid path resolution.
IT might be good if resolve-tspaths continue resolving the paths
Pass the following file through resolve-tspaths
and observe. The import line does not get changed.
import {
multi,
line,
} from '~/multiline';
const m = {
multi,
line,
};
require("../..")
becomes require("../../../../..")
Try to rerun resolve-tspaths
multiple times on the same files.
It seems that extends
field in tsconfig.json is not supported. Any plan for it?
Hello,
I'm trying to use resolve-tspaths in a mono-repo but it seems that the extends in tsconfig is not supported.
Here is an example repo where you can see the problem: example project
The backend's tsconfig extends tsconfig/server.json
, which extends packages/tsconfig/server.json
which extends packages/tsconfig/base.json
.
The base.json
config contains the paths but when you run the build
command, you get an error saying that compilerOptions.paths is not set in tsconfig
...
If you copy the content of the base.json
file in backend/tsconfig.json
, then the build works perfectly...
Thanks for the help!
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.