build: 打通 FastAPI 与 Vue 最小工程、依赖与数据库连接
后端入口、配置、Redis 与 Alembic 迁移就位;前端 Vite 工程可安装可构建。
This commit is contained in:
1 parent
fb0ddca4de
commit
2aee6286d6
167 files changed
+26082
No files matched your search
@@ -0,0 +1,76 @@
|
||||
import { build } from 'esbuild'
|
||||
import { resolve, dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import * as dotenv from 'dotenv'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
|
||||
// Load development environment variables
|
||||
dotenv.config({ path: '.env.dev' })
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = dirname(__filename)
|
||||
|
||||
async function buildWebClientDev() {
|
||||
try {
|
||||
console.log('Building webclient with development configuration...')
|
||||
|
||||
// For development, we use the existing config.js which is already set for development
|
||||
// No need to copy files like in production build
|
||||
console.log('Using existing config.js for development build')
|
||||
|
||||
// Set NODE_ENV to development for the build
|
||||
process.env.NODE_ENV = 'development'
|
||||
|
||||
// Baked DEFAULT base URL only; getBaseUrl() still resolves
|
||||
// window.chattermateBaseUrl / window.APP_CONFIG at runtime, so no rebuild is
|
||||
// needed when a deployment's env changes.
|
||||
const apiUrl = process.env.VITE_API_URL || 'http://localhost:8000/api/v1'
|
||||
console.log('Using API URL:', apiUrl)
|
||||
|
||||
const sourceFile = resolve(dirname(__dirname), 'src/webclient/chattermate.js')
|
||||
|
||||
await build({
|
||||
entryPoints: [sourceFile],
|
||||
bundle: true,
|
||||
minify: false, // Don't minify for development
|
||||
outfile: resolve(dirname(__dirname), 'public/webclient/chattermate.min.js'),
|
||||
format: 'iife',
|
||||
target: ['es2015'],
|
||||
loader: {
|
||||
'.svg': 'text',
|
||||
},
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"development"',
|
||||
'__CHATTERMATE_API_URL__': JSON.stringify(apiUrl),
|
||||
},
|
||||
sourcemap: true, // Add sourcemap for development
|
||||
})
|
||||
|
||||
// Copy output to dist/webclient directory
|
||||
const publicWebclientPath = resolve(dirname(__dirname), 'public/webclient/chattermate.min.js')
|
||||
const publicSourcemapPath = resolve(dirname(__dirname), 'public/webclient/chattermate.min.js.map')
|
||||
const distWebclientDir = resolve(dirname(__dirname), 'dist/webclient')
|
||||
const distWebclientPath = resolve(distWebclientDir, 'chattermate.min.js')
|
||||
const distSourcemapPath = resolve(distWebclientDir, 'chattermate.min.js.map')
|
||||
|
||||
// Ensure dist/webclient directory exists
|
||||
if (!fs.existsSync(distWebclientDir)) {
|
||||
fs.mkdirSync(distWebclientDir, { recursive: true })
|
||||
}
|
||||
|
||||
// Copy the built file and sourcemap to dist/webclient
|
||||
fs.copyFileSync(publicWebclientPath, distWebclientPath)
|
||||
if (fs.existsSync(publicSourcemapPath)) {
|
||||
fs.copyFileSync(publicSourcemapPath, distSourcemapPath)
|
||||
}
|
||||
console.log('Development web client copied to dist/webclient/')
|
||||
|
||||
console.log('Development web client built successfully!')
|
||||
} catch (error) {
|
||||
console.error('Development build failed:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
buildWebClientDev()
|
||||
@@ -0,0 +1,69 @@
|
||||
import { build } from 'esbuild'
|
||||
import { resolve, dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import * as dotenv from 'dotenv'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
|
||||
// Load production environment variables
|
||||
dotenv.config({ path: '.env.prod' })
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = dirname(__filename)
|
||||
|
||||
async function buildWebClientProd() {
|
||||
try {
|
||||
console.log('Building webclient with production configuration...')
|
||||
|
||||
// Config is now generated by the prebuild step (generate-prod-env.ts)
|
||||
// No need to copy config files here
|
||||
|
||||
// Set NODE_ENV to production for the build
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
// Baked DEFAULT base URL. This only sets the fallback; getBaseUrl() still
|
||||
// resolves window.chattermateBaseUrl / window.APP_CONFIG at runtime, so an
|
||||
// env change on a deployment needs no rebuild of this artifact.
|
||||
const apiUrl = process.env.VITE_API_URL || 'https://api.chattermate.chat/api/v1'
|
||||
console.log('Using API URL:', apiUrl)
|
||||
|
||||
const sourceFile = resolve(dirname(__dirname), 'src/webclient/chattermate.js')
|
||||
|
||||
await build({
|
||||
entryPoints: [sourceFile],
|
||||
bundle: true,
|
||||
minify: true,
|
||||
outfile: resolve(dirname(__dirname), 'public/webclient/chattermate.min.js'),
|
||||
format: 'iife',
|
||||
target: ['es2015'],
|
||||
loader: {
|
||||
'.svg': 'text',
|
||||
},
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
'__CHATTERMATE_API_URL__': JSON.stringify(apiUrl),
|
||||
},
|
||||
})
|
||||
|
||||
// Copy output to dist/webclient directory
|
||||
const publicWebclientPath = resolve(dirname(__dirname), 'public/webclient/chattermate.min.js')
|
||||
const distWebclientDir = resolve(dirname(__dirname), 'dist/webclient')
|
||||
const distWebclientPath = resolve(distWebclientDir, 'chattermate.min.js')
|
||||
|
||||
// Ensure dist/webclient directory exists
|
||||
if (!fs.existsSync(distWebclientDir)) {
|
||||
fs.mkdirSync(distWebclientDir, { recursive: true })
|
||||
}
|
||||
|
||||
// Copy the built file to dist/webclient
|
||||
fs.copyFileSync(publicWebclientPath, distWebclientPath)
|
||||
console.log('Production web client copied to dist/webclient/')
|
||||
|
||||
console.log('Production web client built successfully!')
|
||||
} catch (error) {
|
||||
console.error('Production build failed:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
buildWebClientProd()
|
||||
@@ -0,0 +1,67 @@
|
||||
import { build } from 'vite'
|
||||
import { resolve } from 'path'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as dotenv from 'dotenv'
|
||||
|
||||
// Load development environment variables
|
||||
dotenv.config({ path: '.env.dev' })
|
||||
|
||||
const config = resolve(process.cwd(), 'vite.widget.config.ts')
|
||||
const assetsDir = resolve(process.cwd(), '../backend/assets')
|
||||
const filesToKeep = ['widget.js', 'widget.css']
|
||||
|
||||
async function buildWidgetDev() {
|
||||
try {
|
||||
console.log('Building widget with development configuration...')
|
||||
|
||||
// Set NODE_ENV to development for the build
|
||||
process.env.NODE_ENV = 'development'
|
||||
|
||||
// Run the Vite build
|
||||
await build({ configFile: config })
|
||||
console.log('Vite build completed')
|
||||
|
||||
// Copy CSS file from unused directory to the root assets directory
|
||||
const unusedDir = path.join(assetsDir, 'unused')
|
||||
if (fs.existsSync(unusedDir)) {
|
||||
const files = fs.readdirSync(unusedDir)
|
||||
const cssFile = files.find(file => file.endsWith('.css'))
|
||||
|
||||
if (cssFile) {
|
||||
const sourcePath = path.join(unusedDir, cssFile)
|
||||
const destPath = path.join(assetsDir, 'widget.css')
|
||||
|
||||
fs.copyFileSync(sourcePath, destPath)
|
||||
console.log(`Copied CSS file to ${destPath}`)
|
||||
}
|
||||
|
||||
// Clean up unused directory
|
||||
fs.rmSync(unusedDir, { recursive: true, force: true })
|
||||
console.log('Cleaned up unused directory')
|
||||
}
|
||||
|
||||
// Clean up the assets directory - keep only widget.js and widget.css
|
||||
const entries = fs.readdirSync(assetsDir)
|
||||
|
||||
for (const entry of entries) {
|
||||
if (!filesToKeep.includes(entry)) {
|
||||
const entryPath = path.join(assetsDir, entry)
|
||||
|
||||
if (fs.statSync(entryPath).isDirectory()) {
|
||||
fs.rmSync(entryPath, { recursive: true, force: true })
|
||||
} else {
|
||||
fs.unlinkSync(entryPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Cleaned up assets directory, keeping only: ${filesToKeep.join(', ')}`)
|
||||
console.log('Development widget built successfully!')
|
||||
} catch (error) {
|
||||
console.error('Development build failed:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
buildWidgetDev()
|
||||
@@ -0,0 +1,67 @@
|
||||
import { build } from 'vite'
|
||||
import { resolve } from 'path'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
|
||||
const config = resolve(process.cwd(), 'vite.widget.docker.config.ts')
|
||||
// For Docker, we need to copy to a shared volume or mounted directory
|
||||
// This assumes the backend assets are mounted/shared between containers
|
||||
const assetsDir = resolve(process.cwd(), '/app/backend-assets')
|
||||
const filesToKeep = ['widget.js', 'widget.css']
|
||||
|
||||
async function buildWidgetDocker() {
|
||||
try {
|
||||
// Ensure the backend assets directory exists
|
||||
if (!fs.existsSync(assetsDir)) {
|
||||
fs.mkdirSync(assetsDir, { recursive: true })
|
||||
console.log(`Created backend assets directory: ${assetsDir}`)
|
||||
}
|
||||
|
||||
// Run the Vite build
|
||||
await build({ configFile: config })
|
||||
console.log('Vite build completed')
|
||||
|
||||
// Copy CSS file from unused directory to the root assets directory
|
||||
const unusedDir = path.join(assetsDir, 'unused')
|
||||
if (fs.existsSync(unusedDir)) {
|
||||
const files = fs.readdirSync(unusedDir)
|
||||
const cssFile = files.find(file => file.endsWith('.css'))
|
||||
|
||||
if (cssFile) {
|
||||
const sourcePath = path.join(unusedDir, cssFile)
|
||||
const destPath = path.join(assetsDir, 'widget.css')
|
||||
|
||||
fs.copyFileSync(sourcePath, destPath)
|
||||
console.log(`Copied CSS file to ${destPath}`)
|
||||
}
|
||||
|
||||
// Clean up unused directory
|
||||
fs.rmSync(unusedDir, { recursive: true, force: true })
|
||||
console.log('Cleaned up unused directory')
|
||||
}
|
||||
|
||||
// Clean up the assets directory - keep only widget.js and widget.css
|
||||
const entries = fs.readdirSync(assetsDir)
|
||||
|
||||
for (const entry of entries) {
|
||||
if (!filesToKeep.includes(entry)) {
|
||||
const entryPath = path.join(assetsDir, entry)
|
||||
|
||||
if (fs.statSync(entryPath).isDirectory()) {
|
||||
fs.rmSync(entryPath, { recursive: true, force: true })
|
||||
} else {
|
||||
fs.unlinkSync(entryPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Cleaned up assets directory, keeping only: ${filesToKeep.join(', ')}`)
|
||||
console.log('Widget built successfully for Docker!')
|
||||
console.log(`Files available at: ${assetsDir}`)
|
||||
} catch (error) {
|
||||
console.error('Docker widget build failed:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
buildWidgetDocker()
|
||||
@@ -0,0 +1,67 @@
|
||||
import { build } from 'vite'
|
||||
import { resolve } from 'path'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import dotenv from 'dotenv'
|
||||
|
||||
// Load production environment variables
|
||||
dotenv.config({ path: '.env.prod' })
|
||||
|
||||
const config = resolve(process.cwd(), 'vite.widget.config.ts')
|
||||
const assetsDir = resolve(process.cwd(), '../backend/assets')
|
||||
const filesToKeep = ['widget.js', 'widget.css']
|
||||
|
||||
async function buildWidgetProd() {
|
||||
try {
|
||||
console.log('Building widget with production configuration...')
|
||||
|
||||
// Set NODE_ENV to production for the build
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
// Run the Vite build
|
||||
await build({ configFile: config })
|
||||
console.log('Vite build completed')
|
||||
|
||||
// Copy CSS file from unused directory to the root assets directory
|
||||
const unusedDir = path.join(assetsDir, 'unused')
|
||||
if (fs.existsSync(unusedDir)) {
|
||||
const files = fs.readdirSync(unusedDir)
|
||||
const cssFile = files.find(file => file.endsWith('.css'))
|
||||
|
||||
if (cssFile) {
|
||||
const sourcePath = path.join(unusedDir, cssFile)
|
||||
const destPath = path.join(assetsDir, 'widget.css')
|
||||
|
||||
fs.copyFileSync(sourcePath, destPath)
|
||||
console.log(`Copied CSS file to ${destPath}`)
|
||||
}
|
||||
|
||||
// Clean up unused directory
|
||||
fs.rmSync(unusedDir, { recursive: true, force: true })
|
||||
console.log('Cleaned up unused directory')
|
||||
}
|
||||
|
||||
// Clean up the assets directory - keep only widget.js and widget.css
|
||||
const entries = fs.readdirSync(assetsDir)
|
||||
|
||||
for (const entry of entries) {
|
||||
if (!filesToKeep.includes(entry)) {
|
||||
const entryPath = path.join(assetsDir, entry)
|
||||
|
||||
if (fs.statSync(entryPath).isDirectory()) {
|
||||
fs.rmSync(entryPath, { recursive: true, force: true })
|
||||
} else {
|
||||
fs.unlinkSync(entryPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Cleaned up assets directory, keeping only: ${filesToKeep.join(', ')}`)
|
||||
console.log('Production widget built successfully!')
|
||||
} catch (error) {
|
||||
console.error('Production build failed:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
buildWidgetProd()
|
||||
@@ -0,0 +1,63 @@
|
||||
import { build } from 'vite'
|
||||
import { resolve } from 'path'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import dotenv from 'dotenv'
|
||||
|
||||
// Load the local .env so a plain `build:widget` bakes the local API URL
|
||||
// (VITE_API_URL) instead of falling through to the widget-env default.
|
||||
dotenv.config({ path: '.env' })
|
||||
|
||||
const config = resolve(process.cwd(), 'vite.widget.config.ts')
|
||||
const assetsDir = resolve(process.cwd(), '../backend/assets')
|
||||
const filesToKeep = ['widget.js', 'widget.css']
|
||||
|
||||
async function buildWidget() {
|
||||
try {
|
||||
// Run the Vite build
|
||||
await build({ configFile: config })
|
||||
console.log('Vite build completed')
|
||||
|
||||
// Copy CSS file from unused directory to the root assets directory
|
||||
const unusedDir = path.join(assetsDir, 'unused')
|
||||
if (fs.existsSync(unusedDir)) {
|
||||
const files = fs.readdirSync(unusedDir)
|
||||
const cssFile = files.find(file => file.endsWith('.css'))
|
||||
|
||||
if (cssFile) {
|
||||
const sourcePath = path.join(unusedDir, cssFile)
|
||||
const destPath = path.join(assetsDir, 'widget.css')
|
||||
|
||||
fs.copyFileSync(sourcePath, destPath)
|
||||
console.log(`Copied CSS file to ${destPath}`)
|
||||
}
|
||||
|
||||
// Clean up unused directory
|
||||
fs.rmSync(unusedDir, { recursive: true, force: true })
|
||||
console.log('Cleaned up unused directory')
|
||||
}
|
||||
|
||||
// Clean up the assets directory - keep only widget.js and widget.css
|
||||
const entries = fs.readdirSync(assetsDir)
|
||||
|
||||
for (const entry of entries) {
|
||||
if (!filesToKeep.includes(entry)) {
|
||||
const entryPath = path.join(assetsDir, entry)
|
||||
|
||||
if (fs.statSync(entryPath).isDirectory()) {
|
||||
fs.rmSync(entryPath, { recursive: true, force: true })
|
||||
} else {
|
||||
fs.unlinkSync(entryPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Cleaned up assets directory, keeping only: ${filesToKeep.join(', ')}`)
|
||||
console.log('Widget built successfully!')
|
||||
} catch (error) {
|
||||
console.error('Build failed:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
buildWidget()
|
||||
@@ -0,0 +1,56 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as dotenv from 'dotenv'
|
||||
|
||||
// Load development environment variables
|
||||
dotenv.config({ path: '.env.dev' })
|
||||
|
||||
// (swenv.js is gone — the app service worker src/sw.ts inlines its Firebase
|
||||
// config at build time via import.meta.env)
|
||||
|
||||
// Create config.js content for development using environment variables
|
||||
const configContent = `// Runtime configuration - this file gets replaced at container startup
|
||||
// Assigned to self, not window, so the service worker can importScripts()
|
||||
// it too; in a page self === window, so window.APP_CONFIG still works.
|
||||
self.APP_CONFIG = {
|
||||
// API URLs
|
||||
API_URL: "${process.env.VITE_API_URL || 'http://localhost:8000/api/v1'}",
|
||||
WS_URL: "${process.env.VITE_WS_URL || 'ws://localhost:8000'}",
|
||||
WIDGET_URL: "${process.env.VITE_WIDGET_URL || 'http://localhost:8000'}",
|
||||
|
||||
// Firebase Configuration
|
||||
FIREBASE_API_KEY: "${process.env.VITE_FIREBASE_API_KEY || 'your_firebase_api_key_here'}",
|
||||
FIREBASE_AUTH_DOMAIN: "${process.env.VITE_FIREBASE_AUTH_DOMAIN || 'your_firebase_auth_domain_here'}",
|
||||
FIREBASE_PROJECT_ID: "${process.env.VITE_FIREBASE_PROJECT_ID || 'your_firebase_project_id_here'}",
|
||||
FIREBASE_MESSAGING_SENDER_ID: "${process.env.VITE_FIREBASE_MESSAGING_SENDER_ID || '680125690355'}",
|
||||
FIREBASE_APP_ID: "${process.env.VITE_FIREBASE_APP_ID || 'your_firebase_app_id_here'}",
|
||||
FIREBASE_STORAGE_BUCKET: "${process.env.VITE_FIREBASE_STORAGE_BUCKET || 'your_firebase_storage_bucket_here'}",
|
||||
FIREBASE_MEASUREMENT_ID: "${process.env.VITE_FIREBASE_MEASUREMENT_ID || 'your_firebase_measurement_id_here'}",
|
||||
FIREBASE_VAPID_KEY: "${process.env.VITE_FIREBASE_VAPID_KEY || 'your_firebase_vapid_key_here'}",
|
||||
|
||||
// Google Fonts API
|
||||
GOOGLE_FONTS_API_KEY: "${process.env.VITE_GOOGLE_FONTS_API_KEY || 'your_google_fonts_api_key_here'}",
|
||||
|
||||
// Demo Widget ID
|
||||
DEMO_WIDGET_ID: "${process.env.VITE_DEMO_WIDGET_ID || 'your_demo_widget_id_here'}",
|
||||
|
||||
// Node Environment
|
||||
NODE_ENV: "development",
|
||||
HOST: "${process.env.VITE_HOST || '0.0.0.0'}"
|
||||
};
|
||||
`
|
||||
|
||||
// Write config to both public and dist directories
|
||||
const publicConfigPath = './public/config.js'
|
||||
const distConfigPath = './dist/config.js'
|
||||
|
||||
// Write to public directory
|
||||
fs.writeFileSync(publicConfigPath, configContent)
|
||||
console.log('Development config file generated to public/config.js')
|
||||
|
||||
// Ensure dist directory exists and write to dist directory
|
||||
if (!fs.existsSync('./dist')) {
|
||||
fs.mkdirSync('./dist', { recursive: true })
|
||||
}
|
||||
fs.writeFileSync(distConfigPath, configContent)
|
||||
console.log('Development config file generated to dist/config.js')
|
||||
@@ -0,0 +1,57 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as dotenv from 'dotenv'
|
||||
|
||||
// Load production environment variables
|
||||
dotenv.config({ path: '.env.prod' })
|
||||
|
||||
// (swenv.js is gone — the app service worker src/sw.ts inlines its Firebase
|
||||
// config at build time via import.meta.env)
|
||||
|
||||
// Create config.js content for production using environment variables
|
||||
const configContent = `// Runtime configuration - this file gets replaced at container startup
|
||||
// Assigned to self, not window, so the service worker can importScripts()
|
||||
// it too; in a page self === window, so window.APP_CONFIG still works.
|
||||
self.APP_CONFIG = {
|
||||
// API URLs
|
||||
API_URL: "${process.env.VITE_API_URL || 'https://api.chattermate.chat/api/v1'}",
|
||||
WS_URL: "${process.env.VITE_WS_URL || 'wss://api.chattermate.chat'}",
|
||||
WIDGET_URL: "${process.env.VITE_WIDGET_URL || 'https://api.chattermate.chat'}",
|
||||
|
||||
// Firebase Configuration
|
||||
FIREBASE_API_KEY: "${process.env.VITE_FIREBASE_API_KEY || ''}",
|
||||
FIREBASE_AUTH_DOMAIN: "${process.env.VITE_FIREBASE_AUTH_DOMAIN || ''}",
|
||||
FIREBASE_PROJECT_ID: "${process.env.VITE_FIREBASE_PROJECT_ID || ''}",
|
||||
FIREBASE_MESSAGING_SENDER_ID: "${process.env.VITE_FIREBASE_MESSAGING_SENDER_ID || ''}",
|
||||
FIREBASE_APP_ID: "${process.env.VITE_FIREBASE_APP_ID || ''}",
|
||||
FIREBASE_STORAGE_BUCKET: "${process.env.VITE_FIREBASE_STORAGE_BUCKET || ''}",
|
||||
FIREBASE_MEASUREMENT_ID: "${process.env.VITE_FIREBASE_MEASUREMENT_ID || ''}",
|
||||
FIREBASE_VAPID_KEY: "${process.env.VITE_FIREBASE_VAPID_KEY || ''}",
|
||||
|
||||
// Google Fonts API
|
||||
GOOGLE_FONTS_API_KEY: "${process.env.VITE_GOOGLE_FONTS_API_KEY || ''}",
|
||||
|
||||
// Demo Widget ID
|
||||
DEMO_WIDGET_ID: "${process.env.VITE_DEMO_WIDGET_ID || ''}",
|
||||
|
||||
// Node Environment
|
||||
NODE_ENV: "production",
|
||||
HOST: "${process.env.VITE_HOST || '0.0.0.0'}",
|
||||
VITE_SHOPIFY_API_KEY: "${process.env.VITE_SHOPIFY_API_KEY || ''}",
|
||||
};
|
||||
`
|
||||
|
||||
// Write config to both public and dist directories
|
||||
const publicConfigPath = './public/config.js'
|
||||
const distConfigPath = './dist/config.js'
|
||||
|
||||
// Write to public directory
|
||||
fs.writeFileSync(publicConfigPath, configContent)
|
||||
console.log('Production config file generated to public/config.js')
|
||||
|
||||
// Ensure dist directory exists and write to dist directory
|
||||
if (!fs.existsSync('./dist')) {
|
||||
fs.mkdirSync('./dist', { recursive: true })
|
||||
}
|
||||
fs.writeFileSync(distConfigPath, configContent)
|
||||
console.log('Production config file generated to dist/config.js')
|
||||
Reference in new issue
Block a user