Skip to content
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

error on build: "MongoInternals" is not exported by "meteor/mongo" #279

Open
alisnic opened this issue Jan 17, 2025 · 2 comments
Open

error on build: "MongoInternals" is not exported by "meteor/mongo" #279

alisnic opened this issue Jan 17, 2025 · 2 comments

Comments

@alisnic
Copy link

alisnic commented Jan 17, 2025

This constant is actually exported by the meteor/mongo package

Sample code:

import { MongoInternals } from 'meteor/mongo';

async function runTransactionWithRetry<T>(asyncFunction: (session: ClientSession) => Promise<T>): Promise<T | null> {
  let result: T | null = null;

  await MongoInternals.defaultRemoteCollectionDriver().mongo.client.withSession(async session => {
    await session.withTransaction(async () => {
      result = await asyncFunction(session);
    });
  });

  return result;
}

my package versions:

    "meteor-vite": "^3.1.2",
    "vite": "^6.0.7

Meteor version 3.0.4

Vite config:

import react from '@vitejs/plugin-react';
import fs from 'fs';
import { meteor } from 'meteor-vite/plugin';
import path from 'path';
import { defineConfig } from 'vite';
import { nodePolyfills } from 'vite-plugin-node-polyfills';

export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname)
    }
  },
  plugins: [
    nodePolyfills(),
    react({ fastRefresh: false }),
    meteor({
      clientEntry: 'imports/startup/client/index.ts',
      stubValidation: {
        warnOnly: true
      },
      meteorStubs: {
        debug: false
      }
    })
  ],
  optimizeDeps: {
    exclude: ['@meteor-vite/react-meteor-data', 'io-ts'],
    esbuildOptions: {
      plugins: [
        {
          name: 'esbuild-plugin-react-virtualized',
          setup({ onLoad }) {
            onLoad(
              {
                filter: /react-virtualized[/\\]dist[/\\]es[/\\]WindowScroller[/\\]utils[/\\]onScroll\.js$/
              },
              async ({ path }) => {
                const code = fs.readFileSync(path, 'utf8');
                const broken = `import { bpfrpt_proptype_WindowScroller } from "../WindowScroller.js";`;
                return { contents: code.replace(broken, '') };
              }
            );
          }
        }
      ]
    }
  }
});

The error does not happen when starting the server locally

@alisnic alisnic changed the title "MongoInternals" is not exported by "meteor/mongo" error on build: "MongoInternals" is not exported by "meteor/mongo" Jan 17, 2025
@alisnic
Copy link
Author

alisnic commented Jan 17, 2025

Here is a repo that reproduces the problem - run meteor build ../some/path to reproduce. The problem is in conditionally imported code under if (Meteor.isServer). Somehow meteor-vite tries to import Meteor package in server mode on the client https://github.com/alisnic/meteor3-tla-repro/tree/meteor-vite

export async function isoFunc() {
  if (Meteor.isServer) {
    const { runTransactionWithRetry } = await import('/server/internals.ts')
    runTransactionWithRetry()
  } else {
    console.log('client!');
  }
}

@JorgenVatle
Copy link
Owner

Oh, thanks for the heads up on this. 🙌

Meteor-Vite does not currently have full support for Meteor-specific conditional imports. I'm not sure if there's any good way of implementing this behavior due to the way Vite analyzes module dependencies. Refactoring to use Vite's suggested environment-specific conditionals should help indicate to Vite that the module shouldn't be imported on the client.

export async function isoFunc() {
-  if (Meteor.isServer) {
+  if (import.meta.env.SSR) { 
    const { runTransactionWithRetry } = await import('/server/internals.ts')
    runTransactionWithRetry()
  } else {
    console.log('client!');
  }
}

We may be able to do a find and replace for conditionals like this, though I worry there may be a risk of unwanted/hard-to-debug behavior if it matches something it shouldn't. I'll definitely have a closer look at ways to handle this, at least for the Meteor runtime variables like isProduction and isClient.

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