From da5fec4a9441c928830c5998f895d1c0993ffbae Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Thu, 9 Jan 2025 08:15:48 -0500 Subject: [PATCH] feat: Adds browser-sync / hot reload --- Sources/App/BrowserSync.swift | 17 ++++++++++++++ Sources/App/configure.swift | 4 ++++ Sources/App/entrypoint.swift | 44 +++++++++++++++++------------------ swift-dev | 6 +++++ 4 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 Sources/App/BrowserSync.swift create mode 100755 swift-dev diff --git a/Sources/App/BrowserSync.swift b/Sources/App/BrowserSync.swift new file mode 100644 index 0000000..df854ab --- /dev/null +++ b/Sources/App/BrowserSync.swift @@ -0,0 +1,17 @@ +import Foundation +import Vapor + +#if DEBUG + struct BrowserSyncHandler: LifecycleHandler { + func didBoot(_ application: Application) throws { + let process = Process() + process.executableURL = URL(filePath: "/bin/sh") + process.arguments = ["-c", "browser-sync reload"] + do { + try process.run() + } catch { + print("Could not auto-reload: \(error)") + } + } + } +#endif diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 31b0434..5360513 100644 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -11,6 +11,10 @@ public func configure(_ app: Application) async throws { app.middleware.use(app.sessions.middleware) app.middleware.use(User.sessionAuthenticator()) + #if DEBUG + app.lifecycle.use(BrowserSyncHandler()) + #endif + switch app.environment { case .production, .development: app.databases.use(DatabaseConfigurationFactory.sqlite(.file("db.sqlite")), as: .sqlite) diff --git a/Sources/App/entrypoint.swift b/Sources/App/entrypoint.swift index 2e85ece..846c5b3 100644 --- a/Sources/App/entrypoint.swift +++ b/Sources/App/entrypoint.swift @@ -1,31 +1,31 @@ -import Vapor import Logging import NIOCore import NIOPosix +import Vapor @main enum Entrypoint { - static func main() async throws { - var env = try Environment.detect() - try LoggingSystem.bootstrap(from: &env) - - let app = try await Application.make(env) + static func main() async throws { + var env = try Environment.detect() + try LoggingSystem.bootstrap(from: &env) - // This attempts to install NIO as the Swift Concurrency global executor. - // You can enable it if you'd like to reduce the amount of context switching between NIO and Swift Concurrency. - // Note: this has caused issues with some libraries that use `.wait()` and cleanly shutting down. - // If enabled, you should be careful about calling async functions before this point as it can cause assertion failures. - // let executorTakeoverSuccess = NIOSingletons.unsafeTryInstallSingletonPosixEventLoopGroupAsConcurrencyGlobalExecutor() - // app.logger.debug("Tried to install SwiftNIO's EventLoopGroup as Swift's global concurrency executor", metadata: ["success": .stringConvertible(executorTakeoverSuccess)]) - - do { - try await configure(app) - } catch { - app.logger.report(error: error) - try? await app.asyncShutdown() - throw error - } - try await app.execute() - try await app.asyncShutdown() + let app = try await Application.make(env) + + // This attempts to install NIO as the Swift Concurrency global executor. + // You can enable it if you'd like to reduce the amount of context switching between NIO and Swift Concurrency. + // Note: this has caused issues with some libraries that use `.wait()` and cleanly shutting down. + // If enabled, you should be careful about calling async functions before this point as it can cause assertion failures. + // let executorTakeoverSuccess = NIOSingletons.unsafeTryInstallSingletonPosixEventLoopGroupAsConcurrencyGlobalExecutor() + // app.logger.debug("Tried to install SwiftNIO's EventLoopGroup as Swift's global concurrency executor", metadata: ["success": .stringConvertible(executorTakeoverSuccess)]) + + do { + try await configure(app) + } catch { + app.logger.report(error: error) + try? await app.asyncShutdown() + throw error } + try await app.execute() + try await app.asyncShutdown() + } } diff --git a/swift-dev b/swift-dev new file mode 100755 index 0000000..b788cb0 --- /dev/null +++ b/swift-dev @@ -0,0 +1,6 @@ +#!/usr/bin/env zsh +touch .build/browser-dev-sync +browser-sync start -p localhost:8080 --ws & + +watchexec -w Sources -e .swift -r 'swift build --product App && touch .build/browser-dev-sync' & +watchexec -w .build/browser-dev-sync --ignore-nothing -r '.build/debug/App'