diff --git a/bridgetown-core/lib/bridgetown-core/commands/esbuild/esbuild.config.js b/bridgetown-core/lib/bridgetown-core/commands/esbuild/esbuild.config.js index 842c855c6..d45d834e1 100644 --- a/bridgetown-core/lib/bridgetown-core/commands/esbuild/esbuild.config.js +++ b/bridgetown-core/lib/bridgetown-core/commands/esbuild/esbuild.config.js @@ -1,16 +1,17 @@ -const build = require("./config/esbuild.defaults.js") +import build from "./config/esbuild.defaults.js" // You can customize this as you wish, perhaps to add new esbuild plugins. // // ``` -// const path = require("path") -// const esbuildCopy = require('esbuild-plugin-copy').default +// import { copy } from 'esbuild-plugin-copy' +// // const esbuildOptions = { // plugins: [ -// esbuildCopy({ +// copy({ +// resolveFrom: 'cwd', // assets: { -// from: [path.resolve(__dirname, 'node_modules/somepackage/files/*')], -// to: [path.resolve(__dirname, 'output/_bridgetown/somepackage/files')], +// from: ['./node_modules/somepackage/files/*')], +// to: ['./output/_bridgetown/somepackage/files')], // }, // verbose: false // }), diff --git a/bridgetown-core/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb b/bridgetown-core/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb index b824886cb..b3fcb9c88 100644 --- a/bridgetown-core/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +++ b/bridgetown-core/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb @@ -16,19 +16,19 @@ const autogeneratedBridgetownConfig = { "islandsDir": "_islands" } -const path = require("path") -const fsLib = require("fs") +import path from "path" +import fsLib from "fs" const fs = fsLib.promises -const { pathToFileURL, fileURLToPath } = require("url") -const glob = require("glob") -const postcss = require("postcss") -const postCssImport = require("postcss-import") -const readCache = require("read-cache") +import { pathToFileURL, fileURLToPath } from "url" +import { glob } from "glob" +import postcss from "postcss" +import postCssImport from "postcss-import" +import readCache from "read-cache" // Detect if an NPM package is available const moduleAvailable = name => { try { - require.resolve(name) + import.meta.resolve(name) return true } catch (e) { } return false @@ -43,7 +43,7 @@ const generateSourceMappingURL = sourceMap => { // Import Sass if available let sass if (moduleAvailable("sass")) { - sass = require("sass") + sass = (await import("sass")).default } // Glob plugin derived from: @@ -288,9 +288,9 @@ const bridgetownConfigured = (bridgetownConfig, outputFolder) => { } // Load the PostCSS config from postcss.config.js or whatever else is a supported location/format -const postcssrc = require("postcss-load-config") +const postcssrc = (await import("postcss-load-config")).default -module.exports = async (esbuildOptions, ...args) => { +export default async (esbuildOptions, ...args) => { let outputFolder; if (typeof esbuildOptions === "string") { // legacy syntax where first argument is output folder outputFolder = esbuildOptions @@ -313,7 +313,7 @@ module.exports = async (esbuildOptions, ...args) => { esbuildOptions.plugins.push(bridgetownPreset(bridgetownConfig)) if (esbuildOptions.bridgetownConfig) delete esbuildOptions.bridgetownConfig - const esbuild = require("esbuild") + const esbuild = (await import("esbuild")).default const entryPoints = esbuildOptions.entryPoints || ["./frontend/javascript/index.js"] if (esbuildOptions.entryPoints) delete esbuildOptions.entryPoints diff --git a/bridgetown-core/lib/bridgetown-core/commands/esbuild/update.rb b/bridgetown-core/lib/bridgetown-core/commands/esbuild/update.rb index a229819d1..3d2d9ddb3 100644 --- a/bridgetown-core/lib/bridgetown-core/commands/esbuild/update.rb +++ b/bridgetown-core/lib/bridgetown-core/commands/esbuild/update.rb @@ -2,8 +2,22 @@ template "esbuild.defaults.js.erb", "config/esbuild.defaults.js", force: true copy_file "jsconfig.json" -say "🎉 esbuild configuration updated successfully!" + +unless File.read("package.json").include?('"type": "module"') + insert_into_file "package.json", + after: '"private": true,' do + <<-JS.chomp + + "type": "module", + JS + end +end + +gsub_file "postcss.config.js", "module.exports =", "export default" +gsub_file "esbuild.config.js", 'const build = require("./config/esbuild.defaults.js")', + 'import build from "./config/esbuild.defaults.js"' +add_npm_package "esbuild@latest glob@latest" unless Bridgetown.env.test? + +say "\n🎉 esbuild configuration updated successfully!" say "You may need to add `$styles/` to the front of your main CSS imports." say "See https://www.bridgetownrb.com/docs/frontend-assets#esbuild-setup for details." -say "⚠️ Don't forget to update the esbuild version in your `package.json` file to \"^0.20.2\"" -say "and run `npm install`!" diff --git a/bridgetown-core/lib/site_template/package.json.erb b/bridgetown-core/lib/site_template/package.json.erb index 776052b4e..48b4ddc56 100644 --- a/bridgetown-core/lib/site_template/package.json.erb +++ b/bridgetown-core/lib/site_template/package.json.erb @@ -1,6 +1,7 @@ { "name": "<%= @site_name %>", "version": "1.0.0", + "type": "module", "private": true, "scripts": { "esbuild": "node esbuild.config.js --minify", diff --git a/bridgetown-core/lib/site_template/postcss.config.js.erb b/bridgetown-core/lib/site_template/postcss.config.js.erb index f99c0c7c6..663755e6e 100644 --- a/bridgetown-core/lib/site_template/postcss.config.js.erb +++ b/bridgetown-core/lib/site_template/postcss.config.js.erb @@ -1,4 +1,4 @@ -module.exports = { +export default { plugins: { 'postcss-flexbugs-fixes': {}, 'postcss-preset-env': { diff --git a/bridgetown-core/test/test_esbuild_command.rb b/bridgetown-core/test/test_esbuild_command.rb index a0add5988..86a7fc3f0 100644 --- a/bridgetown-core/test/test_esbuild_command.rb +++ b/bridgetown-core/test/test_esbuild_command.rb @@ -68,7 +68,7 @@ def rakefile capture_stdout { @cmd.invoke(:esbuild, ["update"]) } end - assert_file_contains %r!module.exports!, esbuild_defaults + assert_file_contains %r!export default async!, esbuild_defaults refute_file_contains %r!OLD_VERSION!, esbuild_defaults end end diff --git a/bridgetown-website/src/_data/requirements.yml b/bridgetown-website/src/_data/requirements.yml index a1f589042..939e1a902 100644 --- a/bridgetown-website/src/_data/requirements.yml +++ b/bridgetown-website/src/_data/requirements.yml @@ -1,2 +1,2 @@ min_ruby: 3.1 -min_node: 20 +min_node: 20.6 diff --git a/bridgetown-website/src/_docs/automations.md b/bridgetown-website/src/_docs/automations.md index 6435c7c45..aa4ea458d 100644 --- a/bridgetown-website/src/_docs/automations.md +++ b/bridgetown-website/src/_docs/automations.md @@ -77,7 +77,7 @@ create_file "netlify.toml" do command = "bin/bridgetown deploy" publish = "output" [build.environment] - NODE_VERSION = "12" + NODE_VERSION = "22" [context.production.environment] BRIDGETOWN_ENV = "production" NETLIFY diff --git a/bridgetown-website/src/_docs/installation/upgrade.md b/bridgetown-website/src/_docs/installation/upgrade.md index 068bab686..66cc03b39 100644 --- a/bridgetown-website/src/_docs/installation/upgrade.md +++ b/bridgetown-website/src/_docs/installation/upgrade.md @@ -14,17 +14,23 @@ We’ve have a [Technical Help board](https://community.bridgetown.pub/c/technic ## Upgrading to Bridgetown 2.0 (Beta) -The first thing to know is that there are new minimum versions of both Ruby and Node for the v2 release cycle. In general, we try to support the previous two significant releases of these runtimes in addition to the current ones (aka Ruby 3.3 and Node 22) with each major version increase. So you will need to use a minimum of: +The first thing to know is that there are new minimum versions of both Ruby and Node.js for the v2 release cycle. In general, we try to support the previous two significant releases of these runtimes in addition to the current ones (aka Ruby 3.3 and Node 23) with each major version increase. So you will need to use a minimum of: * Ruby 3.1.4 (⚠️ there's a bug in earlier versions of Ruby 3.1 which will prevent Bridgetown to run) -* Node 20 +* Node 20.6 (⚠️ earlier versions of Node aren't compatible with esbuild's ESM-based config) -We do recommend switching to the latest versions (Ruby 3.3 and Node 22 as of the time of this writing) if possible. +If you use versioning dotfiles (for example `.ruby-version` and `.nvmrc`), you'll want to update those in your projects. We do recommend switching to the latest versions (Ruby 3.3 and Node 22 LTS or 23 as of the time of this writing) if possible. To upgrade to Bridgetown 2.0, edit your `Gemfile` to update the version numbers in the argument for the `bridgetown` and `bridgetown-routes` (if applicable) gem to `2.0.0.beta2` and then run `bundle update bridgetown`. We also recommend you run `bin/bridgetown esbuild update` so you get the latest default esbuild configuration Bridgetown provides, and you may need to update your `esbuild` version in `package.json` as well. +{%@ Note type: :warning do %} + +Only update your esbuild configuration if you're also willing to switch to ESModules (rather than CommonJS). This means your `package.json` file will include `"type": "module"` and Node JS code wil use `import` and `export` statements rather than `require` and `module.exports` going forward. [Here's an explainer](https://www.freecodecamp.org/news/modules-in-javascript/) about the JavaScript language switch to ESM. + +{% end %} + ### Switching from Yarn to NPM 📦 Bridgetown uses NPM now by default, rather than Yarn, for frontend package managing. You may continue to use Yarn on your existing projects, but if you'd like to switch to NPM, you can delete your `yarn.lock` file, run `npm install` (shorthand: `npm i`), and check in `package-lock.json` instead. You can also use [pnpm](https://pnpm.io) if you prefer. Bridgetown is now compatible with all three package managers.