I am attempting to use the vite-plugin-federation described here: to allow a Vue application to use remote modules developed by others. The application is Javascript based, but it has a Typescript build config, much like the examples presented with the vite-plugin.
I was able to successfully use a remote module in my application when I hardcoded the URL to it in the vite-config.ts file. What I need though is to be able to specify the modules to be loaded at runtime (not in the vite-config.ts) and for this the documentation suggests using virtual:__federation. I followed the example of using the
import {__federation_method_getRemote as getRemote,
__federation_method_setRemote as setRemote,
__federation_method_unwrapDefault as unwrapModule,
type IRemoteConfig,
} from "virtual:__federation__";
in my Vue component, but the production build fails with this error:
error during build:
[vite:load-fallback] Could not load virtual__federation__ (imported by src/utils/moduleFederation.ts): The argument 'path' must be a string, Uint8Array, or URL without null bytes. Received '\x00virtual:__federation__'
TypeError [PLUGIN_ERROR]: Could not load virtual:__federation__ (imported by src/utils/moduleFederation.ts): The argument 'path' must be a string, Uint8Array, or URL without null bytes. Received '\x00virtual:__federation__'
The vite-plugin-federation documentation suggests to add a module declaration for virtual:__federation__ when working in a Typescript envrionment as I am doing and have done so in a separate file, "__federation__.d.ts". I included this in the tsconfig.app.json file but it still gives the same error in my application
Have therefore created this repo to present the problem in a simple project. In this project, I have put the usage of the virtual federation functions into a utils\moduleFederation.ts file and importing that as a composable into the HelloWorld.vue.
When the HelloWorld.vue script language is Javascript, I get exactly the same error that I see in my production application. When it is Typescript (), the import seems to be successful but it is still failing with the same error, it's just happening later.
My tsconfig.app.ts:
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
/* Linting */
"strict": true,
"noUnusedLocals": false,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"allowJs": true,
},
"include": [
"__federation__.d.ts",
"src/**/*.js",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue"
]
}
My vite-config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import federation from "@originjs/vite-plugin-federation";
// /config/
export default defineConfig({
plugins: [
vue(),
federation({
name: "agent",
filename: "remoteEntry.js",
shared: { vue: { modulePreload: true } },
}),
],
esbuild: {
supported: {
"top-level-await": true,
},
},
build: {
target: 'esnext',
minify: false,
cssCodeSplit: true,
rollupOptions: {
output: {
minifyInternalExports: false
}
}
}
});
HellowWorld.vue
<script setup lang="ts">
// This will work when using lang="ts" in the <script> tag
import {onMounted, ref} from 'vue'
import { useFederation } from '../utils/moduleFederation.ts'
modulefederation.ts
import {
__federation_method_setRemote as setRemote,
__federation_method_getRemote as getRemote,
__federation_method_unwrapDefault as unwrapModule
} from 'virtual:__federation__'
export function useFederation() {
function setModule(moduleName: string, url: string) {
setRemote(moduleName, {
url: () => Promise.resolve(url),
format: 'esm',
from: 'vite'
})
}
function getComponent(moduleName: string, componentName: string) : Object {
return getRemote(moduleName, `.\\${componentName}`).then((module) => {
unwrapModule(module).then((module) =>
Promise.resolve(module)
)
})
}
return {
setModule,
getComponent
}
}
Any ideas please? I'm sure that it must be a build parameter that I am missing but I can't work out what and it seems like it should be fairly straightforward from the documentation. As I understand it, the \0 prefix is always added for virtual module names but I don't understand why the extra '0' is there.
I am attempting to use the vite-plugin-federation described here: https://github.com/originjs/vite-plugin-federation to allow a Vue application to use remote modules developed by others. The application is Javascript based, but it has a Typescript build config, much like the examples presented with the vite-plugin.
I was able to successfully use a remote module in my application when I hardcoded the URL to it in the vite-config.ts file. What I need though is to be able to specify the modules to be loaded at runtime (not in the vite-config.ts) and for this the documentation suggests using virtual:__federation. I followed the example of using the
import {__federation_method_getRemote as getRemote,
__federation_method_setRemote as setRemote,
__federation_method_unwrapDefault as unwrapModule,
type IRemoteConfig,
} from "virtual:__federation__";
in my Vue component, but the production build fails with this error:
error during build:
[vite:load-fallback] Could not load virtual__federation__ (imported by src/utils/moduleFederation.ts): The argument 'path' must be a string, Uint8Array, or URL without null bytes. Received '\x00virtual:__federation__'
TypeError [PLUGIN_ERROR]: Could not load virtual:__federation__ (imported by src/utils/moduleFederation.ts): The argument 'path' must be a string, Uint8Array, or URL without null bytes. Received '\x00virtual:__federation__'
The vite-plugin-federation documentation suggests to add a module declaration for virtual:__federation__ when working in a Typescript envrionment as I am doing and have done so in a separate file, "__federation__.d.ts". I included this in the tsconfig.app.json file but it still gives the same error in my application
Have therefore created this repo https://github.com/paama/virtual-federation-test to present the problem in a simple project. In this project, I have put the usage of the virtual federation functions into a utils\moduleFederation.ts file and importing that as a composable into the HelloWorld.vue.
When the HelloWorld.vue script language is Javascript, I get exactly the same error that I see in my production application. When it is Typescript (), the import seems to be successful but it is still failing with the same error, it's just happening later.
My tsconfig.app.ts:
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
/* Linting */
"strict": true,
"noUnusedLocals": false,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"allowJs": true,
},
"include": [
"__federation__.d.ts",
"src/**/*.js",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue"
]
}
My vite-config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import federation from "@originjs/vite-plugin-federation";
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
federation({
name: "agent",
filename: "remoteEntry.js",
shared: { vue: { modulePreload: true } },
}),
],
esbuild: {
supported: {
"top-level-await": true,
},
},
build: {
target: 'esnext',
minify: false,
cssCodeSplit: true,
rollupOptions: {
output: {
minifyInternalExports: false
}
}
}
});
HellowWorld.vue
<script setup lang="ts">
// This will work when using lang="ts" in the <script> tag
import {onMounted, ref} from 'vue'
import { useFederation } from '../utils/moduleFederation.ts'
modulefederation.ts
import {
__federation_method_setRemote as setRemote,
__federation_method_getRemote as getRemote,
__federation_method_unwrapDefault as unwrapModule
} from 'virtual:__federation__'
export function useFederation() {
function setModule(moduleName: string, url: string) {
setRemote(moduleName, {
url: () => Promise.resolve(url),
format: 'esm',
from: 'vite'
})
}
function getComponent(moduleName: string, componentName: string) : Object {
return getRemote(moduleName, `.\\${componentName}`).then((module) => {
unwrapModule(module).then((module) =>
Promise.resolve(module)
)
})
}
return {
setModule,
getComponent
}
}
Any ideas please? I'm sure that it must be a build parameter that I am missing but I can't work out what and it seems like it should be fairly straightforward from the documentation. As I understand it, the \0 prefix is always added for virtual module names but I don't understand why the extra '0' is there.
Share Improve this question asked Feb 6 at 17:17 paapaa000paapaa000 434 bronze badges1 Answer
Reset to default 0Answer provided indirectly by someone else having the same problem and was replying to a page that I had previously visited: https://github.com/originjs/vite-plugin-federation/issues/549
The comment that resolved my issue: https://github.com/originjs/vite-plugin-federation/issues/502#issuecomment-1727954152
Had to add this to vite-config.js:
remotes: {
remoteName: '',
},