diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8b4f2d0..f0cca03d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,14 +68,9 @@ jobs: password: postgres port: 5432 postgres-version: 18 - - uses: actions/setup-node@v6 + - uses: oven-sh/setup-bun@v2 with: - node-version: 24 - - name: Enable Corepack (for yarn) - run: | - corepack enable - corepack prepare yarn@1.22.22 --activate - yarn --version + bun-version: latest - uses: crystal-lang/install-crystal@v1 with: crystal: latest @@ -110,14 +105,9 @@ jobs: password: postgres port: 5432 postgres-version: 18 - - uses: actions/setup-node@v6 + - uses: oven-sh/setup-bun@v2 with: - node-version: 24 - - name: Enable Corepack (for yarn) - run: | - corepack enable - corepack prepare yarn@1.22.22 --activate - yarn --version + bun-version: latest - uses: crystal-lang/install-crystal@v1 with: crystal: latest diff --git a/src/browser_app_skeleton/package.json.ecr b/src/browser_app_skeleton/package.json.ecr index 35baa2a6..412c1bf1 100644 --- a/src/browser_app_skeleton/package.json.ecr +++ b/src/browser_app_skeleton/package.json.ecr @@ -7,15 +7,8 @@ "modern-normalize": "^3.0.1" }, "scripts": { - "heroku-postbuild": "yarn build", - "dev": "vite", - "build": "vite build", - "preview": "vite preview", - "watch": "vite build --watch" - }, - "devDependencies": { - "vite": "^7.3.1", - "vite-plugin-compression": "^0.5.1", - "vite-plugin-dev-manifest": "^1.4.1" + "build": "bun lib/lucky/src/bun/bake.js", + "dev": "bun run build --dev", + "prod": "bun run build --prod" } } \ No newline at end of file diff --git a/src/browser_app_skeleton/src/components/shared/layout_head.cr.ecr b/src/browser_app_skeleton/src/components/shared/layout_head.cr.ecr index f4de97b3..0fe791ed 100644 --- a/src/browser_app_skeleton/src/components/shared/layout_head.cr.ecr +++ b/src/browser_app_skeleton/src/components/shared/layout_head.cr.ecr @@ -11,8 +11,12 @@ class Shared::LayoutHead < BaseComponent responsive_meta_tag # Development helper used with the `lucky watch` command. - # Reloads the browser when files are updated. + # Reloads the browser when Crystal files are updated. live_reload_connect_tag if LuckyEnv.development? + + # Development helper used with the `bun run dev` command. + # Reloads the browser when asset files are updated. + bun_reload_connect_tag if LuckyEnv.development? end end end diff --git a/src/browser_app_skeleton/src/css/app.css.ecr b/src/browser_app_skeleton/src/css/app.css.ecr index 3dbc0b90..a4bd288a 100644 --- a/src/browser_app_skeleton/src/css/app.css.ecr +++ b/src/browser_app_skeleton/src/css/app.css.ecr @@ -8,8 +8,6 @@ * * @import "./variables/colors"; * -* Note: Vite automatically resolves imports from node_modules -* https://stackoverflow.com/questions/39535760/what-does-a-tilde-in-a-css-url-do */ @import 'modern-normalize/modern-normalize.css'; diff --git a/src/browser_app_skeleton/vite.config.js.ecr b/src/browser_app_skeleton/vite.config.js.ecr deleted file mode 100644 index a9405e5f..00000000 --- a/src/browser_app_skeleton/vite.config.js.ecr +++ /dev/null @@ -1,98 +0,0 @@ -import { defineConfig } from 'vite' -import { resolve } from 'path' -import compression from 'vite-plugin-compression' -import devManifest from 'vite-plugin-dev-manifest' - -// https://vitejs.dev/config/ -export default defineConfig({ - // Root directory is project root (where vite.config.js is) - root: '.', - - // Public directory for static assets - publicDir: 'public/assets', - - // Build configuration - build: { - // Output directory - outDir: 'public', - // Don't empty the output directory (Lucky serves from public/) - emptyOutDir: false, - // Generate manifest for Lucky asset helpers - manifest: true, - // Define entry points - rollupOptions: { - input: { - // These entry names map to asset paths in Lucky: - // "app" -> asset("js/app.js") - // "styles" -> asset("css/app.css") - app: resolve(__dirname, 'src/js/app.js'), - styles: resolve(__dirname, 'src/css/app.css') - } - }, - // Asset output configuration - assetsDir: 'assets', - // Source maps for production - sourcemap: process.env.NODE_ENV === "production" ? false : true, - }, - - // CSS configuration - css: { - devSourcemap: true - }, - - // Server configuration for development - server: { - // This allows Vite to be accessed from Lucky's dev server - origin: 'http://localhost:3001', - port: 3001, - strictPort: true, - // Enable HMR - hmr: { - host: 'localhost' - }, - // Exclude non-frontend directories from file watching to prevent memory leaks - watch: { - ignored: [ - "**", // Ignore all files and subdirectories in the root - "!**/src/js/**", // Re-include the 'src/js' directory - "!**/src/css/**", // Re-include the 'src/css' directory - "!**/public/**", // Re-include the 'public' directory - "!**/vite.config.js", // Ensure the config file itself is watched - // Add other specific folders you want to watch with the '!**/{folderName}/**' pattern - ], - }, - }, - - // Preview server configuration (for testing production builds) - preview: { - port: 3001 - }, - - // Plugins - plugins: [ - // Generate dev manifest for Lucky's compile-time asset validation - devManifest({ - manifestName: 'manifest.dev', - clearOnClose: false - }), - // Gzip compression for production builds - process.env.NODE_ENV === 'production' && compression({ - algorithm: 'gzip', - ext: '.gz', - threshold: 1024, - }), - // Add Brotli compression if desired - // process.env.NODE_ENV === 'production' && compression({ - // algorithm: 'brotliCompress', - // ext: '.br', - // threshold: 1024, - // }), - ].filter(Boolean), - - // Resolve configuration - resolve: { - alias: { - '@': resolve(__dirname, 'src') - } - } -}) \ No newline at end of file diff --git a/src/generators/web.cr b/src/generators/web.cr index 5dde2e4c..3b075d89 100644 --- a/src/generators/web.cr +++ b/src/generators/web.cr @@ -103,9 +103,8 @@ class LuckyCli::Generators::Web ignore_list.concat([ "/public/js", "/public/css", - "/public/.vite", "/public/assets", - "/public/manifest.dev.json", + "/public/*manifest*.json", "/node_modules", "yarn-error.log", ]) diff --git a/src/lucky_cli/browser_src_template.cr b/src/lucky_cli/browser_src_template.cr index b24ec358..8496ea18 100644 --- a/src/lucky_cli/browser_src_template.cr +++ b/src/lucky_cli/browser_src_template.cr @@ -12,9 +12,6 @@ class BrowserSrcTemplate def template_folder LuckyTemplate.create_folder do |root_dir| - root_dir.add_file("vite.config.js") do |io| - ECR.embed("#{__DIR__}/../browser_app_skeleton/vite.config.js.ecr", io) - end root_dir.add_file("package.json") do |io| ECR.embed("#{__DIR__}/../browser_app_skeleton/package.json.ecr", io) end @@ -30,7 +27,6 @@ class BrowserSrcTemplate public_dir.add_file("favicon.ico") do |io| ECR.embed("#{__DIR__}/../browser_app_skeleton/public/favicon.ico.ecr", io) end - # Vite generates its manifest automatically public_dir.add_file("robots.txt") do |io| ECR.embed("#{__DIR__}/../browser_app_skeleton/public/robots.txt.ecr", io) end diff --git a/src/lucky_cli/wizard/web.cr b/src/lucky_cli/wizard/web.cr index fb8af70b..c37d96f1 100644 --- a/src/lucky_cli/wizard/web.cr +++ b/src/lucky_cli/wizard/web.cr @@ -37,8 +37,8 @@ class LuckyCli::Wizard::Web Full (recommended for most apps) ● Great for server rendered HTML or Single Page Applications - ● Vite included for fast development and optimized builds - ● Setup to compile CSS and JavaScript + ● Use Bun for fast development and optimized builds + ● Setup to compile CSS and Javascript/Typescript ● Support for rendering HTML API diff --git a/src/web_app_skeleton/Procfile.dev.ecr b/src/web_app_skeleton/Procfile.dev.ecr index 4fe43d31..08461f7f 100644 --- a/src/web_app_skeleton/Procfile.dev.ecr +++ b/src/web_app_skeleton/Procfile.dev.ecr @@ -3,5 +3,5 @@ system_check: crystal script/system_check.cr web: lucky watch <%- else -%> web: lucky watch --reload-browser -assets: yarn dev +assets: bun run dev <%- end -%> \ No newline at end of file diff --git a/src/web_app_skeleton/config/server.cr.ecr b/src/web_app_skeleton/config/server.cr.ecr index b4c2f25c..e56dbf59 100644 --- a/src/web_app_skeleton/config/server.cr.ecr +++ b/src/web_app_skeleton/config/server.cr.ecr @@ -21,9 +21,9 @@ Lucky::Server.configure do |settings| settings.port = Lucky::ServerSettings.port end - # Configure asset host for Vite + # Configure asset host if LuckyEnv.development? - # In development, Vite serves assets from its dev server + # In development, assets are served from the dev server settings.asset_host = "" elsif LuckyEnv.production? # In production, Lucky serves the built assets diff --git a/src/web_app_skeleton/docker/dev_entrypoint.sh.ecr b/src/web_app_skeleton/docker/dev_entrypoint.sh.ecr index 94d15ffd..0597e9d4 100755 --- a/src/web_app_skeleton/docker/dev_entrypoint.sh.ecr +++ b/src/web_app_skeleton/docker/dev_entrypoint.sh.ecr @@ -28,8 +28,8 @@ if ! [ -d bin ] ; then mkdir bin fi <%- if browser? -%> -echo 'Installing npm packages...' -yarn install +echo 'Installing bun packages...' +bun install --no-progress <%- end -%> if ! shards check ; then echo 'Installing shards...' diff --git a/src/web_app_skeleton/docker/development.dockerfile.ecr b/src/web_app_skeleton/docker/development.dockerfile.ecr index b4008eb3..4e22cbc5 100644 --- a/src/web_app_skeleton/docker/development.dockerfile.ecr +++ b/src/web_app_skeleton/docker/development.dockerfile.ecr @@ -2,31 +2,21 @@ FROM crystallang/crystal:<%= crystal_version %> # Install utilities required to make this Dockerfile run RUN apt-get update && \ - apt-get install -y wget -<%- if browser? -%> -# Add the nodesource ppa to apt. Update this to change the nodejs version. -RUN wget https://deb.nodesource.com/setup_16.x -O- | bash + apt-get install -y wget curl unzip # Apt installs: -# - nodejs (from above ppa) is required for front-end apps. # - Postgres cli tools are required for lucky-cli. -# - tmux is required for the Overmind process manager. RUN apt-get update && \ - apt-get install -y nodejs postgresql-client tmux && \ + apt-get install -y postgresql-client && \ rm -rf /var/lib/apt/lists/* -# NPM global installs: -# - Yarn is the default package manager for the node component of a lucky +<%- if browser? -%> +# Bun global installs: +# - Bun is the default package manager for the asset component of a lucky # browser app. -RUN npm install -g yarn -<%- else -%> - -# Apt installs: -# - Postgres cli tools are required for lucky-cli. -# - tmux is required for the Overmind process manager. -RUN apt-get update && \ - apt-get install -y postgresql-client tmux && \ - rm -rf /var/lib/apt/lists/* +RUN curl -fsSL https://bun.sh/install | bash +ENV BUN_INSTALL="/root/.bun" +ENV PATH="$BUN_INSTALL/bin:$PATH" <%- end -%> # Install lucky cli @@ -40,4 +30,3 @@ WORKDIR /app ENV DATABASE_URL=postgres://postgres:postgres@host.docker.internal:5432/postgres EXPOSE 3000 EXPOSE 3001 - diff --git a/src/web_app_skeleton/script/setup.cr.ecr b/src/web_app_skeleton/script/setup.cr.ecr index 0fcdb517..f80bf821 100644 --- a/src/web_app_skeleton/script/setup.cr.ecr +++ b/src/web_app_skeleton/script/setup.cr.ecr @@ -6,19 +6,21 @@ require "./system_check" print_done +notice "Installing shards" +run_command "shards", "install" + +print_done + <%- if browser? -%> -notice "Installing node dependencies" -run_command "yarn", "install", "--no-progress" +notice "Installing Bun dependencies" +run_command "bun", "install", "--no-progress" notice "Building initial asset manifest" -run_command "yarn", "build" +run_command "bun", "run", "build" print_done <%- end -%> -notice "Installing shards" -run_command "shards", "install" - if !File.exists?(".env") notice "No .env found. Creating one." File.touch ".env" @@ -34,4 +36,4 @@ run_command "lucky", "db.seed.required_data" run_command "lucky", "db.seed.sample_data" print_done -notice "Run 'lucky dev' to start the app" \ No newline at end of file +notice "Run 'lucky dev' to start the app" diff --git a/src/web_app_skeleton/script/system_check.cr.ecr b/src/web_app_skeleton/script/system_check.cr.ecr index 39fbd24d..8e47410b 100755 --- a/src/web_app_skeleton/script/system_check.cr.ecr +++ b/src/web_app_skeleton/script/system_check.cr.ecr @@ -11,8 +11,8 @@ require "./helpers/*" # should go in your Procfile.dev. <%- if browser? -%> -if command_not_found "yarn" - print_error "Yarn is not installed\n See https://yarnpkg.com/lang/en/docs/install/ for install instructions." +if command_not_found "bun" + print_error "Bun is not installed\n See https://bun.sh/ for install instructions." end <%- end -%> diff --git a/src/web_app_skeleton/src/app.cr.ecr b/src/web_app_skeleton/src/app.cr.ecr index 9780afbb..a729e9b1 100644 --- a/src/web_app_skeleton/src/app.cr.ecr +++ b/src/web_app_skeleton/src/app.cr.ecr @@ -2,19 +2,7 @@ require "./shards" <%- if browser? -%> # Load the asset manifest -# In development, vite-plugin-dev-manifest creates public/manifest.dev.json -# In production, Vite creates public/.vite/manifest.json -# The manifest path is determined by which file exists at compile time -{% if file_exists?("public/manifest.dev.json") %} - Lucky::AssetHelpers.load_manifest "public/manifest.dev.json", use_vite: true -{% elsif file_exists?("public/.vite/manifest.json") %} - Lucky::AssetHelpers.load_manifest "public/.vite/manifest.json", use_vite: true -{% else %} - # For initial compilation, we'll assume development mode - # The dev server will create the manifest before the app is recompiled - Lucky::AssetHelpers.load_manifest "public/manifest.dev.json", use_vite: true -{% end %} - +Lucky::AssetHelpers.load_manifest(from: :bun) <%- end -%> require "../config/server" require "./app_database"