bridgetown
bridgetown copied to clipboard
docs: Add a mention for how to glob image files (frontend bundler)
Currently it seems that if you want to use webpack_path
with an image in frontend/images/
, it's not possible if the same image isn't used in a JS or CSS file (e.g. import "../images/file.png"
in frontend/javascript/index.js
).
This limitation isn't mentioned anywhere in the docs, as far as I can see.
Bridgetown Version: 0.21.5
To Reproduce
- Create a fresh Bridgetown site
- Add an image to
frontend/images/
- Try to use that file on a liquid page (e.g.
<link rel="icon" type="image/png" href="{% webpack_path images/favicon.png %}" />
)
Current behavior
An opaque error is printed to the logs:
[Bridgetown] Webpack: There was an error parsing your images/favicon.png file. Please check your images/favicon.png file for any errors.
[Bridgetown] Webpack: There was an error parsing your images/favicon.png file. Please check your images/favicon.png file for any errors.
[Bridgetown] Webpack: There was an error parsing your images/favicon.png file. Please check your images/favicon.png file for any errors.
[Bridgetown] Webpack: There was an error parsing your images/favicon.png file. Please check your images/favicon.png file for any errors.
[Bridgetown] Webpack: There was an error parsing your images/favicon.png file. Please check your images/favicon.png file for any errors.
[Bridgetown] Webpack: There was an error parsing your images/favicon.png file. Please check your images/favicon.png file for any errors.
And the emitted mark-up is:
<link rel="icon" type="image/png" href="MISSING_WEBPACK_MANIFEST_FILE" />
Expected behavior
I would expect, based on the documentation, to be able to use any image from frontend/
with the #webpack_path
helper to take advantage of file hashes etc…
Screenshots
—
Computing environment (please complete the following information):
- OS: macOS Big Sur
- Browser: any browser
- Browser Version —
- Ruby Version: 2.6.6
Additional context
—
I managed to fix this for my site by adding copy-webpack-plugin:
// webpack.config.js
const path = require("path");
const { merge } = require('webpack-merge')
const CopyPlugin = require("copy-webpack-plugin");
let config = require("./config/webpack.defaults.js")
const customConfig = {
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, "frontend/**/*.{png,svg,jpg,jpeg,gif}"),
to: "../images/[name].[contenthash][ext]"
},
],
}),
],
};
config = merge(config, customConfig)
module.exports = config
Thanks @matiaskorhonen, I think your CopyPlugin idea is pretty cool. I've also seen code that you can add to your entrypoint that loops over files and requires them, thus adding them to the manifest. Wonder which approach is better…
Updating this issue to cover adding a mention for how to glob image files in both esbuild and Webpack frontend bundler configs.
Speaking of the frontend developer, this can also be used with videos too? Not just images.
Thanks for the quick fix @matiaskorhonen, looks like that should work for me as well. I'd always had issues using the frontend bundler with images, only got it work correctly with CSS/SCSS.
Speaking of the frontend developer, this can also be used with videos too? Not just images.
Yeah, I don't see why not. You'd just need to add mp4
or webm
or whatever to the glob pattern…
I used the same setup for both images and data files on the @euruko 2022 conference site: https://github.com/euruko/2022.euruko.org/blob/2496dfb206b5c6835bc82e0d7981a786fb89169e/webpack.config.js#L27-L43
I seem to have issues with this as I work wit esBuild better than Webpack.
I gave esbuild-plugin-copy
a try, but keeps resulting in:
copy is not a function
Code:
const build = require("./config/esbuild.defaults.js")
const outputFolder = "output"
const copy = 'esbuild-plugin-copy';
const esbuildOptions = {
plugins: [
copy({
assets: {
from: ['./frontend/images/*'],
to: ['./output/images/*',],
},
}),
],
}
build(outputFolder, esbuildOptions)
@jaredcwhite id say a copy plugin that writes to a manifest is better. The problem with the manifests that are generated by doing import statements is that the strings get inlined into the final bundle, so you would need to make a separate assets entrypoint that you never use.
Also, ESBuilds asset detection is spotty at best since the asset -> hashed asset requires some workarounds.
https://github.com/evanw/esbuild/issues/2731