Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure Webpack to load a module from its src folder instead of dist?

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 image 419
Kai Sellgren Avatar asked Jun 16 '19 11:06

Kai Sellgren


People also ask

Does webpack use TSC?

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.

Does webpack include node_modules?

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.


2 Answers

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.

like image 143
sdgluck Avatar answered Oct 01 '22 15:10

sdgluck


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.

like image 20
Kai Sellgren Avatar answered Oct 01 '22 17:10

Kai Sellgren