-
Scaffold a Vite project with the React template:
npm init vite my-react-project -- --template react
-
Install
vite-plugin-css-injected-by-js
to automatically inject the app's styles into the document<head>
:cd my-react-project npm i -D vite-plugin-css-injected-by-js
-
Configure Vite to use that plugin via
plugins
; and to disable CSS code splitting viabuild.cssCodeSplit
:// vite.config.js import { defineConfig } from 'vite' import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' export default defineConfig({ plugins: [ cssInjectedByJsPlugin(), ], build: { cssCodeSplit: false, }, })
-
Configure Vite to build a single JavaScript file (i.e., the
main.jsx
file) viabuild.rollupOptions.input
:// vite.config.js import { defineConfig } from 'vite' export default defineConfig({ build: { rollupOptions: { input: { app: './src/main.jsx', }, }, }, })
-
Configure Vite to specify the deployment target's base URL via
base
:// vite.config.js import { defineConfig } from 'vite' export default defineConfig({ base: 'https://cdn.jsdelivr.net/gh/tony19-sandbox/vite-react-single-js-file/dist/', })
The base URL is ideally a CDN link for optimum load performance. For example, if the app files were hosted on GitHub at
https://github.com/tony19-sandbox/vite-react-single-js-file/tree/main/dist
, the CDN link would behttps://cdn.jsdelivr.net/gh/tony19-sandbox/vite-react-single-js-file/dist/
. -
Build the app:
cd my-react-project npm run build
The build then produces a
dist
directory containing these files:dist/assets/app.d91c60c0.js dist/assets/logo.ecc203fb.svg
- In your blog page, insert a custom HTML block.
-
In the HTML block, add a
div
with an ID that matches the mounting point insrc/main.jsx
from your app's original source (the default ID is"root"
).<div id="root">App loading...</div>
-
Add a
<script>
that pulls in theapp.js
file previously built. For example, if you've hosted the script on GitHub, you could use a CDN link like this:<script src="https://cdn.jsdelivr.net/gh/tony19-sandbox/vite-react-single-js-file/dist/assets/app.d91c60c0.js"></script>
The result looks like this: