Micro FE React + Vite + TailwindCSS and using in HTML

create Vite React with Typescript

    npm init vite

Add TailwindCSS for vite: https://tailwindcss.com/docs/guides/vite

Then we will change script at package.json little bit

"scripts": {
    "dev": "vite --port 5001 --strictPort",
    "build": "vite build",
    "preview": "vite preview --port 5001 --strictPort",
    "serve": "vite preview --port 5001 --strictPort"
  },

After that we will run while coding as well

    yarn dev

Create Counter Component with styles

import { useState } from "react";
import "./Counter.css";

interface CounterProps {}

const Counter: React.FunctionComponent<CounterProps> = () => {
  const [count, setCount] = useState(0);

  const handleIncrement = () => {
    setCount(count + 1);
  };

  const handleDecrement = () => {
    setCount(count - 1);
  };
  return (
    <div className="flex justify-center items-center flex-col space-y-4">
      <h1 className="text-3xl font-bold">{count}</h1>
      <div className="flex space-x-2">
        <button
          className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
          onClick={handleIncrement}
        >
          Increment
        </button>
        <button
          className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
          onClick={handleDecrement}
        >
          Decrement
        </button>
      </div>
    </div>
  );
};

export default Counter;

Add the Tailwind directives to Counter CSS

@tailwind base;
@tailwind components;
@tailwind utilities;

At main.tsx change to with id "counter" will render in another host

import React from "react";
import ReactDOM from "react-dom/client";
import Counter from "./components/Counter";

ReactDOM.createRoot(document.getElementById("counter") as HTMLElement).render(
  <React.StrictMode>
    <Counter />
  </React.StrictMode>
);

Also change id in index.html because we change the root id to counter id

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS</title>
  </head>
  <body>
    <div id="counter"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

Before change config we should install vite-plugin-css-injected-by-js, this package will make the CSS union into one JavaScript file

yarn add vite-plugin-css-injected-by-js -D

At vite.config.ts the setting to export file name Counter.js and it is the only file JavaScript in dist folder

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    // this make CSS will have in JavaScript file
    cssInjectedByJsPlugin(),
  ],
  build: {
    target: "esnext",
    rollupOptions: {
      output: {
        // this make only make one JavaScript file
        inlineDynamicImports: true,
        name: "counter",
        entryFileNames: "Counter.js",
      },
    },
  },
});

Run build and Run Serve

    yarn run build
    yarn run serve

The Counter.js will able to use at http://localhost:5001/Counter.js you can click for check it also have code

Running Test

Create HTML file make sure create div with id counter that we defined, and add script that import http://localhost:5001/Counter.js

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link />
    <title>Host</title>
  </head>
  <body>
    <div id="counter"></div>
    <script type="module" src="http://localhost:5001/Counter.js"></script>
  </body>
</html>

Run by anything you have

Settings Window

If you expect that use in other host like React, Vue that able to Components sharing or State sharing so you have to take a look at here: https://github.com/originjs/vite-plugin-federation