-
-
Notifications
You must be signed in to change notification settings - Fork 115
Expand file tree
/
Copy pathbuild.js
More file actions
193 lines (163 loc) · 7.77 KB
/
build.js
File metadata and controls
193 lines (163 loc) · 7.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import { exec } from 'child_process';
import { promisify } from 'util';
const execPromise = promisify(exec);
// Resolve project root, assuming this script is in <project_root>/scripts/
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');
// Ensures a directory exists. If it doesn't, it's created recursively.
async function ensureDir(dirPath) {
try {
await fs.access(dirPath);
} catch (error) {
if (error.code === 'ENOENT') {
await fs.mkdir(dirPath, { recursive: true });
} else {
throw error;
}
}
}
// Cleans a directory by removing all its contents (files and subdirectories).
async function cleanDir(directory) {
try {
await fs.access(directory);
const entries = await fs.readdir(directory, { withFileTypes: true });
for (const entry of entries) {
const entryPath = path.join(directory, entry.name);
if (entry.isDirectory()) {
await fs.rm(entryPath, { recursive: true, force: true });
} else {
await fs.unlink(entryPath);
}
}
console.log(`Cleaned directory: ${directory}`);
} catch (error) {
if (error.code === 'ENOENT') {
console.log(`Directory not found, no need to clean: ${directory}`);
} else {
console.error(`Error cleaning directory ${directory}:`, error);
throw error;
}
}
}
// Recursively copies a directory.
async function copyDirRecursive(src, dest) {
await ensureDir(dest);
const entries = await fs.readdir(src, { withFileTypes: true });
for (let entry of entries) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
await copyDirRecursive(srcPath, destPath);
} else {
await fs.copyFile(srcPath, destPath);
}
}
}
// Main build function to prepare packages for publishing.
async function build() {
console.log('Starting build process...');
// Define all necessary paths
const cliPackageDir = path.join(projectRoot, 'packages', 'cli');
const cliDistDir = path.join(cliPackageDir, 'dist');
const cliDistAssetsDir = path.join(cliDistDir, 'assets');
const cssPackageDir = path.join(projectRoot, 'packages', 'css');
const cssDistDir = path.join(cssPackageDir, 'dist');
const srcDir = path.join(projectRoot, 'src');
const srcCssDir = path.join(srcDir, 'css');
const srcJsDir = path.join(srcDir, 'js');
const srcNunjucksDir = path.join(srcDir, 'nunjucks');
const srcJinjaDir = path.join(srcDir, 'jinja');
// Clean previous build artifacts
console.log('Cleaning distribution directories...');
await cleanDir(cliDistDir);
await cleanDir(cssDistDir);
// Build CLI package
console.log('Building CLI package...');
await ensureDir(cliDistDir); // Ensure base dist dir exists
await ensureDir(cliDistAssetsDir); // Ensure assets dir within dist exists
await fs.copyFile(path.join(cliPackageDir, 'index.js'), path.join(cliDistDir, 'index.js'));
console.log(`Copied CLI index.js to ${cliDistDir}`);
// JS files minification and copy
const jsFiles = await fs.readdir(srcJsDir);
const cliJsDistDir = path.join(cliDistAssetsDir, 'js');
const cssJsDistDir = path.join(cssDistDir, 'js');
await ensureDir(cliJsDistDir);
await ensureDir(cssJsDistDir);
console.log('Copying and minifying JS files...');
for (const jsFile of jsFiles) {
if (path.extname(jsFile) === '.js') {
const srcFile = path.join(srcJsDir, jsFile);
const baseName = path.basename(jsFile, '.js');
const minifiedFileName = `${baseName}.min.js`;
// Copy original file to both destinations
await fs.copyFile(srcFile, path.join(cliJsDistDir, jsFile));
await fs.copyFile(srcFile, path.join(cssJsDistDir, jsFile));
// Create and copy minified file to both destinations
const cliDestMinFile = path.join(cliJsDistDir, minifiedFileName);
await execPromise(`npx terser ${srcFile} -o ${cliDestMinFile} --compress --mangle`);
await fs.copyFile(cliDestMinFile, path.join(cssJsDistDir, minifiedFileName));
}
}
// Create combined component files
console.log('Creating combined component files...');
const componentsToCombine = ['basecoat.js', 'dropdown-menu.js', 'popover.js', 'select.js', 'sidebar.js', 'tabs.js', 'toast.js'];
const componentPaths = componentsToCombine.map(f => path.join(srcJsDir, f));
// Create non-minified bundle
let combinedContent = '';
for (const p of componentPaths) {
combinedContent += await fs.readFile(p, 'utf-8') + '\n';
}
const allJsPath = path.join(cliJsDistDir, 'all.js');
await fs.writeFile(allJsPath, combinedContent);
await fs.copyFile(allJsPath, path.join(cssJsDistDir, 'all.js'));
// Create minified bundle
const allMinJsPath = path.join(cliJsDistDir, 'all.min.js');
await execPromise(`npx terser ${componentPaths.join(' ')} -o ${allMinJsPath} --compress --mangle`);
await fs.copyFile(allMinJsPath, path.join(cssJsDistDir, 'all.min.js'));
console.log(`Copied and minified JS to ${cliJsDistDir} and ${cssJsDistDir}`);
await copyDirRecursive(srcNunjucksDir, path.join(cliDistAssetsDir, 'nunjucks'));
console.log(`Copied Nunjucks assets to ${path.join(cliDistAssetsDir, 'nunjucks')}`);
await copyDirRecursive(srcJinjaDir, path.join(cliDistAssetsDir, 'jinja'));
console.log(`Copied Jinja assets to ${path.join(cliDistAssetsDir, 'jinja')}`);
// Build CSS package
console.log('Building CSS package...');
await ensureDir(cssDistDir); // Ensure dist dir exists for css package
await fs.copyFile(path.join(srcCssDir, 'basecoat.css'), path.join(cssDistDir, 'basecoat.css'));
console.log(`Copied basecoat.css to ${cssDistDir}`);
await fs.copyFile(path.join(srcCssDir, 'basecoat.shared.css'), path.join(cssDistDir, 'basecoat.shared.css'));
console.log(`Copied basecoat.shared.css to ${cssDistDir}`);
// Create Tailwind CSS builds for the CSS package
const cdnCssSrc = path.join(srcCssDir, 'basecoat.cdn.css');
const cssDistCdnPath = path.join(cssDistDir, 'basecoat.cdn.css');
const cssDistCdnMinPath = path.join(cssDistDir, 'basecoat.cdn.min.css');
await execPromise(`npx tailwindcss -i "${cdnCssSrc}" -o "${cssDistCdnPath}"`);
console.log(`Generated non-minified CSS: ${cssDistCdnPath}`);
await execPromise(`npx tailwindcss -i "${cdnCssSrc}" -o "${cssDistCdnMinPath}" --minify`);
console.log(`Generated minified CSS: ${cssDistCdnMinPath}`);
// Now for the Quasar build
const quasarCssSrc = path.join(srcCssDir, 'basecoat.quasar.css');
const cssDistQuasarPath = path.join(cssDistDir, 'basecoat.quasar.css');
const cssDistQuasarMinPath = path.join(cssDistDir, 'basecoat.quasar.min.css');
await execPromise(`npx tailwindcss -i "${quasarCssSrc}" -o "${cssDistQuasarPath}"`);
console.log(`Generated non-minified Quasar CSS: ${cssDistQuasarPath}`);
await execPromise(`npx tailwindcss -i "${quasarCssSrc}" -o "${cssDistQuasarMinPath}" --minify`);
console.log(`Generated minified Quasar CSS: ${cssDistQuasarMinPath}`);
console.log('HACK: Modifying Quasar CSS for :root, :host to body...');
let quasarCssContent = await fs.readFile(cssDistQuasarPath, 'utf-8');
quasarCssContent = quasarCssContent.replace(/:root, :host/g, 'body');
await fs.writeFile(cssDistQuasarPath, quasarCssContent);
console.log(`Modified ${cssDistQuasarPath} to replace :root with body`);
let quasarMinCssContent = await fs.readFile(cssDistQuasarMinPath, 'utf-8');
quasarMinCssContent = quasarMinCssContent.replace(/:root,:host/g, 'body');
await fs.writeFile(cssDistQuasarMinPath, quasarMinCssContent);
console.log(`Modified ${cssDistQuasarMinPath} to replace :root with body`);
console.log('Build process finished successfully!');
}
build().catch(error => {
console.error('Build failed:', error);
process.exit(1);
});