microsoft / fluentui

Fluent UI web represents a collection of utilities, React components, and web components for building web applications.
https://react.fluentui.dev
Other
18.36k stars 2.72k forks source link

[Feature]: Support Remix [SSR] #32825

Open it950 opened 2 weeks ago

it950 commented 2 weeks ago

Library

React Components / v9 (@fluentui/react-components)

Describe the feature that you would like added

Does fluentui v9 support remix? how to do it?

Have you discussed this feature with our team

No

Additional context

No response

Validations

Priority

None

ValentinaKozlova commented 2 weeks ago

@it950, could you please give more details?

it950 commented 2 weeks ago

In the remix document, css in js is not recommended, while fluentui v9 uses css in js technology. Therefore, can fluentui v9 be installed directly in remix? In addition, there is no introduction on how to use in remix in the fluent v9 document

ValentinaKozlova commented 2 weeks ago

In the remix document, css in js is not recommended, while fluentui v9 uses css in js technology. Therefore, can fluentui v9 be installed directly in remix? In addition, there is no introduction on how to use in remix in the fluent v9 document

Have you tried to install it? And have you tried to follow instruction of using SSR in V9? If it's not working, please let me know what errors you have

it950 commented 2 weeks ago

In the remix document, css in js is not recommended, while fluentui v9 uses css in js technology. Therefore, can fluentui v9 be installed directly in remix? In addition, there is no introduction on how to use in remix in the fluent v9 document

Have you tried to install it? And have you tried to follow instruction of using SSR in V9? If it's not working, please let me know what errors you have

I have created a remix start project only install @fluentui/react-components and @fluentui/react-icons, and only change the code in the root.ts:

export default function App() {
  return (
    <FluentProvider theme={webLightTheme}>
      <Outlet />
    </FluentProvider>
  );
}

An error like the following: image

How to setup a new remix project correctly that use a @fluent/react-components and @fluentui/react-icons ?

layershifter commented 1 week ago

The issue is that v9 does not support native ESM, see #26176 and #23508.


However, there is a workaround. Quoting myself from an internal chat:

Anyway, the source of the issue is that Fluent packages are bundled in a way that they does not really support native ESM:

// test.mjs
import { Button} from '@fluentui/react-components'
console.log(Button)

image

~But it's solvable with Vite if we bundle some deps (https://vitejs.dev/config/ssr-options.html#ssr-noexternal), this was enough to make it alive:~

export default defineConfig({
 plugins: [react()],
 ssr: {
   noExternal: /@fluentui|@swc|@floating-ui/,
 },
});

~I also put some CSS rendering rendering config (check entry-* files), altogether is there: https://stackblitz.com/edit/bluwy-create-vite-extra-qnzeak~

~And seems to work, I believe that for Remix itself it would be something similar.~ Edit: looks like it has own config https://remix.run/docs/en/main/guides/vite#configuration

And no, it won't work with Remix as they also use in dev Vite Runtime API 💥

I wrote a naive plugin that makes it work:

const fluentConfigPlugin: Plugin = {
 config(config, envConfig) {
   if (envConfig.mode === 'production') {
     return {
       ssr: {
         noExternal: /@fluentui|@swc|@floating-ui/,
       },
     };
   }

   return {
     legacy: {
       proxySsrExternalModules: true,
     },
   };
 },
};

With that - it should work for now, https://stackblitz.com/edit/remix-run-remix-i6tns1 🚀

it950 commented 1 week ago

@layershifter Much appreciated! 😊

  1. I added @fluent/react-icons base on your demo: https://stackblitz.com/edit/remix-run-remix-bi2gcp?file=app%2Froutes%2Ftest.tsx
  2. And then add a test page in routes folder.

There is an error like this: image

layershifter commented 1 week ago

@it950 indeed, sadly @fluentui/react-icons don't have the same export maps as other packages:

https://github.com/microsoft/fluentui/blob/c189a92730fbf4befd28fad97fc27638c277207d/packages/react-components/react-accordion/library/package.json#L62-L65

it950 commented 1 week ago

don't have the same export maps as other packages:

the makeStyles function also can not run, image

We are currently migrating v8 to v9, v8 used CRA before, and v9 uses nextjs at present. However, the speed of nextjs development environment is too slow, even with turbo, HRM loading is still very slow, so we want to test remix. but now remix is still hard to run with @fluentui/react-components, too many problems.

Can you give me some advice? Thank you

layershifter commented 5 days ago

Can you give me some advice? Thank you

Hey, this requires a proper investigation and unfortunately I don't have capacity to do a proper investigation now :(

georgetakla commented 1 day ago

@it950 regarding @fluentui/react-icons

@layershifter Much appreciated! 😊

  1. I added @fluent/react-icons base on your demo: https://stackblitz.com/edit/remix-run-remix-bi2gcp?file=app%2Froutes%2Ftest.tsx
  2. And then add a test page in routes folder.

There is an error like this: image

I used @layershifter idea of building a plugin and created one to fix the issues in this package ..

const fluentIconsFixPlugin: Plugin = {
  name: 'fluent-icons-fix-plugin',
  config(config, { mode }) {
    return {
      build: {
        rollupOptions: {
          output: {
            // Ensure files from @fluentui/react-icons are output correctly as ESM
            entryFileNames: (chunkInfo) => {
              if (chunkInfo.facadeModuleId && chunkInfo.facadeModuleId.includes('@fluentui/react-icons')) {
                return '[name].mjs'; // Use .mjs extension for ESM files
              }
              return '[name].js';
            },
          },
        },
      },
      ssr: {
        // Ensure @fluentui/react-icons is not treated as an external dependency during SSR
        noExternal: ['@fluentui/react-icons'],
      },
      optimizeDeps: {
        // Force Vite to pre-bundle @fluentui/react-icons as ESM
        include: ['@fluentui/react-icons'],
      },
    };
  },
};

I did not get the error, but not sure if the icons are displayed correctly .. try it and let us know