Git Product home page Git Product logo

tsc-alias's Introduction

tsc-alias

Replace alias paths with relative paths after typescript compilation. You can add aliases that reference other projects outside your tsconfig.json project by providing a relative path to the baseUrl.

npm version License Donate

Comparison to tsconfig-paths

+ Compile time (no runtime dependencies)

Getting Started

First, install tsc-alias as devDependency using npm.

npm install -g tsc-alias
npm install --save-dev tsc-alias

Add it to your build scripts in package.json

"scripts": {
  "build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
}

================ OR ===================

"scripts": {
  "build": "tsc && tsc-alias",
  "build:watch": "tsc && (concurrently \"tsc -w\" \"tsc-alias -w\")"
}

Issues

If you have an issue, please create one. But, before:

  • try to check the FAQ.
  • try to check if there exits alike issues.
  • try to run with --debug and check if config is correctly loaded and all sourcefiles are found.

API

Installation

npm install tsc-alias

Usage

import { replaceTscAliasPaths } from 'tsc-alias';

replaceTscAliasPaths(options?);

Here are all the available options:

Option Description Default Value
project, p path to tsconfig.json 'tsconfig.json'
watch Observe file changes false
outDir Run in a folder leaving the "outDir" of the tsconfig.json (relative path to tsconfig) tsconfig.compilerOptions.outDir
declarationDir Works the same as outDir but for declarationDir tsconfig.compilerOptions.declarationDir
resolveFullPaths Attempt to replace incomplete import paths (those not ending in .js) with fully resolved paths (for ECMAScript Modules compatibility) false
resolveFullExtension Allows you to specify the extension of incomplete import paths, works with resolveFullPaths '.js' | '.mjs' | '.cjs'
silent Reduced terminal output. This is a deprecated option and no longer has any effect. true
verbose Additional information is output to the terminal false
debug Debug information is send to the terminal false
replacers Files to import as extra replacers More info []
output The output object tsc-alias will send logs to. new Output(options.verbose)
fileExtensions Overwrite file extensions tsc-alias will use to scan and resolve files. undefined

Configuration via tsconfig.json Example

{
  "compilerOptions": {
    ...
  },
  "tsc-alias": {
    "verbose": false,
    "resolveFullPaths": true,
    "replacers": {
      "exampleReplacer": {
        "enabled": true,
        "file": "./exampleReplacer.js"
      },
      "otherReplacer": {
        "enabled": true,
        "file": "./otherReplacer.js"
      }
    },
    "fileExtensions": {
      "inputGlob": "{js,jsx,mjs}",
      "outputCheck": ["js", "json", "jsx", "mjs"]
    }
  }
}

Single file replacer

We can use tsc-alias in a single file, with a function that returns the modified contents.

We prepare the replacer with prepareSingleFileReplaceTscAliasPaths(), passing the same options that we would pass to replaceTscAliasPaths(). That will return a promise of a function that receives the file contents and path, and returns the transformed contents, synchronously.

import { prepareSingleFileReplaceTscAliasPaths } from 'tsc-alias';

const runFile: SingleFileReplacer = await prepareSingleFileReplaceTscAliasPaths(options?);

function treatFile(filePath: string) {
  const fileContents = fs.readFileSync(filePath, 'utf8');
  const newContents = runFile({fileContents, filePath});
  // do stuff with newContents
}

tsc-alias's People

Contributors

adam-coster avatar alvis avatar andresmarpz avatar axmad386 avatar eturino avatar giovannini avatar izumiya avatar jaydenliang avatar jokero avatar justkey007 avatar kalvenschraut avatar ljwagerfield avatar lucky06688 avatar marneborn avatar mfmfuyu avatar mgcrea avatar misterluffy avatar nicholas-ochoa avatar p-chan avatar pfdgithub avatar raouldeheer avatar thomaswhyne avatar thundermiracle avatar troymurphy avatar viezhong avatar yifanwww avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

tsc-alias's Issues

UnhandledPromiseRejectionWarning: TypeError: replacer is not a function

// tsconfig.json
image

// tsc-alias-replacer.js
image

The code doesn't work when I upgrade the latest version.

But when I use the older version, it works.

I think there is a bug in replacers code.

