mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
Initial SSR implementation (#157)
* continued ssr work * continued ssr work * prettier * all components now rendering * everything finally works * fix type issues * working on breadcrumb * working on breadcrumb * radio group * convert all tests to ssr * prettier * test suite finally passing * add layout stuff * add changelog * fix TS issue * fix tests * fixing deploy stuff * get QR code displaying * fix tests * fix tests * prettier * condense hydration stuff * prettier * comment out range test * fixing issues * use base fixtures * fixing examples * dont vendor * fix import of hydration support * adding notes * add notesg * add ssr loader * fix build * prettier * add notes * add notes * prettier * fixing bundled stuff * remove cdn * remove cdn * prettier * fiixng tests * prettier * split jobs?? * prettier * fix build stuff * add reset mouse and await aTimeout * prettier * fix improper tests * prettier * bail on first * fix linting * only test form with client * redundancy on ssr-loader?? * maybe this will work * prettier * try callout now * fix form.test.ts * fix form.test.ts * prettier * fix forms * fix forms * try again * prettier * add some awaits * prettier * comment out broken SSR tests * prettier * comment out broken SSR tests * prettier * dont skip in CI * upgrade playwright to beta * prettier * try some trickery * try some trickery * await updateComplete * try to fix form.test.ts * import hydrateable elements 1 time * prettier * fix input defaultValue issues * fix form controls to behave like their native counterpartS * add changelog entry * prettier * fix unexpected behavior with range / button
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { deleteAsync } from 'del';
|
||||
import { dirname, join, relative } from 'path';
|
||||
import { distDir, docsDir, rootDir, runScript, siteDir } from './utils.js';
|
||||
import { distDir, docsDir, cdnDir, rootDir, runScript, siteDir } from './utils.js';
|
||||
import { execSync } from 'child_process';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { globby } from 'globby';
|
||||
@@ -14,17 +14,16 @@ import getPort, { portNumbers } from 'get-port';
|
||||
import ora from 'ora';
|
||||
import process from 'process';
|
||||
|
||||
//
|
||||
// TODO - CDN dist and unbundled dist
|
||||
//
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const isDeveloping = process.argv.includes('--develop');
|
||||
const isAlpha = process.argv.includes('--alpha');
|
||||
const spinner = ora({ text: 'Web Awesome', color: 'cyan' }).start();
|
||||
const packageData = JSON.parse(await readFile(join(rootDir, 'package.json'), 'utf-8'));
|
||||
const version = JSON.stringify(packageData.version.toString());
|
||||
let buildContext;
|
||||
let buildContexts = {
|
||||
bundledContext: {},
|
||||
unbundledContext: {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs the full build.
|
||||
@@ -38,6 +37,10 @@ async function buildAll() {
|
||||
await generateReactWrappers();
|
||||
await generateTypes();
|
||||
await generateStyles();
|
||||
|
||||
// copy everything to unbundled before we generate bundles.
|
||||
await copy(cdnDir, distDir, { overwrite: true });
|
||||
|
||||
await generateBundle();
|
||||
await generateDocs();
|
||||
|
||||
@@ -54,7 +57,9 @@ async function cleanup() {
|
||||
spinner.start('Cleaning up dist');
|
||||
|
||||
await deleteAsync(distDir);
|
||||
await deleteAsync(cdnDir);
|
||||
await mkdir(distDir, { recursive: true });
|
||||
await mkdir(cdnDir, { recursive: true });
|
||||
|
||||
spinner.succeed();
|
||||
}
|
||||
@@ -83,7 +88,7 @@ function generateReactWrappers() {
|
||||
spinner.start('Generating React wrappers');
|
||||
|
||||
try {
|
||||
execSync(`node scripts/make-react.js --outdir "${distDir}"`, { stdio: 'inherit' });
|
||||
execSync(`node scripts/make-react.js --outdir "${cdnDir}"`, { stdio: 'inherit' });
|
||||
} catch (error) {
|
||||
console.error(`\n\n${error.message}`);
|
||||
}
|
||||
@@ -100,13 +105,13 @@ async function generateStyles() {
|
||||
|
||||
// NOTE - alpha setting omits all stylesheets except for these because we use them in the docs
|
||||
if (isAlpha) {
|
||||
await copy(join(rootDir, 'src/themes/applied.css'), join(distDir, 'themes/applied.css'), { overwrite: true });
|
||||
await copy(join(rootDir, 'src/themes/color_standard.css'), join(distDir, 'themes/color_standard.css'), {
|
||||
await copy(join(rootDir, 'src/themes/applied.css'), join(cdnDir, 'themes/applied.css'), { overwrite: true });
|
||||
await copy(join(rootDir, 'src/themes/color_standard.css'), join(cdnDir, 'themes/color_standard.css'), {
|
||||
overwrite: true
|
||||
});
|
||||
await copy(join(rootDir, 'src/themes/default.css'), join(distDir, 'themes/default.css'), { overwrite: true });
|
||||
await copy(join(rootDir, 'src/themes/default.css'), join(cdnDir, 'themes/default.css'), { overwrite: true });
|
||||
} else {
|
||||
await copy(join(rootDir, 'src/themes'), join(distDir, 'themes'), { overwrite: true });
|
||||
await copy(join(rootDir, 'src/themes'), join(cdnDir, 'themes'), { overwrite: true });
|
||||
}
|
||||
|
||||
spinner.succeed();
|
||||
@@ -121,7 +126,7 @@ async function generateTypes() {
|
||||
spinner.start('Running the TypeScript compiler');
|
||||
|
||||
try {
|
||||
execSync(`tsc --project ./tsconfig.prod.json --outdir "${distDir}"`);
|
||||
execSync(`tsc --project ./tsconfig.prod.json --outdir "${cdnDir}"`);
|
||||
} catch (error) {
|
||||
return Promise.reject(error.stdout);
|
||||
}
|
||||
@@ -137,6 +142,7 @@ async function generateTypes() {
|
||||
async function generateBundle() {
|
||||
spinner.start('Bundling with esbuild');
|
||||
|
||||
// Bundled config
|
||||
const config = {
|
||||
format: 'esm',
|
||||
target: 'es2020',
|
||||
@@ -148,6 +154,7 @@ async function generateBundle() {
|
||||
'./src/webawesome.ts',
|
||||
// Autoloader + utilities
|
||||
'./src/webawesome.loader.ts',
|
||||
'./src/webawesome.ssr-loader.ts',
|
||||
// Individual components
|
||||
...(await globby('./src/components/**/!(*.(style|test)).ts')),
|
||||
// Translations
|
||||
@@ -155,23 +162,41 @@ async function generateBundle() {
|
||||
// React wrappers
|
||||
...(await globby('./src/react/**/*.ts'))
|
||||
],
|
||||
outdir: distDir,
|
||||
outdir: cdnDir,
|
||||
chunkNames: 'chunks/[name].[hash]',
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"production"' // required by Floating UI
|
||||
},
|
||||
bundle: true,
|
||||
splitting: true,
|
||||
minify: false,
|
||||
plugins: [replace({ __WEBAWESOME_VERSION__: version })]
|
||||
};
|
||||
|
||||
if (isDeveloping) {
|
||||
// Incremental builds for dev
|
||||
buildContext = await esbuild.context(config);
|
||||
await buildContext.rebuild();
|
||||
} else {
|
||||
// One-time build for production
|
||||
await esbuild.build(config);
|
||||
const unbundledConfig = {
|
||||
...config,
|
||||
splitting: true,
|
||||
treeShaking: true,
|
||||
// Don't inline libraries like Lit etc.
|
||||
packages: 'external',
|
||||
outdir: distDir
|
||||
};
|
||||
|
||||
try {
|
||||
if (isDeveloping) {
|
||||
buildContexts.bundledContext = await esbuild.context(config);
|
||||
buildContexts.unbundledContext = await esbuild.context(unbundledConfig);
|
||||
|
||||
await buildContexts.bundledContext.rebuild();
|
||||
await buildContexts.unbundledContext.rebuild();
|
||||
} else {
|
||||
// One-time build for production
|
||||
await esbuild.build(config);
|
||||
await esbuild.build(unbundledConfig);
|
||||
}
|
||||
} catch (error) {
|
||||
spinner.fail();
|
||||
console.log(chalk.red(`\n${error}`));
|
||||
}
|
||||
|
||||
spinner.succeed();
|
||||
@@ -183,7 +208,8 @@ async function generateBundle() {
|
||||
async function regenerateBundle() {
|
||||
try {
|
||||
spinner.start('Re-bundling with esbuild');
|
||||
await buildContext.rebuild();
|
||||
await buildContexts.bundledContext.rebuild();
|
||||
await buildContexts.unbundledContext.rebuild();
|
||||
} catch (error) {
|
||||
spinner.fail();
|
||||
console.log(chalk.red(`\n${error}`));
|
||||
@@ -216,7 +242,7 @@ async function generateDocs() {
|
||||
|
||||
// Copy dist (production only)
|
||||
if (!isDeveloping) {
|
||||
await copy(distDir, join(siteDir, 'dist'));
|
||||
await copy(cdnDir, join(siteDir, 'dist'));
|
||||
}
|
||||
|
||||
spinner.succeed(`Writing the docs ${chalk.gray(`(${output}`)})`);
|
||||
@@ -256,7 +282,7 @@ if (isDeveloping) {
|
||||
server: {
|
||||
baseDir: siteDir,
|
||||
routes: {
|
||||
'/dist': './dist'
|
||||
'/dist/': './dist-cdn/'
|
||||
}
|
||||
},
|
||||
callbacks: {
|
||||
@@ -330,9 +356,8 @@ if (isDeveloping) {
|
||||
// Cleanup everything when the process terminates
|
||||
//
|
||||
function terminate() {
|
||||
if (buildContext) {
|
||||
buildContext.dispose();
|
||||
}
|
||||
// dispose of contexts.
|
||||
Object.values(buildContexts).forEach(context => context?.dispose?.());
|
||||
|
||||
if (spinner) {
|
||||
spinner.stop();
|
||||
|
||||
@@ -7,6 +7,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
// Helpful directories
|
||||
export const rootDir = dirname(__dirname);
|
||||
export const distDir = join(rootDir, 'dist');
|
||||
export const cdnDir = join(rootDir, 'dist-cdn');
|
||||
export const docsDir = join(rootDir, 'docs');
|
||||
export const siteDir = join(rootDir, '_site');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user