I am trying hard to use vanilla ES modules (apparently not hard enough, I haven’t made changes to Meteor directly yet).
I have this .meteor/packages
to avoid modules
and ecmascript
(there is much less need for those today, and most likely you only really need them if you’re using the new stage 3 decorators):
meteor-base@1.5.2-beta300.0 # Packages every Meteor app needs to have
mobile-experience@1.1.1-beta300.0 # Packages for a great mobile UX
mongo@2.0.0-beta300.0 # The database Meteor supports right now
reactive-var@1.0.13-beta300.0 # Reactive variable for tracker
# commented stuff out, starting simple, avoiding problems
#standard-minifier-css@1.9.2 # CSS minifier run for production mode
#standard-minifier-js@2.8.1 # JS minifier run for production mode
#es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers
#ecmascript@0.16.7 # Enable ECMAScript2015+ syntax in app code
#typescript@4.9.4 # Enable TypeScript syntax in .ts and .tsx modules
shell-server@0.6.0-beta300.0 # Server-side component of the `meteor shell` command
hot-module-replacement@0.5.4-beta300.0 # Update client in development without reloading the page
static-html@1.3.3-beta300.0 # Define static page content in .html files
#accounts-ui # not supported in 3.0 yet, fails with constraint error
#accounts-password
session
and the release is METEOR@3.0-beta.0
.
Now, for server code, placing "type": "module"
in package.json
will break Meteor 3.0:
So I tried to work around that, by setting package.json back to "type":"commonjs"
, defining meteor.mainModule
,
"meteor": {
"mainModule": {
"client": "client/entry.js",
"server": "server/entry.js"
}
}
and then using eval
to force Meteor to skip handling of import()
syntax (why is it handling my import()
syntax when I removed ecmascript
and typesceript
packages anyway?):
//server/entry.js
function nativeImport(path) {
console.log('eval import')
return eval(`import('${path}')`)
}
nativeImport('./imports/test.js').then(({foo}) => console.log('foo', foo))
//./imports/test.js
export const foo = 123
This results in Node.js telling me that import()
is not available inside of a vm
:
I20240106-01:09:39.825(-8)? eval import
W20240106-01:09:39.825(-8)? (STDERR) node:internal/errors:497
W20240106-01:09:39.825(-8)? (STDERR) ErrorCaptureStackTrace(err);
W20240106-01:09:39.825(-8)? (STDERR) ^
W20240106-01:09:39.825(-8)? (STDERR)
W20240106-01:09:39.825(-8)? (STDERR) TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]: A dynamic import callback was not specified.
W20240106-01:09:39.825(-8)? (STDERR) at new NodeError (node:internal/errors:406:5)
W20240106-01:09:39.825(-8)? (STDERR) at importModuleDynamicallyCallback (node:internal/modules/esm/utils:144:9)
W20240106-01:09:39.825(-8)? (STDERR) at eval (eval at nativeImport (app/server/entry.js:21:12), <anonymous>:1:1)
W20240106-01:09:39.825(-8)? (STDERR) at nativeImport (app/server/entry.js:21:12)
W20240106-01:09:39.825(-8)? (STDERR) at app/server/entry.js:23:1
W20240106-01:09:39.825(-8)? (STDERR) at app/server/entry.js:52:4
W20240106-01:09:39.825(-8)? (STDERR) at load (packages/core-runtime.js:139:16)
W20240106-01:09:39.825(-8)? (STDERR) at onDepLoaded (packages/core-runtime.js:118:7)
W20240106-01:09:39.825(-8)? (STDERR) at packages/core-runtime.js:153:7
W20240106-01:09:39.825(-8)? (STDERR) at Array.forEach (<anonymous>)
W20240106-01:09:39.825(-8)? (STDERR) at packages/core-runtime.js:152:22
W20240106-01:09:39.825(-8)? (STDERR) at evaluateNextModule (packages/core-runtime.js:179:14)
W20240106-01:09:39.825(-8)? (STDERR) at packages/core-runtime.js:194:9 {
W20240106-01:09:39.825(-8)? (STDERR) code: 'ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING'
W20240106-01:09:39.825(-8)? (STDERR) }
W20240106-01:09:39.825(-8)? (STDERR)
W20240106-01:09:39.825(-8)? (STDERR) Node.js v20.9.0
Now I’m wondering what hoops I need to jump through next to get this code to not run in a vm
, but as regular Node.js code.
I tried passing the --experimental-vm-modules
option for Node, like this,
SERVER_NODE_OPTIONS=--experimental-vm-modules meteor --exclude-archs web.browser.legacy
but that didn’t do anything.
I’m guessing that at this point I would need to modify Meteor directly to achieve running native ES modules.
I really hope this can be a goal for 3.x because it is a major area in which Meteor is still lagging behind for a long time already.