image

The output is '{ default: { default: [Function] } }', I think it should be '{ default: [Function] }'

Support ts4.5

I looked at the source, and it seems straightforward to support additional extensions. In particular typescript adds support for mjs and cjs , which comes in handy for ESM.

Duplicate in path when using an alias containing '..'

Version
Bug found on 1.2.2

Description
I've got a project with that kind of architecture:

.
├── server
│   ├── build
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── src
│   └── tsconfig.json
└── shared
    ├── package.json
    ├── src
    └── tsconfig.json

with a tsconfig file having those options:

    "outDir": "build",
    "baseUrl": ".",
    "paths": {
      "@shared/*": ["./../shared/src/*"]
    },

The path having pattern .. seems to generate an import with duplicate folder shared: ../../shared/shared/src/*

Expected behaviouor
Generating an import without duplicate (../../shared/src/*)

This seems caused by a typo here: https://github.com/justkey007/tsc-alias/blob/master/src/index.ts#L135

Fail to read compilerOptions.outDir

This bug is found on v1.2.1, not v1.2.0:

I got an incorrect error saying: compilerOptions.outDir is not set.

My tsconfig:

{
  "extends": "@tsconfig/node12/tsconfig.json",
  "compilerOptions": {
    "outDir": "js",
    "baseUrl": ".",
    "paths": { "~/*": ["./*"] }
  },
  "exclude": ["node_modules", ".next"],
  "include": [
    "next-env.d.ts",
    "lib/**/*.ts",
    "utils/**/*.ts",
    "scripts/**/*.ts"
  ]
}

Seems like the new loadConfig API is working incorrectly.

`tsc --watch & tsc-alias --watch` not work

Describe the bug

tsc --watch & tsc-alias --watch not work for the first time tsc creates a file, alias is not replaced

Version Info

Node version [12.16.3]
OS version: [macOS Catalina 10.15.7]

To Reproduce

run tsc --watch & tsc-alias --watch

Expected behavior:

alias be replaced

Alias replacement failed when importing library containing alias

Issue

When using libraries starting with a "@" (like @esfx/collections-hashmap) using a tsconfig.json containing bellow config make import replacement fail with error Error: Cannot find module './esfx/collections-hashmap'

tsconfig.json

"baseUrl": "./src",
"paths": {
  "@/*": [
    "./*",
  ],
},

How to reproduce

Start test on this ### ### branch

Replaces require to npm module

Given the following typescript file...

// file: src/index.ts

import graphql from "graphql";

import typeDefs from "./graphql/typeDefs";

export { graphql, typeDefs };

with the following tsconfig...

// file: tsconfig.json

{
    "compilerOptions": {
        "baseUrl": "./src",
        "paths": {
            "~/*": ["*"]
        }
    }
}

tsc-alias modifies the imports like so:

// file: src/index.js

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.typeDefs = exports.graphql = void 0;
//!!! orig: const graphql_1 = __importDefault(require("graphql"));
const graphql_1 = __importDefault(require("./graphql"));
exports.graphql = graphql_1.default;
const typeDefs_1 = __importDefault(require("./graphql/typeDefs"));
exports.typeDefs = typeDefs_1.default;
//# sourceMappingURL=index.js.map

I guess the require('graphql') is modified because there is a folder called "graphql" in src/ right? Is there a way to prevent paths to npm packages from being modified?

Here is a repo containing a jest test for this: https://github.com/she11sh0cked/tsc-alias-issue

tsc-alilas 1.6.2 does not work on windows

It fails to find any files in the outDir,

From some investigation this is because the windows absolute path is given to globby (this has backslashes).

The globs provided to globby should only have forward slashes:

Note that glob patterns can only contain forward-slashes, not backward-slashes, so if you want to construct a glob pattern from path components, you need to use path.posix.join() instead of path.join().

changing the code in replaceTscAliasPaths to:

        const posixOutput = config.outPath.replace(/\\/g,'/');
        const globPattern = [
            `${posixOutput }/**/*.{mjs,cjs,js,jsx,d.{mts,cts,ts,tsx}}`,
            `!${posixOutput }/**/node_modules`
        ];

Fixes, I'm not sure if this is the best place to fix it.

