Support baseUrl (non-relative imports)
It is a common patten in TypeScript (and create react app) projects to specify a baseUrl in the tsconfig.json to allow for absolute URL imports.
// tsconfig.json
{
"compilerOptions": {
"baseUrl": "src" // non-relative imports are relative to this path
},
"include": ["src"]
}
Example project structure:
src/
helpers/bar.ts
foo.ts
tsconfig.json
Example code:
// helpers/bar.ts (with baseUrl: src)
import { foo } from 'foo'
// helpers/bar.ts (without baseUrl)
import { foo } from '../foo'
Babel plugin or link to the feature description
- https://www.typescriptlang.org/docs/handbook/module-resolution.html#base-url
- https://create-react-app.dev/docs/importing-a-component/#absolute-imports
- https://levelup.gitconnected.com/understand-and-configure-absolute-import-paths-in-javascript-5cde3be2630d
Additional context I am looking into using SWC to replace babel in a large monorepo I manage. I ran across very few issues but had to stop when I hit this snag. I think there is a large section of the existing JavaScript community that uses this feature (or a variation). For instance, something like non-relative imports is supported by:
- TypeScript
- Babel
- Rollup
- Webpack
- ESLint
There are some pros and cons of using these types of imports in your code. There is no denying that it is popular and a positive developer experience. My sense is that the argument against something like baseUrl is that it (perhaps) doesn't fit well with the official spec for import resolving.
It seems like Node is providing some mechanisms for doing parent-relative import resolving. It is notable the NODE_PATH is explicitly not supported by Node's ES Modules.
- https://nodejs.org/api/esm.html#esm_import_meta_resolve_specifier_parent
- https://nodejs.org/api/esm.html#esm_no_node_path
ideal case
In an ideal world we could use non-relative imports in our source code and have them transpiled into relative paths in the final code.
// in
import { foo } from 'foo'
Building for ESM:
// out (esm)
import { foo } from '../foo'
Building for CJS:
// out (cjs; simplified for clarity)
const { foo } = require('../foo')
- https://www.npmjs.com/package/typescript-transform-paths
- https://github.com/Microsoft/TypeScript/issues/15479#issuecomment-300240856
- https://www.npmjs.com/package/babel-plugin-module-resolver
For more context, TypeScript has limited support for generating output code that respects the baseUrl settings. The transform paths plugin does this and it requires a custom compiler (ttypescript). Using Babel to transform your TypeScript means you can use the module resolver plugin to convert to relative imports.
What I'm most worried about is the right steps to get both the transpile and transform features we use today with our current babel/typescript rig.
SWC is appealing because it correctly recognizes that preset-env is 99% of that you need. However, the power of the tooling has spoiled us. We're dependent on bespoke productivity tools (like path transforms) that enhance developer experience but are not directly related to the core task of transpiling TypeScript/ES code to work in a variety of JavaScript environments.
Do you mean you want to use baseUrl without paths?
Do you mean you want to use baseUrl without paths?
Hey @kdy1 !
I have this exact use case yes, where I have only baseUrl: 'src' and no paths configured.
Right now I cannot use swc because it does not work with this configuration.
It may need some more thoughts, but I'm under impression we (swc/core) eventually get rid of custom resolving behavior including existing options but instead let userland plugin / module does custom resolving, as similar to babel's plugin which is referenced in here.
are there currently any work arounds in combination with swc, previously i used just ttsc with a path transformer plugin.
would love to speed up my builds. anyway swc looks really nice. great job
Any progress on this issue? I'm stuck.
I checked if this is easily implementable, but I decided to postpone it as it requires resolving logic
I would also love this feature. I looked into rollup which has a plugin for this. But rollup builds my code 20 times slower than SWC (even with esbuild plugin). Refactored everything to relative imports for now, hoping that SWC will support absolute imports soon.
In the mean time if anyone has a good workaround please let me know. Thanks so much for an awesome tool :)
Would absolutely love this feature too! We are using SWC as the transpiler for our backend Nest.js project and skip webpack entirely. Currently relative imports + nodenext target is the way we do it, but would prefer being able to use absolute imports without specifying paths.
I have project with baseUrl and without paths.
@kdy1 Are there any plans to implement this in the immediate future (using baseUrl without paths specified)?
Currently using webpack for module resolution which then calls into SWC.
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.