I am working on a monorepo and therefore I want Webpack to load my sources from src
instead of dist
(dist
is specified in package.json
).
For example given the following structure:
/packages/core/dist/index.js (compiled output)
/packages/core/src/index.ts (original TypeScript source)
/packages/core/package.json (`main` and `module` point to `dist`)
Now inside /packages/foo/src/index.ts
I am doing import Foo from '@test/core'
. The problem is that Webpack reads core
package's package.json
and uses its module
and main
fields that point to dist
folder. I instead want Webpack to load the original sources from src
, because this @test/core
is part of my own codebase and not an external dependency.
Is there a way to force Webpack to load my original TS sources only for certain modules like the ones beginning with @test/
?
Like Babel, Webpack depends on TSC to transpile TypeScript to JavaScript but as TSC doesn't have a clue about Webpack, hence Webpack needs a loader to talk to TSC. This is where the ts-loader comes into play. Webpack compiles a TypeScript file using ts-loader package which asks TSC to do the compilation.
Webpack allows you to define externals - modules that should not be bundled. When bundling with Webpack for the backend - you usually don't want to bundle its node_modules dependencies. This library creates an externals function that ignores node_modules when bundling in Webpack.
You can use a resolve alias.
For example, assuming your webpack config is above the packages folder:
{
resolve: {
extensions: [".ts", ".js", ".json"],
alias: {
"@test/core": path.resolve(__dirname, "packages/core/src")
}
}
}
Then you can use require as usual, but any paths starting with @test/core
will be resolved to path.resolve(__dirname, "packages/core/dist")
.
require("@test/core")
=> packages/core/src/index.ts
require("@test/core/module")
=> packages/core/src/module.ts
As .ts
is a non-standard extension you have to add this to resolve.extensions
.
I resolved it with NormalModuleReplacementPlugin
:
I put this in my Webpack config:
plugins: [
new webpack.NormalModuleReplacementPlugin(
/@test\/[a-z]+$/,
resource => {
resource.request = resource.request + '/src/index'
}
)
]
Since I am using TS, I also had to add .ts
extension to:
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
}
Now importing @test/xyz
will be imported as @test/xyz/src/index
-- and it will first look out for .ts
extension.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With