Replacement get ignored in some cases if the prefix is not immediately followed by a '/'

I have a tsconfig like the following:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "#*": [
        "src/*"
      ]
    },
  }
}

In my ts file deep in the root directory, let's say I have src/a/index.ts and src/a/b/index.ts, and there is a file referencing these two files like the following:

import * as a from '#a';
import * as b from '#a/b';

Expected Result

After using tsc-alias, the result should be the following:

const a = require("<path to src>/a");
const b = require("<path to src>/a/b");

Current Result

However, referencing to #a/b is somehow ignored, but referencing to #a is working:

const a = require("<path to src>/a");
const b = require("#a/b");

Nodemon support!

This plugin working fine while compilation.

Can you guide me how to use in watch mode with nodemon/ts-node ?

node --inspect -r ts-node/register src/server.ts

Aliases to files don't resolve properly

To reproduce
project
| -- src
| -- constants.ts
| -- app.ts

tsconfig.json

{
  "compilerOptions": {
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "importHelpers": true,
    "inlineSources": true,
    "module": "commonjs",
    "noEmitHelpers": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "outDir": "./dist",
    "skipLibCheck": true,
    "sourceMap": true,
    "sourceRoot": "/",
    "strict": true,
    "strictFunctionTypes": true,
    "strictNullChecks": true,
    "target": "es2016",
    "types": ["node"],
    "typeRoots": ["node_modules/@types"],
    "baseUrl": "src",
    "paths": {
      "$constants": ["constants"]
    }
  },
  "include": ["src/**/*", ".env"],
  "exclude": ["node_modules", "src/**/*.spec.*"]
}

src/constants.ts

export default {};

src/app.ts

import C from '$constants';
console.log(C);

Results in

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const _constants_1 = (0, tslib_1.__importDefault)(require("."));
console.log(_constants_1.default);

It should be:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const _constants_1 = (0, tslib_1.__importDefault)(require("./constants.js"));
console.log(_constants_1.default);

Using path-cache's exists method instead of just fs.existsSync makes my case work...

tsc-alias command line arguments are not parsed

I found that tsc-alias --watch does not work and why this issue is happening.

In src/bin/index.ts, your code to parse command-line arguments seems good. But this change is not reflected in the dist/bin/index.js (current version is v1.4.0).

p.s. I think using concurrently would be stable.

(in package.json)
"build:watch": "concurrently \"tsc -w\" \"tsc-alias --watch\""

Relative path off by one with baseUrl set

I had my tsconfig.json set up with

  "baseUrl": "./src",
  "paths": {
      "@/*": [
        "./*"
      ]
    },

This compiled....

import { PipelineStage } from `@/pipeline`

To the following (the relative path has an extra ../)

var pipeline_1 = require("../../../pipeline");

Changing the tsconfig to the following fixed the issue. Now the require only has ../../pipeline.

  "baseUrl": ".",
  "paths": {
      "@/*": [
        "./src/*"
      ]
    },

Not finding @tsconfig packages in NPM7 workspace.

Running into this issue now:

12:05:03 Info: === tsc-alias starting ===
12:05:03  Error:  File $WORKSPACE/$REPO/packages/$SUB_PACKAGE/node_modules/@tsconfig/node14/tsconfig.json not found

Where it shouldn't be found because this package is part of a monorepo and all the packages are in the node_modules at the root, directory. I.e. tsc-alias should be looking at $WORKSPACE/$REPO/node_modules/@tsconfig/node14/tsconfig.json. I.e. it should be using the normal module resolution, recursively checking ancestor directory's node_modules.

More specifically, in the $SUB_PACKAGE we have the following:

tsconfig:

{
  "extends": "@tsconfig/node14/tsconfig.json",
  "compilerOptions": {
     ...
  }
}

My guess is that this function (resolveTsConfigExtendsPath) needs to be updated to follow the regular node module resolution pattern.

Cannot install [email protected] via npm and "tsc-alias" not found when using yarn

When installing tsc-alias via npm:

> npm i tsc-alias -D
npm WARN deprecated [email protected]: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated [email protected]: Please see https://github.com/lydell/urix#deprecated
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

