test: added a react application test (in the browser)

This commit is contained in:
2024-01-07 00:23:20 +01:00
parent e96c2248ee
commit 3e46055845
22 changed files with 1669 additions and 220 deletions

View File

@@ -0,0 +1,36 @@
import {createRoot} from "react-dom/client";
import {StrictMode, useEffect, useState} from "react";
const states = ['started', 'tick', 'ended'];
export function App(){
const [state, setState] = useState(states[0])
useEffect(()=>{
let timeout: any;
let nextState = states[states.indexOf(state)+1];
if(nextState) {
timeout = setTimeout(() => {
console.log(`Test my sourcemap: ${nextState}`);
setState(nextState)
}, 10);
}
return ()=>{
if(timeout) {
clearTimeout(timeout);
}
}
}, [state])
return (<div style={{alignSelf: "center"}}>
<b>{state}</b>
</div>);
}
export async function start({root: rootContainer}: {root: HTMLElement}){
if(!rootContainer) throw new Error("Missing root element");
const root = createRoot(rootContainer);
root.render(<StrictMode>
<App />
</StrictMode>);
}

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<title>HTML5 Logo</title>
<path d="M108.4 0h23v22.8h21.2V0h23v69h-23V46h-21v23h-23.2M206 23h-20.3V0h63.7v23H229v46h-23M259.5 0h24.1l14.8 24.3L313.2 0h24.1v69h-23V34.8l-16.1 24.8l-16.1-24.8v34.2h-22.6M348.7 0h23v46.2h32.6V69h-55.6"/>
<path fill="#e44d26" d="M107.6 471l-33-370.4h362.8l-33 370.2L255.7 512"/>
<path fill="#f16529" d="M256 480.5V131H404.3L376 447"/>
<path fill="#ebebeb" d="M142 176.3h114v45.4h-64.2l4.2 46.5h60v45.3H154.4M156.4 336.3H202l3.2 36.3 50.8 13.6v47.4l-93.2-26"/>
<path fill="#fff" d="M369.6 176.3H255.8v45.4h109.6M361.3 268.2H255.8v45.4h56l-5.3 59-50.7 13.6v47.2l93-25.8"/>
</svg>

After

Width:  |  Height:  |  Size: 693 B

View File

@@ -0,0 +1,14 @@
export default {
presets: [
["@babel/preset-env", {
shippedProposals: true,
}],
["@babel/preset-typescript", {
}],
["@babel/preset-react", {
development: process.env.BABEL_ENV === "development",
runtime: "automatic"
}]
],
}

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
Test bundle!
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="./assets/logo-sq.svg">
{{{ head }}}
</head>
<body>
<div id="root">Here the app should load!</div>
<script src="./index.mjs" type="module"></script>
</body>
</html>

View File

@@ -0,0 +1,27 @@
// Dynamically loads libraries and bootstraps the application
(async ()=>{
// Add a loader here if any
const root = document.getElementById('root')
if(root) root.innerHTML= `<div style="align-self: center">My app has loaded!!</div>`;
try {
// Load app
const [
appModule,
] = await Promise.all([
import("./app.tsx"),
]);
console.log("Bootstrapped, ready to go!");
// Wait for DOM to be ready
if(document.readyState === 'loading') {
await new Promise((resolve)=>document.addEventListener('DOMContentLoaded', resolve));
}
// Start the app!
await appModule.start({root});
}catch(err){
console.error(err);
}
})()

View File

@@ -0,0 +1,16 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"target": "ESNext",
"moduleResolution": "Bundler",
"module": "ESNext",
"strict": true,
"paths":{
"react": ["./node_modules/@types/react"]
},
"allowSyntheticDefaultImports": true,
"allowUnreachableCode": true,
"allowUnusedLabels": true,
"noUnusedLocals": false
},
}

90
test/jsx-web-app/test.js Normal file
View File

@@ -0,0 +1,90 @@
import {join, dirname} from "node:path";
import test from "ava";
// Rollup * plugins
import { rollup } from "rollup";
import urlPlugin from "@rollup/plugin-url";
import nodeResolve from "@rollup/plugin-node-resolve";
import babelPlugin from "@rollup/plugin-babel";
import commonJsPlugin from "@rollup/plugin-commonjs";
import typescriptPlugin from "@rollup/plugin-typescript";
import replacePlugin from "@rollup/plugin-replace";
import html from "../../src/index.ts";
import serveTest from "../util/test-server.ts";
/**
* @type {OutputOptions}
*/
const output= {
dir: 'output', // Output all files
format: 'es', // iifi and cjs should be added to tests
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
chunkFileNames: '[name].js',
entryFileNames: '[name].[extname]',
assetFileNames: '[name].[extname]',
};
import {fileURLToPath} from "node:url";
import handlebars from "handlebars";
const __dirname = dirname(fileURLToPath(import.meta.url));
process.chdir(join(__dirname, 'fixtures'));
const defaultAssetInclude = [
'**/*.(png|jpg|jpeg|gif|ico|svg)',// images, svg
'**/*.(woff|woff2|eot|ttf|otf)',// fonts
'**/*.(webm|mp4)',// video
];
test.serial('web-bundle', async (t) => {
const bundle = await rollup({
input: 'index.hbs',
treeshake: 'smallest',
plugins: [
html({
transform(src) {
return handlebars.compile(src)({
head: `<title>I'm cool!</title>`
});
}
}),
nodeResolve({
extensions: ['.js', '.mjs', '.jsx', '.ts', '.tsx'],
browser: true,
}),
commonJsPlugin({
}),
typescriptPlugin({
sourceMap: true,
// exclude: 'node_modules/**',
noEmitOnError: true,
outputToFilesystem: false,
noForceEmit: true,
jsx: "preserve",
}),
babelPlugin({
extensions: ['.js', '.mjs', '.jsx', '.ts', '.tsx'],
babelHelpers: "bundled",
}),
replacePlugin({
preventAssignment: false,
'process.env.NODE_ENV': process.env.NODE_ENV==='production'?`'${process.env.NODE_ENV}'` : '"development"'
}),
urlPlugin({
include: defaultAssetInclude,
}),
serveTest({
path: 'index.html',
t,
})
],
});
const generated = await bundle.generate(output);
});