hood / vite-plugin-shadow-style

A Vite plugin to inject css styles into the shadow root of web components.
17 stars 3 forks source link

`SHADOW_STYLE` not defined with dev server #5

Closed panta82 closed 1 month ago

panta82 commented 5 months ago

It seems SHADOW_STYLE is not defined when running the dev server (npm run dev), only in production builds.

Is this by design, or am I doing something wrong? My experimental config is pretty vanilla:

import { shadowStyle } from "vite-plugin-shadow-style";

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), shadowStyle()],
  build: {
    rollupOptions: {
      plugins: [react(), shadowStyle()],
    },
  },
});
hood commented 5 months ago

Yes, I've currently only used this plugin in builds and never in dev mode.

To give you some context, the plugin was born because I needed to distribute widgets in single file bundles to sprinkle interactivity over an old static website. In my setup I use React too and, to take advantage of HMR etc, I use a different config for dev mode where I simply mount them as components in a SPA. So in practical words: your typical index.html file imports an SPA entry point where you simply render all of your components in series. Not a 100% accurate reproduction of your output, but it's been reliable for my scenarios. My build script basically treats every entry file as a separate build.

I'm surely interested in getting this to work in a dev environment, so keep an eye on the updates, and feel free to contribute if you feel like it, I'm still learning the inner workings of Vite.

panta82 commented 5 months ago

Thanks. Here is how I set it up currently.

index.html loads index.tsx to use during dev:

import './index.css';

import React from 'react';
import ReactDOM from 'react-dom/client';

import App from './app/App.tsx';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

index_build.tsx uses shadow-root and generates a web component output.

import React from 'react';
import ReactDOM from 'react-dom/client';
import root from 'react-shadow';

import App from './app/App.tsx';
import globalCss from './index.css?inline';

export default function (element: HTMLElement) {
  ReactDOM.createRoot(element).render(
    <React.StrictMode>
      <root.div>
        <style type="text/css">{globalCss}</style>
        <style type="text/css">{SHADOW_STYLE}</style>
        <App />
      </root.div>
    </React.StrictMode>
  );
}

vite.config.js:

import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import { shadowStyle } from 'vite-plugin-shadow-style';

export default defineConfig(({ command }) => {
  return {
    plugins: [react()].filter(Boolean),
    define: {
      'process.env': {},
    },
    build: {
      lib: {
        entry: 'src/index_build.tsx',
        name: 'mountWebComponent',
        fileName: 'web-component',
      },
      rollupOptions: {
        plugins: [command === 'build' && shadowStyle()].filter(Boolean),
      },
    },
  };
});