npm ERR! code ENOENT
npm ERR! syscall chmod
npm ERR! path D:\Projects\vscode\Temp\node_modules\tsc-alias\bin\index.js
npm ERR! errno -4058
npm ERR! enoent ENOENT: no such file or directory, chmod 'D:\Projects\vscode\Temp\node_modules\tsc-alias\bin\index.js'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\YF\AppData\Roaming\npm-cache\_logs\2020-11-09T02_31_41_996Z-debug.log

Yarn can add tsc-alias successfully, but fails to execute tsc-alias:

> yarn add tsc-alias -D
yarn add v1.22.4
info No lockfile found.
[1/4] Resolving packages...
warning tsc-alias > globby > fast-glob > micromatch > snapdragon > source-map-resolve > [email protected]: https://github.com/lydell/resolve-url#deprecated
warning tsc-alias > globby > fast-glob > micromatch > snapdragon > source-map-resolve > [email protected]: Please see https://github.com/lydell/urix#deprecated
[2/4] Fetching packages...
info [email protected]: The platform "win32" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 89 new dependencies.
info Direct dependencies
└─ [email protected]
info All dependencies
├─ @jfonx/[email protected]
├─ @mrmlnc/[email protected]
├─ @nodelib/[email protected]
...
├─ [email protected]
├─ [email protected]
└─ [email protected]
Done in 6.25s.

> yarn tsc-alias
yarn run v1.22.4
error Command "tsc-alias" not found.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

The scripts tsc-alias does not exist in node_modules/.bin/.

Continues on error when `silent` option passed to Output class instance

error(message: string, exitProces = false) {
if (this.silent) return;
Console.error(message, exitProces);
}

It looks like the intention of the silent option is to disable console logging. However, in the case of calling output.error when that value is set, the early return prevents the process from being ended.

For example, in the entrypoint file using silent mode would allow the following validity checks to fail while the program continues running:

tsc-alias/src/index.ts

Lines 61 to 69 in 19356e7

if (!baseUrl) {
output.error('compilerOptions.baseUrl is not set', true);
}
if (!paths) {
output.error('compilerOptions.paths is not set', true);
}
if (!outDir) {
output.error('compilerOptions.outDir is not set', true);
}

Versions 1.3.0 and 1.3.1 are not works for my project.

Hi,
Versions 1.3.0 and 1.3.1 are not works for my project, but version 1.2.11 is working fine.

I have this error on the last version. But when I run npx [email protected] it works without errors.

Info: === tsc-alias starting ===
/home/victor/GIT/Nanoheal.com/nh_deployment/packages/cloud-backend/node_modules/tsc-alias/dist/index.js:121
        const isAlias = requiredModule.includes('/')
                                       ^

TypeError: Cannot read property 'includes' of undefined
    at replaceImportStatement (/home/victor/GIT/Nanoheal.com/nh_deployment/packages/cloud-backend/node_modules/tsc-alias/dist/index.js:121:40)
    at /home/victor/GIT/Nanoheal.com/nh_deployment/packages/cloud-backend/node_modules/tsc-alias/dist/index.js:145:83
    at String.replace (<anonymous>)
    at ImportPathResolver.replaceSourceImportPaths (/home/victor/GIT/Nanoheal.com/nh_deployment/packages/cloud-backend/node_modules/tsc-alias/dist/utils/ImportPathResolver.js:23:35)
    at Object.replaceSourceImportPaths (/home/victor/GIT/Nanoheal.com/nh_deployment/packages/cloud-backend/node_modules/tsc-alias/dist/utils/ImportPathResolver.js:64:51)
    at replaceAlias (/home/victor/GIT/Nanoheal.com/nh_deployment/packages/cloud-backend/node_modules/tsc-alias/dist/index.js:145:32)
    at Object.replaceTscAliasPaths (/home/victor/GIT/Nanoheal.com/nh_deployment/packages/cloud-backend/node_modules/tsc-alias/dist/index.js:168:13)
    at Object.<anonymous> (/home/victor/GIT/Nanoheal.com/nh_deployment/packages/cloud-backend/node_modules/tsc-alias/dist/bin/index.js:16:5)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
error Command failed with exit code 1.

Thanks for your project!

tsc-alias does not take custom tsconfig.json file

