shoelace/scripts/build.js

136 wiersze
4.0 KiB
JavaScript

import browserSync from 'browser-sync';
import chalk from 'chalk';
import commandLineArgs from 'command-line-args';
import copy from 'recursive-copy';
import del from 'del';
import esbuild from 'esbuild';
import fs from 'fs';
import getPort from 'get-port';
import glob from 'globby';
import path from 'path';
import { execSync } from 'child_process';
const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
const externalDependencies = Object.keys(packageData.dependencies);
const build = esbuild.build;
const bs = browserSync.create();
const { dev } = commandLineArgs({ name: 'dev', type: Boolean });
del.sync(['./dist', './docs/dist']);
try {
if (!dev) execSync('tsc', { stdio: 'inherit' }); // for type declarations
execSync('node scripts/make-metadata.js', { stdio: 'inherit' });
execSync('node scripts/make-search.js', { stdio: 'inherit' });
execSync('node scripts/make-vscode-data.js', { stdio: 'inherit' });
execSync('node scripts/make-css.js', { stdio: 'inherit' });
execSync('node scripts/make-icons.js', { stdio: 'inherit' });
} catch (err) {
console.error(chalk.red(err));
process.exit(1);
}
(async () => {
const buildResult = await esbuild
.build({
format: 'esm',
target: 'es2017',
entryPoints: [
// The whole shebang dist
'./src/shoelace.ts',
// Components
...(await glob('./src/components/**/!(*.(style|test)).ts')),
// Public utilities
...(await glob('./src/utilities/**/!(*.(style|test)).ts')),
// Theme stylesheets
...(await glob('./src/themes/**/!(*.test).ts'))
],
outdir: './dist',
chunkNames: 'chunks/[name].[hash]',
incremental: dev,
define: {
// Popper.js expects this to be set
'process.env.NODE_ENV': '"production"'
},
external: dev ? undefined : externalDependencies,
bundle: true,
splitting: true,
plugins: []
})
.catch(err => {
console.error(chalk.red(err));
process.exit(1);
});
// Create the docs distribution by copying dist into the docs folder. This is what powers the website. It doesn't need
// to exist in dev because Browser Sync routes it virtually.
if (!dev) {
await del('./docs/dist');
await Promise.all([copy('./dist', './docs/dist')]);
}
console.log(chalk.green('The build has finished! 📦\n'));
// Dev server
if (dev) {
const port = await getPort({
port: getPort.makeRange(4000, 4999)
});
console.log(chalk.cyan(`Launching the Shoelace dev server at http://localhost:${port}! 🥾\n`));
// Launch browser sync
bs.init({
startPath: '/',
port,
logLevel: 'silent',
logPrefix: '[shoelace]',
logFileChanges: true,
notify: false,
single: true,
ghostMode: false,
server: {
baseDir: 'docs',
routes: {
'/dist': './dist'
}
}
});
// Rebuild and reload when source files change
bs.watch(['src/**/!(*.test).*']).on('change', async filename => {
console.log(`Source file changed - ${filename}`);
buildResult
// Rebuild and reload
.rebuild()
.then(async () => {
// Rebuild stylesheets when a theme file changes
if (/^src\/themes/.test(filename)) {
execSync('node scripts/make-css.js', { stdio: 'inherit' });
}
})
.then(() => {
// Skip metadata when styles are changed
if (/(\.css|\.styles\.ts)$/.test(filename)) {
return;
}
execSync('node scripts/make-metadata.js', { stdio: 'inherit' });
})
.then(() => bs.reload())
.catch(err => console.error(chalk.red(err)));
});
// Reload without rebuilding when the docs change
bs.watch(['docs/**/*.md']).on('change', filename => {
console.log(`Docs file changed - ${filename}`);
execSync('node scripts/make-search.js', { stdio: 'inherit' });
bs.reload();
});
}
// Cleanup on exit
process.on('SIGTERM', () => buildResult.rebuild.dispose());
})();