Skip to content

Node.js errors when running emconfigure ./configure when there exists a package.json with type: "module" #24244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jeremy-code opened this issue May 2, 2025 · 2 comments

Comments

@jeremy-code
Copy link

jeremy-code commented May 2, 2025

Version

emscripten/[email protected]

# emcc -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.8 (70404efec4458b60b953bc8f1529f2fa112cdfd1)
clang version 21.0.0git (https:/github.com/llvm/llvm-project 23e3cbb2e82b62586266116c8ab77ce68e412cf8)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /emsdk/upstream/bin
# node -v
v20.18.0
# which node
/emsdk/node/20.18.0_64bit/bin/node

Description

Suppose you had the following files: configure.ac, dummy.c, and package.json. (Note: this is true even if package.json is not in the root directory, only such that the nearest package.json to cwd has type: module.)

# configure.ac
AC_INIT([dummy], [0.1])
AC_CONFIG_SRCDIR([dummy.c])
AC_PROG_CC
AC_OUTPUT
// dummy.c
int x = 20;
{
  // package.json
  "type": "module"
}

Failing command line in full:

autoreconf && emconfigure ./configure (or any variation that uses autoconf)

Terminal output:

configure: ./configure
checking for gcc... /emsdk/upstream/emscripten/emcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... configure: error: in `/src':
configure: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
See `config.log' for more details
emconfigure: error: './configure' failed (returned 77)

Snippet of output of config.log (full output here: https://pastebin.com/mWuRPrUP, or with EMCC_DEBUG=1 here: https://pastebin.com/aDECYhHk)

# config.log
...
configure:2721: checking whether we are cross compiling
configure:2729: /emsdk/upstream/emscripten/emcc -o conftest    conftest.c  >&5
configure:2733: $? = 0
configure:2740: ./conftest
file:///src/conftest:79
  var fs = require('fs');
           ^

ReferenceError: require is not defined in ES module scope, you can use import instead
    at file:///src/conftest:79:12
    at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:473:24)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:123:5)

Node.js v20.18.0
configure:2744: $? = 1
configure:2751: error: in `/src':
configure:2753: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.

Indeed, if you remove the type: module from package.json, config.log will look like this:

configure:2721: checking whether we are cross compiling
configure:2729: /emsdk/upstream/emscripten/emcc -o conftest    conftest.c  >&5
configure:2733: $? = 0
configure:2740: ./conftest
configure:2744: $? = 0
configure:2759: result: no
configure:2764: checking for suffix of object files

and a.wasm, config.status will be generated.

In regards to conftest, this is the the output of /emsdk/upstream/emscripten/emcc -o conftest conftest.c and conftest.c is

/* confdefs.h */
#define PACKAGE_NAME "dummy"
#define PACKAGE_TARNAME "dummy"
#define PACKAGE_VERSION "0.1"
#define PACKAGE_STRING "dummy 0.1"
#define PACKAGE_BUGREPORT ""
#define PACKAGE_URL ""
/* end confdefs.h.  */
#include <stdio.h>
int
main (void)
{
FILE *f = fopen ("conftest.out", "w");
 return ferror (f) || fclose (f) != 0;
 
  ;
  return 0;
}

I believe the reason this occurs is that a feature was added to automatically detect extensionless modules based on the nearest package.json in v21.0.0, and this was backported to 20.10.0. Setting --experimental-default-type=commonjs doesn't seem to fix it though.

I haven't found any solutions for this other than generating a package.json in the build directory with npm init --yes or deleting that type: "module".

@sbc100
Copy link
Collaborator

sbc100 commented May 2, 2025

Yeah it kind of sucks that node doesn't support forcing commonjs from the command line.

I guess one possible solution would be to convert all configure tests to use .mjs and ES modules? Would using the .mjs extensions for ES module mode even if type: module were not in the package.json? i.e. does mjs force module mode?

@jeremy-code
Copy link
Author

Yeah it kind of sucks that node doesn't support forcing commonjs from the command line.

I guess one possible solution would be to convert all configure tests to use .mjs and ES modules? Would using the .mjs extensions for ES module mode even if type: module were not in the package.json? i.e. does mjs force module mode?

Yeah, I'm empathetic that this issue isn't on Emscripten's end and is more of a quirk of Node.js. Personally, I'm fine with my solution of just running npm init --yes in any directories with a configure script since from what I can tell, while autodetecting module syntax is now unflagged (as of v22.7.0), it's still not recommended due to a bit of overhead and adding type: "module" to ES packages is still recommended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants