Skip to content

Commit

Permalink
feat: serve app with Vite
Browse files Browse the repository at this point in the history
  • Loading branch information
KaiVandivier committed Apr 16, 2024
1 parent 9c9aa17 commit 93799a6
Show file tree
Hide file tree
Showing 6 changed files with 807 additions and 5 deletions.
1 change: 1 addition & 0 deletions cli/src/commands/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ const handler = async ({
)
reporter.print('')

// todo: split up app and plugin starts
const shellStartPromise = shell.start({ port: newPort })

if (config.entryPoints.plugin) {
Expand Down
4 changes: 2 additions & 2 deletions cli/src/lib/shell/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = ({ config, paths }) => {
build: async () => {
await exec({
cmd: 'yarn',
args: ['run', 'build'],
args: ['build'],
cwd: paths.shell,
env: getEnv({ ...baseEnvVars, ...getPWAEnvVars(config) }),
pipe: false,
Expand All @@ -30,7 +30,7 @@ module.exports = ({ config, paths }) => {
start: async ({ port }) => {
await exec({
cmd: 'yarn',
args: ['run', 'start'],
args: ['start:vite'],
cwd: paths.shell,
env: getEnv({ ...baseEnvVars, port, ...getPWAEnvVars(config) }),
pipe: false,
Expand Down
72 changes: 72 additions & 0 deletions shell/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="theme-color" content="#ffffff" />

<!-- Injection point for base URL from backend -->
<meta name="dhis2-base-url" content="__DHIS2_BASE_URL__" />

<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link
rel="manifest"
crossorigin="use-credentials"
href="/manifest.json"
/>
<meta name="msapplication-config" content="browserconfig.xml" />

<link rel="icon" href="/favicon.ico" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="48x48"
href="/favicon-48x48.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#235b8b" />

<title>%REACT_APP_DHIS2_APP_NAME% | DHIS2</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="dhis2-app-root"></div>
<div id="dhis2-portal-root"></div>

<!-- The entrypoint for Vite -->
<script type="module" src="./src/index.js"></script>

<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
6 changes: 5 additions & 1 deletion shell/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@dhis2/d2-i18n": "^1.1.1",
"@dhis2/pwa": "11.1.1",
"@dhis2/ui": "^9.4.4",
"@vitejs/plugin-react": "^4.2.1",
"classnames": "^2.2.6",
"moment": "^2.29.1",
"post-robot": "^10.0.46",
Expand All @@ -30,9 +31,12 @@
"source-map-explorer": "^2.1.0",
"styled-jsx": "^4.0.1",
"typeface-roboto": "^0.0.75",
"typescript": "^3.6.3"
"typescript": "^3.6.3",
"vite": "^5.2.9"
},
"scripts": {
"start:vite": "vite",
"build:vite": "vite build",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
Expand Down
115 changes: 115 additions & 0 deletions shell/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { resolve } from 'path'
import react from '@vitejs/plugin-react'
import { defineConfig, loadEnv, transformWithEsbuild } from 'vite'

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
// https://vitejs.dev/config/#using-environment-variables-in-config
const env = loadEnv(mode, process.cwd(), ['REACT_APP', 'NODE_ENV'])

// WIP
// Use individual properties for drop-in replacements instead of a whole
// object, which allows for better code trimming optimizations
const defineOptions = {}
Object.entries(env).forEach(([key, val]) => {
defineOptions[`process.env.${key}`] = JSON.stringify(val)
})
console.log({ env, defineOptions })

return {
plugins: [
{
name: 'treat-js-files-as-jsx',
async transform(code, id) {
if (!id.match(/src\/.*\.js$/)) {
return null
}

// Use the exposed transform from vite, instead of directly
// transforming with esbuild
return transformWithEsbuild(code, id, {
loader: 'jsx',
jsx: 'automatic',
})
},
},
react(),
],

// By default, assets are resolved to the root of the domain ('/'), but
// deployed apps aren't served from there.
// This option is basically the same as PUBLIC_URL for CRA and Parcel.
// Works for both dev and production.
base: './',

// Change default ENV prefix from VITE_ to be backward compatible with CRA
// https://vitejs.dev/config/shared-options.html#envprefix
envPrefix: 'REACT_APP',

// Need to add vars on process.env here -- drop-in replacement
define: defineOptions,

build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
// Build an optional plugin -- shares code with main app
// TODO: Dynamically build a plugin, based on context
// plugin: resolve(__dirname, 'plugin.html'),
// TODO: Build the service worker
// 'service-worker': resolve(
// __dirname,
// 'src/service-worker.js'
// ),
},
output: {
// Make sure the service worker output file has the right name
entryFileNames: (assetInfo) =>
assetInfo.name === 'service-worker'
? '[name].js'
: 'assets/[name]-[hash].js',
},
},
},

optimizeDeps: {
force: true,
esbuildOptions: {
loader: {
'.js': 'jsx',
},
},
},

// Allow JSX in .js files (at the cost of performance):
// https://stackoverflow.com/a/74620428
// todo: (switching JSX files to .jsx to not need this allows optimization):
// https://twitter.com/youyuxi/status/1362050255009816577
// esbuild: {
// loader: 'jsx',
// include: [
// // Business as usual for .jsx and .tsx files
// 'src/**/*.jsx',
// 'src/**/*.tsx',
// 'node_modules/**/*.jsx',
// 'node_modules/**/*.tsx',

// // Optional: Add the specific files you want to allow JSX syntax in
// // "src/LocalJsxInJsComponent.js",
// // "node_modules/bad-jsx-in-js-component/js/BadJSXinJS.js",
// // "node_modules/bad-jsx-in-js-component/ts/BadTSXInTs.ts",

// // Add these lines to allow all .js files to contain JSX
// 'src/**/*.js',
// 'node_modules/**/*.js',

// // Add these lines to allow all .ts files to contain JSX
// 'src/**/*.ts',
// 'node_modules/**/*.ts',
// ],
// exclude: [],
// ensure React is imported in files with JSX
// jsx: 'automatic',
// },
}
})
Loading

0 comments on commit 93799a6

Please sign in to comment.