Webpack is unable to resolve import for ESM module - javascript

I'm trying to use ESM with typescript and webpack in an nx monorepo. After some configuration, I'm able to transpile to ESM with tsc. For this, I had to add a ".js" to the relative imports.
import { AppModule } from './app/app.module.js';
Now that I'm trying to use webpack, it doesn't seem to detect that it's a ESM. Here's the error that I'm getting:
ERROR in ./apps/nxnest/src/main.ts 9:0-48
Module not found: Error: Can't resolve './app/app.module.js' in '/home/gabriel/tmp/nxnest/apps/nxnest/src'
resolve './app/app.module.js' in '/home/.../tmp/nxnest/apps/nxnest/src'
using description file: /home/.../tmp/nxnest/package.json (relative path: ./apps/nxnest/src)
using description file: /home/.../tmp/nxnest/package.json (relative path: ./apps/nxnest/src/app/app.module.js)
no extension
/home/.../tmp/nxnest/apps/nxnest/src/app/app.module.js doesn't exist
.ts
/home/.../tmp/nxnest/apps/nxnest/src/app/app.module.js.ts doesn't exist
.tsx
/home/.../tmp/nxnest/apps/nxnest/src/app/app.module.js.tsx doesn't exist
.mjs
/home/.../tmp/nxnest/apps/nxnest/src/app/app.module.js.mjs doesn't exist
.js
/home/.../tmp/nxnest/apps/nxnest/src/app/app.module.js.js doesn't exist
.jsx
/home/.../tmp/nxnest/apps/nxnest/src/app/app.module.js.jsx doesn't exist
as directory
/home/.../tmp/nxnest/apps/nxnest/src/app/app.module.js doesn't exist
webpack 5.75.0 compiled with 1 error in 1968 ms
Because I've to specify ".js" in the import, webpack try to look for it, but I'm using typescript so the file doesn't exists.
Any idea how to fix it?

Related

ESM import resulting in "Cannot resolve path" in IntelliJ

Using IntelliJ IDEA 2021.3.2, Build #IU-213.6777.52
IntelliJ is complaining of Cannot resolve directory 'webpack' when encountering the following line in my webpack.config.js file.
import ModuleFederationPlugin from 'webpack/lib/container/ModuleFederationPlugin.js';
This is how the IDE is highlighting my import:
No issues at build or runtime, and when I Command-Click on this import, it takes me to the ModuleFederationPlugin.js file in my node_modules folder.

Webpack with target node/electron-main not recognizing import node:process

I updated the node module fix-pathbecause it was crashing intermittently.
After updating the node module I cannot use it in my main.js file as it throws the following error:
So instead of using it in the main js, I moved this piece of code to a different file which goes through the webpack build process. But then the webpack build fails as it does not recognize 'node:process'.
ERROR in ./node_modules/default-shell/index.js
Module not found: Error: Can't resolve 'node:os' in '/Users/shashi/projects/trici-atman-desktop/node_modules/default-shell'
resolve 'node:os' in '/Users/shashi/projects/trici-atman-desktop/node_modules/default-shell'
Parsed request is a module
using description file: /Users/shashi/projects/trici-atman-desktop/node_modules/default-shell/package.json (relative path: .)
resolve as module
/Users/shashi/projects/trici-atman-desktop/node_modules/default-shell/node_modules doesn't exist or is not a directory
/Users/shashi/projects/trici-atman-desktop/node_modules/node_modules doesn't exist or is not a directory
/Users/shashi/projects/node_modules doesn't exist or is not a directory
/Users/shashi/node_modules doesn't exist or is not a directory
/Users/node_modules doesn't exist or is not a directory
/node_modules doesn't exist or is not a directory
looking for modules in /Users/shashi/projects/trici-atman-desktop/node_modules
using description file: /Users/shashi/projects/trici-atman-desktop/package.json (relative path: ./node_modules)
using description file: /Users/shashi/projects/trici-atman-desktop/package.json (relative path: ./node_modules/node:os)
no extension
/Users/shashi/projects/trici-atman-desktop/node_modules/node:os doesn't exist
*
/Users/shashi/projects/trici-atman-desktop/node_modules/node:os* doesn't exist
.js
/Users/shashi/projects/trici-atman-desktop/node_modules/node:os.js doesn't exist
.json
/Users/shashi/projects/trici-atman-desktop/node_modules/node:os.json doesn't exist
as directory
/Users/shashi/projects/trici-atman-desktop/node_modules/node:os doesn't exist
[/Users/shashi/projects/trici-atman-desktop/node_modules/default-shell/node_modules]
[/Users/shashi/projects/trici-atman-desktop/node_modules/node_modules]
[/Users/shashi/projects/node_modules]
[/Users/shashi/node_modules]
[/Users/node_modules]
[/node_modules]
[/Users/shashi/projects/trici-atman-desktop/node_modules/node:os]
[/Users/shashi/projects/trici-atman-desktop/node_modules/node:os*]
[/Users/shashi/projects/trici-atman-desktop/node_modules/node:os.js]
[/Users/shashi/projects/trici-atman-desktop/node_modules/node:os.json]
# ./node_modules/default-shell/index.js 2:0-33 12:18-26
# ./node_modules/shell-env/index.js
# ./node_modules/shell-path/index.js
# ./node_modules/fix-path/index.js
# ./desktopServices/AppService.js
# ./desktopServices/desktopServices.js
After seeing the answer to this question, I tried changing the target of my webpack from electron-main to node. But it still did not recognize.
How do I fix this?
This was fixed by upgrading webpack from 4 to 5.

