question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Inconsistency with TypeScript in Module Resolution with Fully-Specified ESM Imports

See original GitHub issue

Bug report

What is the current behavior?

When using extention .js as part of an import (fully-specified ESM import), webpack fails to create a bundle if the file imported have extention .tsx

This shouldnt be like this based on the comment of RyanCavanaugh in this issue https://github.com/microsoft/TypeScript/issues/41887#issuecomment-741968855

“TypeScript doesn’t modify JavaScript code you write, the import path you write should be the one you want to appear in the output .js file”

If the current behavior is a bug, please provide the steps to reproduce.

I created a repo showing this unexpected behavior this repo was tested with both ts-loader and babel-loader

https://github.com/Josehower/webpack-babel-test

  1. clone the repo and install dependencies
  2. use command $yarn start

image

import { test } from './test.js';

console.log('Hello Webpack Project.');
test();
jose fernando hower@DESKTOP-FHTIMFT MINGW64 /D/upleveled-softwork/webpack-test (main)
$ yarn start
yarn run v1.22.5
$ webpack serve --config ./webpack.config.js --mode development
i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from D:\upleveled-softwork\webpack-test\dist
× 「wdm」: asset bundle.js 367 KiB [emitted] (name: main)
runtime modules 706 bytes 4 modules
cacheable modules 336 KiB
  modules by path ./node_modules/webpack-dev-server/ 21.2 KiB
    modules by path ./node_modules/webpack-dev-server/client/ 20.9 KiB 10 modules
    modules by path ./node_modules/webpack-dev-server/node_modules/ 296 bytes 2 modules
  modules by path ./node_modules/html-entities/lib/*.js 61 KiB 5 modules
  modules by path ./node_modules/querystring/*.js 4.51 KiB 3 modules
  modules by path ./node_modules/webpack/hot/ 1.42 KiB
    ./node_modules/webpack/hot/emitter.js 75 bytes [built] [code generated]
    ./node_modules/webpack/hot/log.js 1.34 KiB [built] [code generated]
  modules by path ./node_modules/url/*.js 23.1 KiB
    ./node_modules/url/url.js 22.8 KiB [built] [code generated]
    ./node_modules/url/util.js 314 bytes [built] [code generated]
./node_modules/webpack/hot/ sync nonrecursive ^\.\/log$ 170 bytes [built] [code generated]

ERROR in ./src/index.tsx 1:0-33
Module not found: Error: Can't resolve './test.js' in 'D:\upleveled-softwork\webpack-test\src'
resolve './test.js' in 'D:\upleveled-softwork\webpack-test\src'
  using description file: D:\upleveled-softwork\webpack-test\package.json (relative path: ./src)
    Field 'browser' doesn't contain a valid alias configuration
    using description file: D:\upleveled-softwork\webpack-test\package.json (relative path: ./src/test.js)
      no extension
        Field 'browser' doesn't contain a valid alias configuration
        D:\upleveled-softwork\webpack-test\src\test.js doesn't exist
      *
        Field 'browser' doesn't contain a valid alias configuration
        D:\upleveled-softwork\webpack-test\src\test.js* doesn't exist
      .js
        Field 'browser' doesn't contain a valid alias configuration
        D:\upleveled-softwork\webpack-test\src\test.js.js doesn't exist
      .ts
        Field 'browser' doesn't contain a valid alias configuration
        D:\upleveled-softwork\webpack-test\src\test.js.ts doesn't exist
      .tsx
        Field 'browser' doesn't contain a valid alias configuration
        D:\upleveled-softwork\webpack-test\src\test.js.tsx doesn't exist
      as directory
        D:\upleveled-softwork\webpack-test\src\test.js doesn't exist

webpack 5.36.0 compiled with 1 error in 2410 ms
i 「wdm」: Failed to compile.
  1. use command $yarn tsc --noEmit
jose fernando hower@DESKTOP-FHTIMFT MINGW64 /D/upleveled-softwork/webpack-test (main)
$ yarn tsc --noEmit
yarn run v1.22.5
$ D:\upleveled-softwork\webpack-test\node_modules\.bin\tsc --noEmit
✨  Done in 1.49s.

image

What is the expected behavior?

  • In the example repo yarn start should succesfully create a bundle.

  • Webpack should be able to recognize the files imported and create a bundle even if the import statements with the extention .js point files that have the extention .tsx

Other relevant information:

OS: Windows 10 10.0.19041
CPU: (4) x64 Intel(R) Core(TM) i5-7400 CPU @ 3.00GHz
Binaries:
Node: 16.0.0 - ~\AppData\Local\Temp\yarn--1619542324765-0.4257021548777624\node.CMD
Yarn: 1.22.5 - ~\AppData\Local\Temp\yarn--1619542324765-0.4257021548777624\yarn.CMD
npm: 7.10.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 90.0.4430.93
Edge: Spartan (44.19041.906.0), Chromium (90.0.818.46)

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:6
  • Comments:51 (29 by maintainers)

github_iconTop GitHub Comments

9reactions
Josehowercommented, Jul 15, 2022

another workaround I found was using NormalModuleReplacementPlugin to replace the problematic extension

 module.exports = function (env) {
  return {
    plugins: [
      new webpack.NormalModuleReplacementPlugin(new RegExp(/^\..+\.js$/), function (resource) {
        resource.request = resource.request.replace(new RegExp(/\.js$/), '');
      }),
        }
      ),
    ],
  };
};

in our case, this did the trick

Updated with the RegExp suggested by @laverdet https://github.com/webpack/webpack/issues/13252#issuecomment-1185674918

4reactions
laverdetcommented, Jul 15, 2022

another workaround i found was using NormalModuleReplacementPlugin to replace the problematic extention

 module.exports = function (env) {
  return {
    plugins: [
      new webpack.NormalModuleReplacementPlugin(new RegExp(/\.js$/), function (resource) {
        resource.request = resource.request.replace('.js', '');
      }),
        }
      ),
    ],
  };
};

in our case this did the trick

I tweaked the RegExp here because otherwise imports to modules like sha.js will fail. Thanks!

            new NormalModuleReplacementPlugin(/^\..+\.js$/, resource => {
                resource.request = resource.request.replace(/\.js$/, "");
            }),
Read more comments on GitHub >

github_iconTop Results From Across the Web

Documentation - Module Resolution - TypeScript
Module resolution is the process the compiler uses to figure out what an import refers to. Consider an import statement like import {...
Read more >
Webpack ESM import file extension error inconsistency
I have a Webpack 5 project using an npm package composed of multiple ES files using imports that don't end with a (...
Read more >
SyntaxError: Cannot use import statement outside a module
BREAKING CHANGE: The request './Routes' failed to resolve only because it was resolved as fully specified (probably because the origin is strict ...
Read more >
Can build v4.2, but not v5.0...why not? - Babylon.js Forum
ModuleNotFoundError After Update to babylon 5.0.0 alpha ... resolve: { byDependency: { esm: { - fullySpecified: true + fullySpecified: false } ...
Read more >
TypeScript and native ESM on Node.js - 2ality
In this blog post, I'll explain everything you need to know in order to use and produce native ECMAScript modules on Node.js.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found