Files
webawesome/scripts/build.js

190 lines
6.2 KiB
JavaScript
Raw Permalink Normal View History

2021-06-17 17:38:48 -04:00
import browserSync from 'browser-sync';
import chalk from 'chalk';
import { execSync } from 'child_process';
2021-06-17 17:38:48 -04:00
import commandLineArgs from 'command-line-args';
import del from 'del';
import esbuild from 'esbuild';
import fs from 'fs';
import getPort, { portNumbers } from 'get-port';
import { globby } from 'globby';
import open from 'open';
import copy from 'recursive-copy';
2021-02-26 09:09:13 -05:00
2021-10-22 10:51:17 -04:00
const { bundle, copydir, dir, serve, types } = commandLineArgs([
{ name: 'bundle', type: Boolean },
{ name: 'copydir', type: String },
{ name: 'dir', type: String, defaultValue: 'dist' },
{ name: 'serve', type: Boolean },
{ name: 'types', type: Boolean }
]);
2021-05-11 08:35:31 -04:00
2021-10-16 10:35:42 -04:00
const outdir = dir;
del.sync(outdir);
fs.mkdirSync(outdir, { recursive: true });
2021-02-26 09:09:13 -05:00
(async () => {
try {
execSync(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' });
execSync(`node scripts/make-search.js --outdir "${outdir}"`, { stdio: 'inherit' });
2022-01-26 08:46:20 -05:00
execSync(`node scripts/make-react.js --outdir "${outdir}"`, { stdio: 'inherit' });
execSync(`node scripts/make-vscode-data.js --outdir "${outdir}"`, { stdio: 'inherit' });
2022-02-16 16:02:21 -05:00
execSync(`node scripts/make-web-types.js --outdir "${outdir}"`, { stdio: 'inherit' });
2022-01-25 17:09:53 -05:00
execSync(`node scripts/make-themes.js --outdir "${outdir}"`, { stdio: 'inherit' });
execSync(`node scripts/make-icons.js --outdir "${outdir}"`, { stdio: 'inherit' });
2022-02-10 16:41:20 -05:00
if (types) {
console.log('Running the TypeScript compiler...');
2022-03-24 08:01:09 -04:00
execSync(`tsc --project ./tsconfig.prod.json --outdir "${outdir}"`, { stdio: 'inherit' });
2022-02-10 16:41:20 -05:00
}
} catch (err) {
console.error(chalk.red(err));
process.exit(1);
}
2021-11-04 07:27:18 -04:00
const alwaysExternal = ['@lit-labs/react', 'react'];
2021-02-26 09:09:13 -05:00
const buildResult = await esbuild
.build({
format: 'esm',
target: 'es2017',
2021-10-08 10:11:12 -04:00
entryPoints: [
// The whole shebang
2021-10-08 10:11:12 -04:00
'./src/shoelace.ts',
// Components
...(await globby('./src/components/**/!(*.(style|test)).ts')),
2021-12-06 10:57:54 -05:00
// Translations
...(await globby('./src/translations/**/*.ts')),
2021-10-08 10:11:12 -04:00
// Public utilities
...(await globby('./src/utilities/**/!(*.(style|test)).ts')),
2021-10-08 10:11:12 -04:00
// Theme stylesheets
...(await globby('./src/themes/**/!(*.test).ts')),
2021-11-04 07:27:18 -04:00
// React wrappers
...(await globby('./src/react/**/*.ts'))
2021-10-08 10:11:12 -04:00
],
outdir,
2021-03-02 17:23:49 -05:00
chunkNames: 'chunks/[name].[hash]',
incremental: serve,
2021-02-26 09:09:13 -05:00
define: {
2022-03-03 15:48:20 -05:00
// Floating UI requires this to be set
2021-02-26 09:09:13 -05:00
'process.env.NODE_ENV': '"production"'
},
bundle: true,
//
2021-10-22 10:51:17 -04:00
// We don't bundle certain dependencies in the unbundled build. This ensures we ship bare module specifiers,
// allowing end users to better optimize when using a bundler. (Only packages that ship ESM can be external.)
//
2021-11-04 07:27:18 -04:00
// We never bundle React or @lit-labs/react though!
//
external: bundle
? alwaysExternal
2022-03-03 15:48:20 -05:00
: [...alwaysExternal, '@floating-ui/dom', '@shoelace-style/animations', 'lit', 'qr-creator'],
2021-02-26 09:09:13 -05:00
splitting: true,
plugins: []
2021-02-26 09:09:13 -05:00
})
.catch(err => {
console.error(chalk.red(err));
process.exit(1);
});
2021-10-22 10:51:17 -04:00
// Copy the build output to an additional directory
if (copydir) {
del.sync(copydir);
copy(outdir, copydir);
}
console.log(chalk.green(`The build has been generated at ${outdir} 📦\n`));
2021-02-26 09:09:13 -05:00
2021-10-08 10:11:12 -04:00
// Dev server
if (serve) {
const bs = browserSync.create();
2021-02-26 09:09:13 -05:00
const port = await getPort({
port: portNumbers(4000, 4999)
2021-02-26 09:09:13 -05:00
});
2021-10-22 10:51:17 -04:00
// Make sure docs/dist is empty since we're serving it virtually
del.sync('docs/dist');
const browserSyncConfig = {
open: false,
2021-02-26 09:09:13 -05:00
startPath: '/',
port,
logLevel: 'silent',
logPrefix: '[shoelace]',
logFileChanges: true,
notify: false,
2021-08-24 08:49:27 -04:00
single: true,
2021-08-24 09:03:01 -04:00
ghostMode: false,
2021-02-26 09:09:13 -05:00
server: {
2021-10-14 08:39:17 -04:00
baseDir: 'docs',
routes: {
'/dist': './dist'
}
},
socket: {
socketIoClientConfig: {
// Configure socketIO to retry forever when disconnected to enable the auto-reattach timeout below to work
reconnectionAttempts: Infinity,
reconnectionDelay: 500,
reconnectionDelayMax: 500,
timeout: 1000
}
2021-02-26 09:09:13 -05:00
}
};
2021-02-26 09:09:13 -05:00
// Launch browser sync
bs.init(browserSyncConfig, () => {
// This init callback gets executed after the server has started
const socketIoConfig = browserSyncConfig.socket.socketIoClientConfig;
2022-01-19 08:39:48 -05:00
// Wait enough time for any open, detached clients to have a chance to reconnect. This will be used to determine
// if we reload an existing tab or open a new one.
const tabReattachDelay = socketIoConfig.reconnectionDelayMax * 2 + socketIoConfig.timeout;
2022-01-19 08:39:48 -05:00
setTimeout(() => {
const url = `http://localhost:${port}`;
console.log(chalk.cyan(`Launched the Shoelace dev server at ${url} 🥾\n`));
if (Object.keys(bs.sockets.sockets).length === 0) {
open(url);
} else {
bs.reload();
}
}, tabReattachDelay);
});
2021-02-26 09:09:13 -05:00
// Rebuild and reload when source files change
2021-05-27 16:50:58 -04:00
bs.watch(['src/**/!(*.test).*']).on('change', async filename => {
2021-02-26 09:09:13 -05:00
console.log(`Source file changed - ${filename}`);
buildResult
// Rebuild and reload
2021-02-26 09:09:13 -05:00
.rebuild()
2021-10-22 10:51:17 -04:00
.then(() => {
// Rebuild stylesheets when a theme file changes
if (/^src\/themes/.test(filename)) {
2022-01-25 17:09:53 -05:00
execSync(`node scripts/make-themes.js --outdir "${outdir}"`, { stdio: 'inherit' });
2021-08-04 18:03:24 -04:00
}
})
.then(() => {
// Skip metadata when styles are changed
if (/(\.css|\.styles\.ts)$/.test(filename)) {
return;
}
execSync(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' });
2021-08-04 18:03:24 -04:00
})
2021-10-22 10:51:17 -04:00
.then(() => {
bs.reload();
})
2021-02-26 09:09:13 -05:00
.catch(err => console.error(chalk.red(err)));
});
// Reload without rebuilding when the docs change
2021-09-07 13:13:18 -04:00
bs.watch(['docs/**/*.md']).on('change', filename => {
2021-02-26 09:09:13 -05:00
console.log(`Docs file changed - ${filename}`);
execSync(`node scripts/make-search.js --outdir "${outdir}"`, { stdio: 'inherit' });
2021-02-26 09:09:13 -05:00
bs.reload();
});
}
2021-10-08 10:11:12 -04:00
// Cleanup on exit
process.on('SIGTERM', () => buildResult.rebuild.dispose());
2021-02-26 09:09:13 -05:00
})();