'Typescript issue during compilation around `webpack/HashedModuleIdsPlugin`

I am getting compilation issue around HashedModuleIdsPlugin and typescript :(

When compiling a TS project that allow JS, requires HashedModuleIdsPlugin and export it using commonJS, it raises an error and is not able to produce proper declaration files.

I reproduced it in a super tiny project here: https://github.com/raphaelboukara/test_ts_webpack.

In my src folder I have 2 files:

  • index.ts: import webpack.js
  • webpack.js: exports require('webpack').ids.HashedModuleIdsPlugin
// ./src/index.ts
import "./webpack.js";
// ./src/webpack.js
const { ids: { HashedModuleIdsPlugin } } = require('webpack');
module.exports = HashedModuleIdsPlugin;
{
  "exclude": [
    "dist"
  ],
  "include": [
    "./src"
  ],
  "compilerOptions": {
    "declaration": true,
    "module": "commonjs",
    "allowJs": true,
    "outDir": "dist"
  }
}

When running tsc, I am getting the error:

src/webpack.js:1:1 - error TS9006: Declaration emit for this file requires using private name 'HashedModuleIdsPlugin' from module '"/Users/raphael.b/lab/test_ts_webpack/node_modules/webpack/types"'. An explicit type annotation may unblock declaration emit.

1 const { ids: { HashedModuleIdsPlugin } } = require('webpack');
  ~~~~~


Found 1 error in src/webpack.js:1

How to reproduce?

  1. git clone [email protected]:raphaelboukara/test_ts_webpack.git
  2. nvm use
  3. npm i
  4. npm run build

Environment

  • node: 16.13.1
  • webpack: 5.72.0
  • ts: 4.6.4

Any idea what I am doing wrong?



Solution 1:[1]

requires using private name 'HashedModuleIdsPlugin' from module '"/Users/raphael.b/lab/test_ts_webpack/node_modules/webpack/types"'

Typescript is complaining because HashedModuleIdsPlugin is not explicitly exported from the webpack library. It is only re-exported as a property under ids and ids is explicitly exported from webpack. That's why Typescript says that it is private. It wasn't explicitly made to be accessible directly from the library in the types as you are trying to do here

const { ids: { HashedModuleIdsPlugin } } = require('webpack');

So what you should do is access it from ids and export it so

// webpack.js
const { ids } = require('webpack');
module.exports = ids.HashedModuleIdsPlugin;

You may want to enable compilerOptions.esModuleInterop by setting it to true in your tsconfig.json if you want to do something like

// webpack.js
const { ids } = require('webpack');
module.exports = { HashedModuleIdsPlugin: ids.HashedModuleIdsPlugin }
// index.ts
import { HashedModuleIdsPlugin } from "./webpack.js";

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 orimdominic