My Package Workflow
For my personal projects, I have a consistent structure for the packages I create and reuse. In production, I write these packages in TypeScript and compile them to JavaScript using `tsc` before publishing them to npm. This allows me to seamlessly use them in my other projects. I also run tests on these packages using Jasmine.
During development, I utilize Webpack with `ts-loader` to compile the TypeScript code in a way that supports running example scripts in a browser. Although the projects consuming these packages recognize them as JavaScript files only (due to pre-compilation before publishing), I still use Webpack for consistency.
Uniformly using ES module syntax in all contexts is vital to me. This avoids the hassle of switching between CommonJS for Node.js and ES module syntax for browsers. To ensure this consistency in Jasmine, I have configured my `jasmine.json` file with `"jsLoader": "import"`.
However, I am facing an issue with writing import statements, specifically how to specify file extensions to work seamlessly across different scenarios while developing these packages.
No File Extension Approach
When using `import { foo } from './foo';` in TypeScript, the Node module resolution assumes the file as `foo.ts`. Webpack's `resolve` configuration, specifying `extensions: ['.js', '.ts']`, also aligns with TypeScript's behavior in resolving imports with no file extensions.
Unfortunately, while this approach works for TypeScript and Webpack, running Jasmine tests with `import` without file extensions results in unresolved module errors.
Using .js File Extension Approach
Alternatively, including the `.js` file extension in imports like `import { foo } from './foo.js';` is supported in TypeScript since version 2. This allows successful compilation with `tsc` and resolves Jasmine tests as well.
However, Webpack struggles to interpret `./foo.js` as `./foo.ts`. This hinders building the code for showcasing examples in the browser.
.js Extension with Webpack Aliases
To address this limitation, I resorted to using Webpack's `resolve.alias` configuration to explicitly map `./foo.js` to `./foo.ts`. While this workaround works, it feels cumbersome and lacks scalability.
Is there a better, more optimal solution to handle file extensions in import statements across TypeScript, Webpack, and Jasmine without the need for numerous aliases?