originjs / vite-plugin-federation

Module Federation for vite & rollup
Other
2.34k stars 240 forks source link

Cannot import scoped css from remote component into host app #361

Open estellegr opened 1 year ago

estellegr commented 1 year ago

When I import a remote component into my host app, css inside a styled tag with the scoped attribute does not get loaded. However, when I use the module attribute (or no attribute at all) it works fine.

Versions

Reproduction

remote/src/Header.vue

<script setup lang="ts"></script>

<template>
  <div class="header">
    <div class="header__logo">
      <img src="@/assets/vue.svg" alt="logo" />
    </div>
    <div class="header__title">
      <h1>Remote Header</h1>
    </div>
  </div>
</template>

<style scoped>
.header {
  display: flex;
  align-items: center;
  column-gap: 1.6rem;
  padding: 1.6rem;
  border-bottom: 1px solid #e5e5e5;
}
</style>

host/src/components/Home.vue

<script lang="ts">
import Header from 'remote-app/Header';
</script>

<template>
  <Header />
  <h3>Home Content (Local)</h3>
</template>

remote/vite.config.ts

/// <reference types="vitest" />
import { defineConfig } from 'vite';
import { resolve } from 'path'

import viteTsConfigPaths from 'vite-tsconfig-paths';
import vue from '@vitejs/plugin-vue';
import federation from "@originjs/vite-plugin-federation";

const pathSrc = resolve(__dirname, "src");

export default defineConfig({
  cacheDir: '../../node_modules/.vite/remote',

  server: {
    port: 5001,
    host: 'localhost',
  },

  preview: {
    port: 5001,
    host: 'localhost',
  },

  base: process.env.NODE_ENV === "production" ? "http://localhost:5001/" : "/",

  resolve: {
    alias: {
      '@': `${pathSrc}`,
    },
  },

  plugins: [
    vue(),
    viteTsConfigPaths({
      root: '../../',
    }),
    federation({
      name: 'remote-app',
      filename: 'remoteEntry.js',
      exposes: {
        './Header': `${pathSrc}/Header.vue`,
      }
  }),
  ],

  build: {
    target: "esnext",
    assetsInlineLimit: 40960,
    cssCodeSplit: false,
    sourcemap:true,
    rollupOptions: {
      output: {
        minifyInternalExports: false
      }
    }
  },
});

host/vite.config.ts

/// <reference types="vitest" />
import { defineConfig, searchForWorkspaceRoot } from 'vite';
import vue from '@vitejs/plugin-vue'
import federation from "@originjs/vite-plugin-federation";

export default defineConfig({
  cacheDir: '../../node_modules/.vite/host',

  server: {
    port: 5000,
    host: 'localhost',
    fs: {
      allow: [
        searchForWorkspaceRoot(process.cwd()),
        "../..",
      ]
    }
  },

  preview: {
    port: 5000,
    host: 'localhost',
  },

  plugins: [
    vue(),
    federation({
      name: 'host',
      filename: 'remoteEntry.js',
      remotes: {
        "remote-app": 'http://localhost:5001/assets/remoteEntry.js',
      },
      shared: ['vue']
    })
  ],

  build: {
    target: 'esnext',
    cssCodeSplit: true,
    minify: false,
    rollupOptions: {
      output: {
        format: 'system',
        entryFileNames: 'assets/[name].js',
        minifyInternalExports: false
      }
    }
  },
});

What is Expected?

When using <style module> or <style> I get the correct CSS :

Capture d’écran 2023-02-21 à 11 45 13

What is actually happening?

With <style scoped> I don't have any styling :

Capture d’écran 2023-02-21 à 11 48 52

Thanks for your help 🙏

estellegr commented 1 year ago

After searching, I found that in my In my dist/Header.css I've got this :

.header[data-v-e0f4b3c9]{display:flex;align-items:center;column-gap:1.6rem;padding:1.6rem;border-bottom:1px solid #e5e5e5}

Turns out the attribute generated by the scoped attribute is given to the component children as the following (look for the attribute data-v-e0f4b3c9)

Capture d’écran 2023-02-22 à 11 43 32

If I set the attribute data-v-e0f4b3c9 to the header div, it works :

Capture d’écran 2023-02-22 à 11 43 46

Anybody has a workaround to set the attribute data-v-e0f4b3c9 to the correct node ?

david2am commented 1 year ago

an awful workaround is to use a <div> as the parent in the meanwhile 😅

zacard-orc commented 1 year ago

i met the same problem. I have to use css syntex without scoped in component project, but it may invoke other repeat css name problem

Becessary commented 1 year ago

没错,老夫也遇到了。而且正如3楼老外哥说的,还需要如vue2保持根元素唯一。

weilephp commented 3 months ago

After searching, I found that in my In my dist/Header.css I've got this :

.header[data-v-e0f4b3c9]{display:flex;align-items:center;column-gap:1.6rem;padding:1.6rem;border-bottom:1px solid #e5e5e5}

Turns out the attribute generated by the scoped attribute is given to the component children as the following (look for the attribute data-v-e0f4b3c9) Capture d’écran 2023-02-22 à 11 43 32

If I set the attribute data-v-e0f4b3c9 to the header div, it works : Capture d’écran 2023-02-22 à 11 43 46

Anybody has a workaround to set the attribute data-v-e0f4b3c9 to the correct node ?

I have the same problem, how did you solve it? please help!