Error with TypeScript config and ESM

5
closed
revmischa
revmischa
Posted 4 months ago

Error with TypeScript config and ESM #232

Bug description

I'm using TypeScript webpack config, running with ts-node/esm loader It yells at me:

[webpack-cli] file:///Users/cyber/dev/tombo/freezy/src/webpack/webpack.common.ts:6
import { ESBuildMinifyPlugin } from "esbuild-loader";
         ^^^^^^^^^^^^^^^^^^^
SyntaxError: Named export 'ESBuildMinifyPlugin' not found. The requested module 'esbuild-loader' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'esbuild-loader';
const { ESBuildMinifyPlugin } = pkg;

If I do

import pkg from 'esbuild-loader';
const { ESBuildMinifyPlugin } = pkg;

Then I get the error:

[webpack-cli] Failed to load '/Users/cyber/dev/tombo/freezy/src/webpack/webpack.prod.ts' config
[webpack-cli] src/webpack/webpack.common.ts:7:9 - error TS2339: Property 'ESBuildMinifyPlugin' does not exist on type '(this: any, source: string) => Promise<void>'.

7 const { ESBuildMinifyPlugin } = pkg;
          ~~~~~~~~~~~~~~~~~~~

Reproduction

import pkg from 'esbuild-loader';
const { ESBuildMinifyPlugin } = pkg;

Node.js package manager

npm

Environment

System:
    OS: macOS 12.0.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 25.19 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.17.5 - /usr/local/bin/node
    Yarn: 1.22.17 - /usr/local/bin/yarn
    npm: 8.2.0 - /usr/local/bin/npm
  npmPackages:
    esbuild-loader: ^2.17.0 => 2.17.0
    webpack: ^5.65.0 => 5.65.0


### Can you contribute a fix?

- [X] I’m interested in opening a pull request for this issue.
privatenumber
privatenumber
Created 4 months ago

Does setting esModuleInterop in tsconfig.json help?

In any case, happy to add an ESM distribution now that TS is starting to support export maps in 4.6.0

revmischa
revmischa
Created 4 months ago

This is my tsconfig:

{
  "compilerOptions": {
    "strict": true,
    "module": "ES2020",
    "target": "es2019",
    "incremental": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "rootDir": "src",
    "outDir": "dist/js",
    "noEmitOnError": false,
    "moduleResolution": "node",
    "jsx": "react",
    "plugins": [
      {
        "name": "typescript-plugin-css-modules"
      }
    ],
    "baseUrl": "src",
    "resolveJsonModule": true
  },
  "include": ["src"],
  "files": ["src/types/index.d.ts", "src/types/global.d.ts"]
}
revmischa
revmischa
Created 4 months ago
Screen Shot 2021-12-19 at 20 23 49
pi0
pi0
Created 4 months ago

Hi! Just wanted to mention that we faced a related issue with Nuxt3 as all internals are ESM only. (without typescript also having issues)

A simple workaround: (https://github.com/nuxt/framework/pull/2460)

import esbuildLoader from 'esbuild-loader'

// For plain mjs
const { ESBuildMinifyPlugin } = esbuildLoader

// For typescript
const { ESBuildMinifyPlugin } = (esbuildLoader as unknown as typeof import('esbuild-loader'))

privatenumber
privatenumber
Created 4 months ago

Thanks for linking the PR @pi0 -- I didn't realize this was a regression.

Seems this problem is a result of this change, converting import then exports to export from statements. I will revert this for now.

As a side, I tested an ESM distribution in branch esm, but it seems to create more problems. Using ts-node/esm, it can't even load esbuild-loader because it's dependency webpack-sources is not ESM:

node --loader ts-node/esm webpack.config.js
(node:40630) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
file:///test-esbuild-loader/node_modules/.pnpm/local_61d4bb34c93b5b3ba826a79b4ebb50a3/node_modules/esbuild-loader/dist-esm/minify-plugin.js:2
import { RawSource, SourceMapSource } from 'webpack-sources';
         ^^^^^^^^^
SyntaxError: Named export 'RawSource' not found. The requested module 'webpack-sources' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'webpack-sources';
const { RawSource, SourceMapSource } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:181:5)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)