Use Hardhat ES5 together with Sveltekit ES6

I'd like to use Sveltekit together with hardhat but hardhat uses commonjs require syntax, if run npx hardhat test with js ending I get the error:
Error [ERR_REQUIRE_ESM]: require() of ES Module hardhat.config.js from node_modules\hardhat\internal\core\config\config-loading.js not supported. hardhat.config.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules. Instead rename hardhat.config.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).
If I change to type: commonjs I get this error if I run npm run dev:
Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
svelte.config.js:1
import preprocess from "svelte-preprocess";
^^^^^^
SyntaxError: Cannot use import statement outside a module
If I change svelte.config.js to svelte.config.mjs I get the follwing error: You need to create a svelte.config.js file and if I rename hardhat.config.js hardhat doesn't find the config and wants to create a new project.
Is there any way to combine these two even tho there is a mixture of import and require statements?

Importing a module in typescript which does't exist yet, but will be present in the build directory

I have typescript module and a sass file for a component which exist in one directory. The typescript file will be transpiled at some path in the build directory and sass file will also be compiled to css file at same path in the build directory. Now I want to import css string from the compiled file which exist in the build directory. But while importing it in typescript its giving error that file doesn't exist. Now that is true that css file from which I'm trying to import doesn't exist yet, but it will be present relative to the compiled javascript file in the build directory. How to resolve this issue?
In typescript file I'm importing like this
import navbarStyles from './navbar.css';
The directory structure is
- /navbar
| - navbar.ts
| - navbar.scss
Expected result: I should be able to import string from css file as expected.
You can use wildcard module declaration. Putting something like the following in a css-modules.d.ts file (name doesn't matter) anywhere (usually in root) would work.
declare module "*.css" {
const path: string;
export default path;
// anything else that the bundler exports
}
If you are also bundling scss using webpack or something like that, import "./navbar.scss" would also work.

Does ts-node support '#' style import? If so, how to set it up?

I'm creating a command-line script, using classes from the main express app.
Script resides in the folder:
bin/utils/
├── sync-buyers.ts
└── tsconfig.json
The main express app is in /app use uses import '#/foo/bar/thing.
This is set up in the tsconfig.json of the main app, as follows:
"paths": {
"#/*": ["*"],
"*": [
"node_modules/*",
"app/typings/*"
]
}
},
"include": ["app/**/*", "test/**/*"],
"exclude": ["app/**/*.test.ts", "/__tests__/", "/__mocks__/", "/__snapshots__/", "app/**/__mocks__/"],
"files": ["typings/global.d.ts"]
Script Execution
I'm testing to see if I can import from the main app, so I created a sayHello() function.
#!/usr/bin/env ts-node
/* tslint:disable */
import { sayHello } from '../../app/services/v2/oapp';
sayHello();
When I run it:
TSError: ⨯ Unable to compile TypeScript:
../../app/services/v2/oapp.ts(9,19): error TS2307: Cannot find module
'#/helpers/fetch'.
../../app/services/v2/oapp.ts(10,31): error TS2307: Cannot find module
'#/services/v2/buyer'.
../../app/services/v2/oapp.ts(11,51): error TS2307: Cannot find module
'#/http/HttpHeader'.
Summary:
Does ts-node support '#' style of import? If so, how do I set it up?
So the TypeScript paths configuration only applies to TypeScript's type resolution and checking, meaning that it will allow TypeScript to understand those imports for the purposes of type-checking only, but the code it generates won't automatically rewrite those imports to the correct locations.
There's two common approaches for solving this:
Update the Node resolver to understand the TypeScript paths config. The generated files will still refer to those paths by their #-name.
Most commonly, the tsconfig-paths module is used for this. You can require that module from the node command directly:
node -r tsconfig-paths/register main.js
Rewrite the generated files so that the #-names get replaced with the "real" local relative path locations.
There's a standalone module for this, tspath - you simply run tspath after compiling your TypeScript, and it updates the generated files with the correct paths.
If you're using Webpack, you can also use tsconfig-paths-webpack-plugin, which will take care of configuring Webpack's resolver to correctly locate those #-name paths.
And finally if you're using Babel, you might be interested in babel-plugin-module-resolver which does a similar thing for the Babel toolchain, however the downside here is it doesn't read the paths config from tsconfig.json, so you essentially have to duplicate your paths config in the alias config of this plugin.
Personally I'd recommend tsconfig-paths if this is a Node script or server that's compiled with tsc directly and tsconfig-paths-webpack-plugin if this is a frontend Webpack build.

Categories

Resources