-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.mjs
More file actions
162 lines (138 loc) · 4.99 KB
/
Copy pathbuild.mjs
File metadata and controls
162 lines (138 loc) · 4.99 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
import * as esbuild from 'esbuild'
import { watch } from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import fs from 'fs'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
// Function to toggle HTML comments based on build mode
function toggleHtmlComments(isProduction) {
const indexPath = path.join(__dirname, 'index.html')
let html = fs.readFileSync(indexPath, 'utf-8')
if (isProduction) {
// Production mode: uncomment pro blocks, comment dev blocks
// Pattern: <!--pro-start-->\n <!-- CONTENT -->\n <!--pro-end-->
// Result: <!--pro-start-->\n CONTENT\n <!--pro-end-->
html = html.replace(/<!--pro-start-->\s*\n\s*<!-- ([\s\S]*?) -->\s*\n\s*<!--pro-end-->/g,
(match, content) => {
return `<!--pro-start-->\n ${content}\n <!--pro-end-->`
}
)
// Pattern: <!--dev-start-->\n CONTENT\n <!--dev-end-->
// Result: <!--dev-start-->\n <!-- CONTENT -->\n <!--dev-end-->
html = html.replace(/<!--dev-start-->\s*\n([\s\S]*?)\n\s*<!--dev-end-->/g,
(match, content) => {
return `<!--dev-start-->\n <!-- ${content.trim()} -->\n <!--dev-end-->`
}
)
} else {
// Development mode: comment pro blocks, uncomment dev blocks
// Pattern: <!--pro-start-->\n CONTENT\n <!--pro-end-->
// Result: <!--pro-start-->\n <!-- CONTENT -->\n <!--pro-end-->
html = html.replace(/<!--pro-start-->\s*\n([\s\S]*?)\n\s*<!--pro-end-->/g,
(match, content) => {
return `<!--pro-start-->\n <!-- ${content.trim()} -->\n <!--pro-end-->`
}
)
// Pattern: <!--dev-start-->\n <!-- CONTENT -->\n <!--dev-end-->
// Result: <!--dev-start-->\n CONTENT\n <!--dev-end-->
html = html.replace(/<!--dev-start-->\s*\n\s*<!-- ([\s\S]*?) -->\s*\n\s*<!--dev-end-->/g,
(match, content) => {
return `<!--dev-start-->\n${content}\n <!--dev-end-->`
}
)
}
fs.writeFileSync(indexPath, html)
const mode = isProduction ? '🏭 Production' : '💻 Development'
console.log(`${mode} - HTML comments toggled`)
}
// Custom plugin to output sw.js to root
const swRootPlugin = {
name: 'sw-root',
setup(build) {
build.onEnd(async (result) => {
const swPath = path.join(__dirname, 'dist', 'layx','others','pwa','sw', 'sw.bundle.js')
const rootPath = path.join(__dirname, 'sw.bundle.js')
// Check if sw.bundle.js exists and copy to root
if (fs.existsSync(swPath)) {
fs.copyFileSync(swPath, rootPath)
console.log('📍 Service Worker copied to dist/sw.js')
}
})
}
}
// Build configuration
const buildConfig = {
// Entry points for bundling
entryPoints: [
'assets/js/chat_app/main.js',
'layx/layx.js',
'layx/layx.css',
'assets/css/chat_app/main.css',
'layx/others/pwa/sw/sw.js'
],
// Output configuration
bundle: true,
outdir: 'dist',
outExtension: { '.js': '.bundle.js', '.css': '.bundle.css' },
assetNames: '[path]/[name]',
// Format and target
format: 'esm',
target: ['chrome139'],
// Optimization - minify by default
minify: !process.argv.includes('--dev'),
sourcemap: process.argv.includes('--dev'),
// Module resolution
platform: 'browser',
loader: {
'.woff2': 'file',
'.svg': 'file',
},
// Disable code splitting to include all chunks in main bundle
splitting: false,
// Other options
logLevel: 'info',
plugins: [swRootPlugin],
}
// Check if watch mode or dev mode is enabled
const isWatchMode = process.argv.includes('--watch')
const isDevMode = process.argv.includes('--dev')
async function build() {
try {
const isProduction = !isDevMode
// Toggle HTML comments based on mode
toggleHtmlComments(isProduction)
const modeLabel = isDevMode ? 'Development' : 'Production'
const minifyLabel = buildConfig.minify ? '(minified)' : '(with source maps)'
if (isWatchMode) {
console.log(`🔍 Watch mode enabled (${modeLabel} ${minifyLabel})...`)
const ctx = await esbuild.context(buildConfig)
await ctx.watch()
console.log('✅ Watching for changes...')
// Keep the process alive
process.on('SIGINT', async () => {
console.log('\n🛑 Stopping watcher...')
await ctx.dispose()
process.exit(0)
})
} else {
console.log(`🔨 Building (${modeLabel} ${minifyLabel})...`)
const result = await esbuild.build(buildConfig)
// Print build stats
if (result.metafile) {
const outputs = result.metafile.outputs
console.log('\n📦 Build outputs:')
Object.entries(outputs).forEach(([file, data]) => {
const size = (data.bytes / 1024).toFixed(2)
console.log(` ${file} - ${size} KB`)
})
}
console.log(`✅ Build completed successfully! (${modeLabel})`)
}
} catch (error) {
console.error('❌ Build failed:', error.message)
process.exit(1)
}
}
// Run the build
build()