Conditional imports aren't properly tree-shaken when using Meteor's runtime/environment variables
Environment-specific conditional imports aren't handled the same way Meteor normally does.
The following snippet would result in ./server/some-module being included in the client bundle. It won't be loaded by the client during runtime, but is still available if it compiles:
if (Meteor.isServer) {
await import('./server/some-module') // This should not be included into the client.
}
The current workaround is to use Vite's special import.meta.env variables when you need to conditionally import modules based on the current runtime.
- if (Meteor.isServer) {
+ if (import.meta.env.SSR) {
await import('./server/some-module') // This will now be omitted outright from the client bundle.
}
References:
- https://vite.dev/guide/env-and-mode.html#env-variables
- https://vite.dev/guide/ssr.html#conditional-logic
Related issue:
- https://github.com/JorgenVatle/meteor-vite/issues/279
Hey, thanks for quick response! Unfortunately I stumbled into another problem, it seems that meteor bundler does not like import meta:
SyntaxError: Cannot use 'import.meta' outside a module
at new Script (node:vm:117:7)
at createScript (node:vm:269:10)
at Object.runInThisContext (node:vm:317:10)
at /tools/static-assets/server/boot.js:414:32
at /tools/static-assets/server/boot.js:503:13
at AsyncLocalStorage.run (node:async_hooks:346:14)
at /tools/static-assets/server/boot.js:502:48
at Function.run (<redacted>/.meteor/local/build/programs/server/tools/tool-env/profile.ts:315:14)
at startServerProcess (/tools/static-assets/server/boot.js:501:17)
at Object.<anonymous> (/tools/static-assets/server/boot.js:508:2)
at Object.<anonymous> (/tools/static-assets/server/boot.js:512:4)
at Module._compile (node:internal/modules/cjs/loader:1469:14)
at Module.Mp._compile (/tools/static-assets/server/runtime.js:78:21)
at Object.Module._extensions..js (/tools/static-assets/server/runtime.js:112:21)
at Module.load (node:internal/modules/cjs/loader:1288:32)
at Module.Mp.load (/tools/static-assets/server/runtime.js:35:31)
Is there a way to fix this? Seems related to https://github.com/meteor/meteor/issues/12324
Note for other people, as a workaround you can write a Vite plugin that will transform Meteor.isServer condition to import.meta.env.SSR:
// vite.config.js
export default defineConfig({
plugins: [meteorIsServerPlugin()]
})
function meteorIsServerPlugin() {
return {
name: 'meteor-isserver-plugin',
enforce: 'pre',
transform(code, id) {
if (code.includes('Meteor.isServer')) {
console.log('transforming Meteor.isServer', id);
return {
code: code.replace(/\bMeteor\.isServer\b/g, 'import.meta.env.SSR'),
map: null
};
}
return { code, map: null };
}
};
}
@alisnic Hmm, unless I'm mistaken the import.meta blocks should be omitted from the build that's passed onto Meteor. Does your Meteor entry module contain any imports for your application code?
If you have a repository that reproduces the error message there I'd have a closer look for you. 👍
I use meteor-vite only for client bundle. When Meteor builds server bundle it does not understand import.meta. But that doesn't matter because the plugin I wrote above fixes the problem