Skip to content

Commit

Permalink
Merge pull request #189 from KonnorRogers/main
Browse files Browse the repository at this point in the history
Main -> Latest
  • Loading branch information
KonnorRogers authored May 26, 2024
2 parents edd97c5 + ef6dd8d commit 464ab71
Show file tree
Hide file tree
Showing 8 changed files with 440 additions and 317 deletions.
50 changes: 26 additions & 24 deletions docs/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
GEM
remote: https://rubygems.org/
specs:
activemodel (7.1.3.2)
activesupport (= 7.1.3.2)
activesupport (7.1.3.2)
activemodel (7.1.3.3)
activesupport (= 7.1.3.3)
activesupport (7.1.3.3)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
Expand All @@ -17,14 +17,14 @@ GEM
public_suffix (>= 2.0.2, < 6.0)
amazing_print (1.6.0)
base64 (0.2.0)
bigdecimal (3.1.7)
bridgetown (1.3.3)
bridgetown-builder (= 1.3.3)
bridgetown-core (= 1.3.3)
bridgetown-paginate (= 1.3.3)
bridgetown-builder (1.3.3)
bridgetown-core (= 1.3.3)
bridgetown-core (1.3.3)
bigdecimal (3.1.8)
bridgetown (1.3.4)
bridgetown-builder (= 1.3.4)
bridgetown-core (= 1.3.4)
bridgetown-paginate (= 1.3.4)
bridgetown-builder (1.3.4)
bridgetown-core (= 1.3.4)
bridgetown-core (1.3.4)
activemodel (>= 6.0, < 8.0)
activesupport (>= 6.0, < 8.0)
addressable (~> 2.4)
Expand All @@ -38,7 +38,7 @@ GEM
i18n (~> 1.0)
kramdown (~> 2.1)
kramdown-parser-gfm (~> 1.0)
liquid (~> 5.0)
liquid (>= 5.0, < 5.5)
listen (~> 3.0)
rake (>= 13.0)
roda (~> 3.46)
Expand All @@ -47,8 +47,8 @@ GEM
thor (~> 1.1)
tilt (~> 2.0)
zeitwerk (~> 2.5)
bridgetown-paginate (1.3.3)
bridgetown-core (= 1.3.3)
bridgetown-paginate (1.3.4)
bridgetown-core (= 1.3.4)
bridgetown-quick-search (2.0.0)
bridgetown (>= 1.2.0.beta2, < 2.0)
colorator (1.1.0)
Expand All @@ -66,17 +66,17 @@ GEM
ffi (1.16.3)
hash_with_dot_access (1.2.0)
activesupport (>= 5.0.0, < 8.0)
i18n (1.14.4)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (5.5.0)
liquid (5.4.0)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
minitest (5.22.3)
minitest (5.23.1)
mutex_m (0.2.0)
net-http (0.4.1)
uri
Expand All @@ -85,29 +85,31 @@ GEM
racc (~> 1.4)
nokogiri (1.13.9-x86_64-linux)
racc (~> 1.4)
public_suffix (5.0.4)
public_suffix (5.0.5)
puma (5.6.5)
nio4r (~> 2.0)
racc (1.6.0)
rack (3.0.10)
rake (13.1.0)
rack (3.0.11)
rake (13.2.1)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
rb-inotify (0.11.1)
ffi (~> 1.0)
rexml (3.2.6)
roda (3.78.0)
rexml (3.2.8)
strscan (>= 3.0.9)
roda (3.80.0)
rack
rouge (4.2.1)
serbea (1.0.1)
activesupport (>= 6.0)
erubi (>= 1.10)
tilt (~> 2.0)
strscan (3.1.0)
thor (1.3.1)
tilt (2.3.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uri (0.13.0)
zeitwerk (2.6.13)
zeitwerk (2.6.14)

PLATFORMS
arm64-darwin-21
Expand Down
124 changes: 92 additions & 32 deletions docs/config/esbuild.defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
// when an update is applied hence we strongly recommend adding overrides to
// `esbuild.config.js` instead of editing this file.
//
// Shipped with Bridgetown v1.1.0
// Shipped with Bridgetown v1.3.4

// DO NOT MANUALLY EDIT THIS CONFIGURATION:
const autogeneratedBridgetownConfig = {
"source": "src",
"destination": "output",
"componentsDir": "_components",
"islandsDir": "_islands"
}

const path = require("path")
const fsLib = require("fs")
Expand Down Expand Up @@ -41,15 +49,17 @@ if (moduleAvailable("sass")) {
// Glob plugin derived from:
// https://github.com/thomaschaaf/esbuild-plugin-import-glob
// https://github.com/xiaohui-zhangxh/jsbundling-rails/commit/b15025dcc20f664b2b0eb238915991afdbc7cb58
const importGlobPlugin = () => ({
const importGlobPlugin = (options, bridgetownConfig) => ({
name: "import-glob",
setup: (build) => {
build.onResolve({ filter: /\*/ }, async (args) => {
if (args.resolveDir === "") {
return; // Ignore unresolvable paths
}

const adjustedPath = args.path.replace(/^bridgetownComponents\//, "../../src/_components/")
const adjustedPath = args.path
.replace(/^\$components\/\*\*/, `../../${bridgetownConfig.source}/${bridgetownConfig.componentsDir}/**`)
.replace(/^bridgetownComponents\//, `../../${bridgetownConfig.source}/${bridgetownConfig.componentsDir}/`) // legacy

return {
path: adjustedPath,
Expand All @@ -64,15 +74,19 @@ const importGlobPlugin = () => ({
build.onLoad({ filter: /.*/, namespace: "import-glob" }, async (args) => {
const files = glob.sync(args.pluginData.path, {
cwd: args.pluginData.resolveDir,
}).sort()
})
.filter(module => options.excludeFilter ? !options.excludeFilter.test(module) : true)
.sort()
.map(module => module.replace(`../../${bridgetownConfig.source}/${bridgetownConfig.componentsDir}/`, "$components/"))
.map(module => module.match(/^[a-zA-Z0-9]/) ? `./${module}` : module)

const importerCode = `
${files
.map((module, index) => `import * as module${index} from '${module}'`)
.join(';')}
const modules = {${files
.map((module, index) => `
"${module.replace("../../src/_components/", "")}": module${index},`)
"${module.replace("$components/", "")}": module${index},`)
.join("")}
};
export default modules;
Expand All @@ -84,11 +98,13 @@ const importGlobPlugin = () => ({
})

// Plugin for PostCSS
const postCssPlugin = (options, configuration) => ({
const importPostCssPlugin = (options, configuration) => ({
name: "postcss",
async setup(build) {
// Process .css files with PostCSS
build.onLoad({ filter: (configuration.filter || /\.css$/) }, async (args) => {
if (args.path.endsWith(".lit.css")) return;

const additionalFilePaths = []
const css = await fs.readFile(args.path, "utf8")

Expand All @@ -112,14 +128,19 @@ const postCssPlugin = (options, configuration) => ({
})

// Process the file through PostCSS
const result = await postcss([importPlugin, ...options.plugins]).process(css, {
map: true,
...options.options,
from: args.path,
});

let outputCSS = ""
try {
const result = await postcss([importPlugin, ...options.plugins]).process(css, {
map: true,
...options.options,
from: args.path,
})
outputCSS = result.css
} catch(err) {
console.error(`\nerror: "${err.reason}" while processing CSS file:\n${err.file}:${err.line}:${err.column}\n`)
}
return {
contents: result.css,
contents: outputCSS,
loader: "css",
watchFiles: [args.path, ...additionalFilePaths],
}
Expand Down Expand Up @@ -187,7 +208,7 @@ const sassPlugin = (options) => ({
})

// Set up defaults and generate frontend bundling manifest file
const bridgetownPreset = (outputFolder) => ({
const bridgetownPreset = (bridgetownConfig) => ({
name: "bridgetownPreset",
async setup(build) {
// Ensure any imports anywhere starting with `/` are left verbatim
Expand All @@ -206,13 +227,14 @@ const bridgetownPreset = (outputFolder) => ({
console.warn("esbuild: build process error, cannot write manifest")
return
}
await fs.writeFile(path.join(outputFolder, 'meta.json'), JSON.stringify(result.metafile), { encoding: "utf8" })

const manifest = {}
const entrypoints = []

// We don't need `frontend/` cluttering up everything
const stripPrefix = (str) => str.replace(/^frontend\//, "")
// Clean up entrypoint naming
const stripPrefix = (str) => str
.replace(/^frontend\//, "")
.replace(RegExp(String.raw`^${bridgetownConfig.source}\/${bridgetownConfig.islandsDir}\/`), "islands/")

// For calculating the file size of bundle output
const fileSize = (path) => {
Expand All @@ -221,20 +243,22 @@ const bridgetownPreset = (outputFolder) => ({
return (size / Math.pow(1024, i)).toFixed(2) * 1 + ['B', 'KB', 'MB', 'GB', 'TB'][i]
}

const pathShortener = new RegExp(String.raw`^${bridgetownConfig.destination}\/_bridgetown\/static\/`, "g")

// Let's loop through all the various outputs
for (const key in result.metafile.outputs) {
const value = result.metafile.outputs[key]
const inputs = Object.keys(value.inputs)
const pathShortener = new RegExp(`^${outputFolder}\\/_bridgetown\\/static\\/`, "g")
const outputPath = key.replace(pathShortener, "")

if (value.entryPoint) {
// We have an entrypoint!
manifest[stripPrefix(value.entryPoint)] = outputPath
entrypoints.push([outputPath, fileSize(key)])
} else if (key.match(/index(\.js)?\.[^-.]*\.css/) && inputs.find(item => item.match(/\.(s?css|sass)$/))) {
} else if (key.match(/index(\.js)?\.[^-.]*\.css/) && inputs.find(item => item.match(/frontend.*\.(s?css|sass)$/))) {
// Special treatment for index.css
manifest[stripPrefix(inputs.find(item => item.match(/\.(s?css|sass)$/)))] = outputPath
const input = inputs.find(item => item.match(/frontend.*\.(s?css|sass)$/))
manifest[stripPrefix(input)] = outputPath
entrypoints.push([outputPath, fileSize(key)])
} else if (inputs.length > 0) {
// Naive implementation, we'll just grab the first input and hope it's accurate
Expand All @@ -256,45 +280,81 @@ const bridgetownPreset = (outputFolder) => ({
}
})

const bridgetownConfigured = (bridgetownConfig, outputFolder) => {
bridgetownConfig = {...autogeneratedBridgetownConfig, ...bridgetownConfig}
if (outputFolder) bridgetownConfig.destination = outputFolder

return bridgetownConfig
}

// Load the PostCSS config from postcss.config.js or whatever else is a supported location/format
const postcssrc = require("postcss-load-config")
const postCssConfig = postcssrc.sync()

module.exports = (outputFolder, esbuildOptions) => {
module.exports = async (esbuildOptions, ...args) => {
let outputFolder;
if (typeof esbuildOptions === "string") { // legacy syntax where first argument is output folder
outputFolder = esbuildOptions
esbuildOptions = args[0]
}
const bridgetownConfig = bridgetownConfigured(esbuildOptions.bridgetownConfig, outputFolder)

esbuildOptions.plugins = esbuildOptions.plugins || []
// Add the PostCSS & glob plugins to the top of the plugin stack
esbuildOptions.plugins.unshift(postCssPlugin(postCssConfig, esbuildOptions.postCssPluginConfig || {}))
const postCssConfig = await postcssrc()
esbuildOptions.plugins.unshift(importPostCssPlugin(postCssConfig, esbuildOptions.postCssPluginConfig || {}))
if (esbuildOptions.postCssPluginConfig) delete esbuildOptions.postCssPluginConfig
esbuildOptions.plugins.unshift(importGlobPlugin())
// Add the Glob plugin
esbuildOptions.plugins.unshift(importGlobPlugin(esbuildOptions.globOptions || {}, bridgetownConfig))
if (esbuildOptions.globOptions) delete esbuildOptions.globOptions
// Add the Sass plugin
esbuildOptions.plugins.push(sassPlugin(esbuildOptions.sassOptions || {}))
if (esbuildOptions.sassOptions) delete esbuildOptions.sassOptions
// Add the Bridgetown preset
esbuildOptions.plugins.push(bridgetownPreset(outputFolder))
esbuildOptions.plugins.push(bridgetownPreset(bridgetownConfig))
if (esbuildOptions.bridgetownConfig) delete esbuildOptions.bridgetownConfig

// esbuild, take it away!
require("esbuild").build({
const esbuild = require("esbuild")
const entryPoints = esbuildOptions.entryPoints || ["./frontend/javascript/index.js"]
if (esbuildOptions.entryPoints) delete esbuildOptions.entryPoints

const islands = glob.sync(`./${bridgetownConfig.source}/${bridgetownConfig.islandsDir}/*.{js,js.rb}`).map(item => `./${item}`)

esbuild.context({
bundle: true,
loader: {
".jpg": "file",
".jpeg": "file",
".png": "file",
".gif": "file",
".svg": "file",
".avif": "file",
".jxl": "file",
".webp": "file",
".woff": "file",
".woff2": "file",
".ttf": "file",
".eot": "file",
},
resolveExtensions: [".tsx", ".ts", ".jsx", ".js", ".css", ".scss", ".sass", ".json", ".js.rb"],
nodePaths: ["frontend/javascript", "frontend/styles"],
watch: process.argv.includes("--watch"),
minify: process.argv.includes("--minify"),
sourcemap: true,
target: "es2016",
entryPoints: ["frontend/javascript/index.js"],
target: "es2020",
entryPoints: [...entryPoints, ...islands],
entryNames: "[dir]/[name].[hash]",
outdir: path.join(process.cwd(), `${outputFolder}/_bridgetown/static`),
outdir: path.join(process.cwd(), `${bridgetownConfig.destination}/_bridgetown/static`),
publicPath: "/_bridgetown/static",
metafile: true,
...esbuildOptions,
}).then(context => {
if (process.argv.includes("--watch")) {
// Enable watch mode
context.watch()
} else {
// Build once and exit if not in watch mode
context.rebuild().then(result => {
context.dispose()
})
}
process.on('SIGINT', () => process.exit())
}).catch(() => process.exit(1))
}
Loading

0 comments on commit 464ab71

Please sign in to comment.