Hi,

like above, I run command tsc-alias -p tsconfig.compile.json and I get error compilerOptions.paths is not set which is not tru for above file, but it is true for default tsconfig.json file. So I put paths to default tsconfig and the error changed to missing outDir which again, is missing from tsconfig.json but exists in tsconfig.compile.json.

This bug exists from @1.4.

Add register used for ava.config.js

The way write ava test isn't support ts alias. It's because ts-node/register won't parse alias.

Therefor I have to require module-alias/register. However, module-alias/register is need to write additional config at package.json.

ts-alias could support ts-alias/register, auto read the tsconfig.json same as ts-node/register. We don't need to write additonal alias config again.

// The ava config use module-alias/register
export default {
  compileEnhancements: false,
  files: ['tests/**/*.ts'],
  extensions: ['ts'],
  require: ['ts-node/register', 'module-alias/register'],
}
// the module-alias config at package.json
{
  "_moduleAliases": {
    "@": "./src"
  }
}
// the tsconfig
{
  "compilerOptions": {

    "paths": {
      "@/*": ["src/*"]
    }
  }
}

Very slow build times?

I don't know if it's a problem you are able to solve, but tsc-alias is really screwing up my build times. I run tsc-alias both manually and in watch mode and it takes up about 90% of the build time. It would be really nice if some performance patches would be done, as I think it would boost this package popularity.

Versions 1.6.2 and higher no longer replaces aliases

After upgrading tsc-alias to 1.6.2 from 1.6.1, the tool seemingly no longer works.

I have a single entry in paths in my tsconfig.json:

{
  "paths": {
    "~*": ["./src/*"]
  }
}

I build my types with the following command: tsc --emitDeclarationOnly --outDir dist && tsc-alias

Previously it worked without issue. After the upgrade, tilde paths in my .d.ts files are no longer replaced with relative paths.

I'm happy to provide more info, just let me know what's needed!

Versions
Node - 17.6.0
NPM - 8.5.2
tsc-alias - 1.6.2

Breaking change on `v1.4.2`: doesn't replace an alias ended by `/` anymore [minor bug]

Thank you for working on tsc-alias 🤗

I'm glad to see this project moving, and see a nice peak on npm download!
It's so much more cleaner to drop aliases at compile time!

Breaking change description

For this alias config:

        "paths": {
            // I'm doing so to use alias directly + match * file inside
            "@backend/config": ["config"],
            "@backend/config/*": ["config/*"],
        }

Using it like following:

import config from "@backend/config/";

Then, my import is not converted

const config_1 = require("@backend/config");

History

I bumped my tsc-watch from 1.3.7 to 1.6.4 and discovered the bug.
I wanted to find why it broke:

// Finding breaking change in tagged versions
1.4.1: OK! :)
1.4.2: BROKEN!

// Finding breaking in commits
e980fee75851012c52878c0d23c2dc05fe83bce4: (1.4.1): OK
18b252a5de960b813490ce6fa6e3a447b943d61e: OK
563183822a006e5f5e51c0a9125fd3f77c18f1ee: BROKEN

... note it's broken to current version 1.6.4

So it seems that this minor change actually broke something 5631838
I didn't dived too much, but it seems the isAlias boolean is false instead of true so the alias is simply not spotted at all

const isAlias = alias.shouldPrefixMatchWildly

tsc-alias/src/index.ts

Lines 189 to 190 in 5631838

requiredModule.startsWith(alias.prefix) &&
requiredModule !== alias.prefix

And actually in this case I'm requiredModule === alias.prefix but honestly I don't have enough knowledge to say what's wrong

Is it a bug?

I would say yes 🤔

  • for instance @backend/config/prod/ (folder) is well recognized
  • but @backend/config/ is not but it's still a folder.

