Skip to content

Commit

Permalink
Update esbuild config to use ESM (#934)
Browse files Browse the repository at this point in the history
* Update esbuild config to use ESM, provide switchover via `bin/bt esbuild update` command

* fix testing

* fix typo

* better wording on switch to ESM

* Mention correct current Node versions
  • Loading branch information
jaredcwhite authored Nov 16, 2024
1 parent 3870ddb commit b29b51c
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -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
// }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down
20 changes: 17 additions & 3 deletions bridgetown-core/lib/bridgetown-core/commands/esbuild/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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`!"
1 change: 1 addition & 0 deletions bridgetown-core/lib/site_template/package.json.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "<%= @site_name %>",
"version": "1.0.0",
"type": "module",
"private": true,
"scripts": {
"esbuild": "node esbuild.config.js --minify",
Expand Down
2 changes: 1 addition & 1 deletion bridgetown-core/lib/site_template/postcss.config.js.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default {
plugins: {
'postcss-flexbugs-fixes': {},
'postcss-preset-env': {
Expand Down
2 changes: 1 addition & 1 deletion bridgetown-core/test/test_esbuild_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion bridgetown-website/src/_data/requirements.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
min_ruby: 3.1
min_node: 20
min_node: 20.6
2 changes: 1 addition & 1 deletion bridgetown-website/src/_docs/automations.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions bridgetown-website/src/_docs/installation/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit b29b51c

Please sign in to comment.