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

The import paths in the built remote entry file do not use the base path configured in vite.config. #217

Open
baijunjie opened this issue Dec 9, 2024 · 6 comments

Comments

@baijunjie
Copy link

Under normal circumstances, the reference paths for resource files built by a plugin should align with the base path specified in the Vite config.

The filename of the exposed remote module usually doesn't include a hash because it's the entry point for remote modules and needs to be accessible by external applications. Therefore, it is typically deployed separately on Nginx, while other resources are placed on a CDN. If a relative path is used, it can cause a bug where files can't be found.

vite.config.js

import { federation } from '@module-federation/vite'

export default {
  base: 'https://cdn.example.com/project-name',
  ...
  plugins: [
    federation({
      name: 'remote',
      filename: 'remote.js',
      exposes: {
        './preload': './src/preload',
      },
      shared: [],
    }),
  ],
}

output remote.js

image
@baijunjie
Copy link
Author

baijunjie commented Dec 9, 2024

For those eager to resolve this issue quickly, I’m providing the following workaround until the author fixes the problem.

vite.config.js

import { federation } from '@module-federation/vite'
import fs from 'node:fs'
import path from 'node:path'

const CDN_ORIGIN = 'https://cdn.example.com/project-name'
export default {
  base: CDN_ORIGIN,
  ...
  plugins: [
    federation({
      name: 'remote',
      filename: 'remote.js',
      exposes: {
        './preload': './src/preload',
      },
      shared: [],
    }),
    {
      name: 'modify-remote-js',
      apply: 'build',
      closeBundle () {
        const outputDir = path.resolve(__dirname, 'dist')
        const fileToProcess = path.join(outputDir, 'remote.js')
        if (fs.existsSync(fileToProcess)) {
          let content = fs.readFileSync(fileToProcess, 'utf-8')
          // For assets deploy to CDN
          content = content.replace(/\.\/assets/g, `${CDN_ORIGIN}/assets`)
          // Fixed: [Uncaught TypeError] i is not a function at hostInit-xxx.js
          content = content.replace('init,', 'init=function(){},')
          fs.writeFileSync(fileToProcess, content)
        }
      },
    },
  ],
}

@gioboa
Copy link
Collaborator

gioboa commented Dec 9, 2024

Thanks @baijunjie for your help, would you like to drop a PR for that?

@baijunjie
Copy link
Author

baijunjie commented Dec 10, 2024

@gioboa I’m very willing to provide a PR, but there are some issues I haven’t fully understood yet, so I’m not sure how to make the modifications.

I found the template code for the remote entry file, but noticed that the path is a placeholder virtual:mf-exposes. However, I couldn’t locate the relevant code where this placeholder is handled.

/src/virtualModules/virtualExposes.ts

const VIRTUAL_EXPOSES = 'virtual:mf-exposes'

/src/virtualModules/virtualRemoteEntry.ts

`import exposesMap from "${VIRTUAL_EXPOSES}"`

@gioboa
Copy link
Collaborator

gioboa commented Dec 10, 2024

@baijunjie Thanks, you can search VIRTUAL_EXPOSES and you will find where is used 💪
eg.

if (id === VIRTUAL_EXPOSES) {
  return generateExposes();
}

@baijunjie
Copy link
Author

baijunjie commented Dec 12, 2024

@gioboa I tried debugging generateExposes() and generateRemoteEntry(), but unfortunately, the output is not the final content of the file since it doesn’t include any information about the code file import paths. It seems the final exported content might be unrelated to this plugin. The issue could also lie with Vite or Rollup—I’m not sure.

I have a question: in this case, how exactly is the remote entry file remote.js generated? From the plugin code, it seems to be created through a Vite or Rollup.

@zhangHongEn
Copy link
Contributor

Use https://module-federation.io/configure/manifest.html and configure the remoteEntry file to include a hash for placement on a CDN.

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

3 participants