That's a superfluous / so I can just refresh my codebase where the bug occurs obviously.
Or maybe this way of using @alias + @alias/* is wrong do you know how I can improve?

Spurious matches when the "for" keyword is inside a string

The regexes used to match import statements assume that the import-related keywords (from, import, require) always carry their functional meaning. But these keywords can also appear inside of strings and comments, where they no longer mean the same thing.

I stumbled on an example that, stripped down, looks like this:

const testCase = `
    'a string with keyword from '
    // The from keyword in that string can cause
    // a match up to the next quote, since the regex does not
    // know that the keyword is in a string context
    'another string using same quote type'
  `;

The regexes end up claiming that the following is an imported path:

`
    // The from keyword in that string can cause
    // a match up to the next quote, since the regex does not
    // know that the keyword is in a string context
`

To completely address this we'd need a more elaborate matching mechanism that strips comments and strings before matching keywords.

However, a band-aid fix to the regexes to have stricter matching would resolve cases like this one. In particular, ensuring that import paths are single-line strings will do the trick.

Not parsing on await imports

Hi there, I found one issue where trying to await imports on a file without extension doesn't translate the build file with the extension.

example:

export const createRoute = async (foo) => {
  try {
    // I want it to be awaited so my database initializes first.
    const { route } = await import("../models/route")

    const result: InsertOneWriteOpResult<Route> = await route.insertOne({ foo })

    return result
  } catch (e) {
    console.error(e)
  }
}

I thought it would be possible due to https://github.com/justkey007/tsc-alias/blob/master/src/utils/ImportPathResolver.ts#L23 but if I leave .js out it will be out when I build with ttsc

Let me know if I can help debug this even further.
cheers

If I use `@username/tsconfig` extends, get `The JSON file is invalid` error

I use shared tsconfig in my project. ( @p-chan/tsconfig )
However, I'm having trouble using tsc-alias in conjunction with shared tsconfig and I'm getting an error.

If you know of a solution, I'd be happy to let you know.


{
  "extends": "@p-chan/tsconfig",
  "compilerOptions": {
    "outDir": "./dist",
    "baseUrl": "./",
    "paths": {
      "@config/*": ["./src/config/*"],
      "@controllers/*": ["./src/controllers/*"],
      "@middlewares/*": ["./src/middlewares/*"]
    }
  }
}
{
  ...
  "scripts": {
    "build": "tsc",
    "postbuild": "tsc-alias",
  },
  ...
}
$ npm run build

Error:  The JSON file is invalid ==> /Users/p-chan/src/github.com/p-chan/myproject/@p-chan/tsconfig

(myproject equal process.cwd().)

Doesn't work if the prefix in paths is not used as a directory

I have a tsconfig like the following:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "#*": [
        "src/*"
      ]
    },
  }
}

In my ts file deep in the root directory, let's say src/a/index.ts, I can simply use

import * as b from '#b';

to get the export in either src/b.ts or src/b/index.ts.

Expected Result

In src/a/index.js after using tsc-alias, the result should be the following:

const b = require("../b");

Current Result

However, currently, the output is the following and it's unresolvable:

const b = require("..b");

The Problem

As we can see here, a / is missing. The cause of the missing / is that we have an assumption that we always have a / after a prefix, e.g. @component/awesome with the prefix @component. See the logic below:

tsc-alias/src/index.ts

Lines 192 to 194 in 4c81b5f

let relativeAliasPath: string = normalizePath(
relative(dirname(file), absoluteAliasPath)
);

tsc-alias/src/index.ts

Lines 200 to 203 in 4c81b5f

const modulePath =
orig.substring(0, index) +
relativeAliasPath +
orig.substring(index + alias.prefix.length);

But, it's not always true as stated in my use case.

The Fix

Luckily, the fix is quick and simple, just need to add the / back when necessary as the following:

const modulePath = 
   orig.substring(0, index) + 
   relativeAliasPath +
   '/' +
   orig.substring(index + alias.prefix.length); 

Any excess // will be removed in

return modulePath.replace(/\/\//g, '/');

So it will only be a simple and clean fix.

Urgent help needed - Failed to import `replacer` file

Hi there,

I've been trying to use this package successfully but I can't import the replacer file.

Here is my file structure

mono-repo
- packages
- - project
- - - src
- - - - assets
- - - - component
- - - - - Button
- - pathReplacer.js
- - tsconfig.json
tsconfig.json

In the Button file, I use an alias for the path like require('#/assets/images/button.png')

Here is my project tsconfig.json

{
  "extends": "../../tsconfig.json",
  "include": ["**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules", "dist"],
  "compilerOptions": {
    "skipLibCheck": true,
    "emitDecoratorMetadata": true,
    "outDir": "dist",
    "isolatedModules": true,
    "declarationDir": "dist",
    "typeRoots": ["./src/types/types.d.ts", "./src/types/styled.d.ts", "../../node_modules/@types"],
    "paths": {
      "#*": ["./src/*"]
    }
  },
  "references": [
    {
      "path": "../ui-core"
    }
  ],
  "tsc-alias": {
    "verbose": false,
    "resolveFullPaths": true,
    "replacers": {
      "pathReplacer": {
        "enabled": true,
        "file": "./pathReplacer.js"
      }
    }
  }
}

I can build the project fine with tsc without errors but as soon I add the tsc-alias section in the tsconfig.json file I get this error

tsc-alias error: Failed to import replacer "./pathReplacer.js"

Here the content of pathReplacer.js

import { replaceTscAliasPaths } from 'tsc-alias'

replaceTscAliasPaths()

Can you help me to resolve this problem?

Breaking change on `v1.4.2`: replacement for non-alias :exploding_head:

Hi!
I've got a second bug spotted on (first minor here), and since 1.4.2
and I think this one is quite interesting as it's replacing a NodeJs native library import statement.

Description / steps to reproduce

  1. tsconfig.json alias config doesn't matter!
"path": {} // empty
  1. file to convert /utils/index.js, which does contain a Node.js native package
    (for instance cluster, but it works for a child_process, fs or whatever)
const cluster = require("cluster");
  1. And, I've got some file /cluster.js:
// the bug occurs as long the file "cluster" exists

The /utils/index.js will be rewritten as following 🤯 🤯 🤯

const cluster = require("../cluster");

Origin

That's not the same source as the minor bug I've spot!
This issue is coming from this commit: 18b252a

// Finding breaking change in tagged versions
1.4.1: OK! :)
1.4.2: BROKEN!

// Finding breaking in commits
e980fee75851012c52878c0d23c2dc05fe83bce4: (1.4.1): OK
18b252a5de960b813490ce6fa6e3a447b943d61e: BROKEN

... note it's broken to current version 1.6.4

I'm trying to spot exactly which code did this regression, probably replaceBaseUrlImport but I'm not sure to be able to edit this code without breaking things 😞

Let me know if I can help

Imports breaking on >1.4.0

I'm upgrading the dependencies on my projects, and after upgrading tsc-alias (to 1.4.1 or 1.5.0), some of my imports are breaking.

The paths on my tsconfig is like this:

"paths": {
      "~/*": ["./*"]
    },

But this

import { Dispatch } from 'redux';

Is becoming

import { Dispatch } from '../../redux';

I think it's because there is a redux folder on the folder it's compiling, but it should not be parsed, as it does not begins with ~/


Another problem I had, was because some paths were not being parsed if an asset was not present (on the release script they were added afterwards)

This import was not parsed if the svg file was not present in the dist folder

export { default as iconx } from '~/assets/icons/iconx.svg';

Matching an alias to another inappropriate import path

Following pull request #44

I have a typescript config as follows:

{
  "compilerOptions": {
    "outDir": "./dist",
    "baseUrl": "./",
    "paths": {
      "@*": ["./src/*"],
      "@router": ["./src/controllers/index.ts"]
    }
  }
}

And I do an import like this:
Important: the router folder does not exist

import { Controller } from '@controllers/index';
import { Router } from '@router';

new Controller();

new Router();

Expected Result

After using tsc-alias, the result should be the following:

"use strict";
exports.__esModule = true;
var index_1 = require("./controllers/index");
var _router_1 = require("./controllers/index.js");
new index_1.Controller();
new _router_1.Router();

Current Result

"use strict";
exports.__esModule = true;
var index_1 = require("./controllers/index");
var _router_1 = require("./router");
new index_1.Controller();
new _router_1.Router();

Proposed solution

Sort aliases in descending order according to their length

use with ts-node

how to configure tsc-alias to be used with ts-node?
you may need to implement a register

node --experimental-modules --experimental-specifier-resolution=node -r tsc-alias/register --loader ts-node/esm ./tasks/index.ts

tsconfig-paths and module-alias don't work with module projects. i.e if you set type: module in your package .json

minimal repo
run npm run start:paths

Bad npm package build 1.3.9

Release https://github.com/justkey007/tsc-alias/releases/tag/v1.3.9 that adds the add event listener doesn't have that new code in the npm package.

Because of it nothing happens on initial build in watch mode when there are no files generated by tsc yet.

https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.3.9.tgz

        if (options.watch) {
            output.info('[Watching for file changes...]');
            const filesWatcher = chokidar_1.watch(globPattern);
            const tsconfigWatcher = chokidar_1.watch(configFile);
            filesWatcher.on('change', (file) => __awaiter(this, void 0, void 0, function* () {
                yield replaceAlias(file, options === null || options === void 0 ? void 0 : options.resolveFullPaths);
            }));
            tsconfigWatcher.on('change', (_) => {
                output.clear();
                filesWatcher.close();
                tsconfigWatcher.close();
                replaceTscAliasPaths(options);
            });
        }

paths are not resolved when './' is specified as baseUrl

Directory structure

├── package.json
├── src
│   ├── controllers
│   │   └── index.ts
│   └── index.ts
├── tsconfig.json
└── yarn.lock

./src/index.ts

import { fooController, barController } from '@controllers/index'

tsconfig.json

{
  "extends": "@stardust-configs/tsconfig/node12",
  "compilerOptions": {
    "outDir": "./dist",
    "baseUrl": "./",
    "paths": {
      "@controllers/*": ["./src/controllers/*"],
    }
  }
}

dist

└── dist
    ├── controllers
    │   └── index.js
    └── index.js

./dist/index.ts

const index_1 = require("./src/controllers/index");

-> Error: Cannot find module

[Question] Keep aliases in source files

Hi,

at first, thanks for the package - it helps us to use path aliases in the AWS CDK.

I have currently the challenge that tsc-alias replaces all @alias definitions in all files.

Based on the code, i can see that the files to replace are hard coded, is there a chance to make the file types configurable?

As reference: https://github.com/justkey007/tsc-alias/blob/master/src/index.ts#L232

Why? I would like to keep the aliases in the *.ts files and only replace the aliases in the javascript files.
Normally i can the build and cdk:synth command before I deploy the code, but to have relative path in the import statements is not what I want and in case the paths are changed, i have to replace each file manually.

Thanks!

Bug: replace module names incorrectly (default import)

Hey

First of all, thanks for this awesome package 😁

We have a small bug.

Steps

  1. Import sharp with:
import sharp from 'sharp';

// ...
  1. Run "tsc && tsc-alias"

Expected

Compiled to JS:

const sharp_1 = __importDefault(require('sharp'));

Actual

Compiled to JS:

const sharp_1 = __importDefault(require('../sharp'));

So there the bug is here! If I remove tsc-alias, I can run the project successfully (via tsconfig-paths for testing)

Issue with relative folder imports such as `./something` for `./something/index.ts` when using `--resolve-full-paths`

I'm seeing a problem with relative folder imports that have an implied index.js when using --resolve-full-paths. I'm running tsc-alias --resolve-full-paths for each of these examples:

Before:
image

Actual Output:
image
(Note the lack of a leading ./ on the authorization and test-helpers imports)

Expected output:
image

Here is what the directory structure looks like:
image

tsconfig.json:

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": ".",
    "baseUrl": ".",
    "paths": {
      "@container": ["src/container.ts"],
      "@interfaces": ["src/interfaces.ts"],
      "@main": ["src/main.ts"],
      "@util": ["src/utils/index.ts"]
    }
  },
  "include": ["src/**/*.ts", "test/**/*.ts"]
}

I have tried changing rootDir and baseUrl to ./ instead of . but that didn't make a difference.

As a workaround for now I was able to grab the latest copy of this package from git and build it to use the new replacer functionality. Using this replacer solved my issue, but ideally I think this should be built in to the package if possible:

function testReplacer({ orig, file, config }) {
  const regex = /from '[a-z].*index.js'$/g;

  if (orig.match(regex)) {
    orig = orig.replace('from \'', 'from \'./');
  }

  return orig;
}

exports.default = testReplacer;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.