Closed GenieTim closed 4 years ago
For now, this is probably difficult to do because of the way Jigsaw parses collection items and builds output paths. But I'm revamping that for the next major release (2.0), and I definitely want to add support for this in that version.
Jigsaw doesn't do any image handling of its own, so it would all be handled in Webpack via Mix or whatever plugins you add. Assuming your images are in source/assets/images
, and your public path in Mix is set to source/assets/build
(which it is by default in Jigsaw, with mix.setPublicPath('source/assets/build/')
), then the following works for me:
let mix = require('laravel-mix');
let build = require('./tasks/build.js');
require('laravel-mix-imagemin');
mix.disableSuccessNotifications();
mix.setPublicPath('source/assets/build/');
mix.webpackConfig({
plugins: [
build.jigsaw,
build.browserSync(),
build.watch([
'config.php',
'source/**/*.md',
'source/**/*.php',
'source/**/*.scss',
]),
],
module: {
rules: [
{
test: /\.(jpe?g|png)$/i,
loader: 'responsive-loader',
options: {
sizes: [150, 300, 600, 900, 1200],
name: "[name]-[width].[ext]",
outputPath: 'images/sizes',
adapter: require('responsive-loader/sharp')
},
}
]
},
});
mix.js('source/_assets/js/main.js', 'js')
.sass('source/_assets/sass/main.scss', 'css/main.css')
.sourceMaps()
.imagemin({
from: 'source/assets/images/**/*.*',
to: 'images/[name].[ext]',
})
.version();
... with the following in main.js
(which is necessary, as far as I can tell, in order to get Webpack to do anything with the images):
require.context("./../../assets/images/", true, /^\.\/.*\.(jpe?g|png)/);
Note that your imagemin
didn't seem to be set up correctly; in my testing, the first parameter, not the second, should be the file patterns
. And responsive-loader
needed the outputPath: 'images'
option.
With this setup, Webpack will:
imagemin
to copy each image from /source/assets/images
, minimize them, and output them to /source/assets/build/images
responsive-loader
(and the require.context()
in main.js
) to copy images from /source/assets/images
, resize them, and output the resized versions to /source/assets/build/images
(you can put them in a subdirectory like sizes/
if you'd like, by modifying outputPath
in options
)After Webpack is done, Jigsaw will copy your whole assets
folder to build_*
, and your pages should link to images that are in assets/build/images
.
NOTE: After you get this set up, I would delete your /source/assets/build
directory before running npm run dev
the first time. I suspect that the duplicated files are old ones lying around from previous runs while you were testing different paths, which don't get deleted.
@damiani i wonder what this line holds: let build = require('./tasks/build.js'); what is the folder tasks (does it have any special meaning) and what is in that js?
Hello
is there a sollution for this? I tried options from comments but did not work for me.
Maybe there is some dev-branch with imagemin implemantation?
thanks
@huglester the code of my blog with working image processing can be found in https://github.com/GenieTim/genieblog.ch, if that helps
Thank you for this nice site generator! I do have a question/proposal/confusion about how to best handle images with Jigsaw. I will make a PR for the docs in case my confusion is understandable.
So, my understanding: By default, jigsaw copies images (and other stuff) in
assets/*
, sayassets/images
1:1 to the output directory (say,build_production
) upon build, no further processing. So far so good.Following problem 1: I am working on a more complex, bigger site/blog kind of thing. I will have many posts with many images. To have an easier management, I would like to group them together: say, a directory
source/_posts/2020/my_post
with anindex.md
and tons of images in the same directory. The images are used by thisindex.md
. This does not work: Jigsaw fails with error(s)CollectionDataLoader.php line 106: No matching collection item handler for file: whatever_image.jpg
. Would you consider an image item handler (copying, possibly compressing the images) a valid proposal for a PR, do you insist on the design decision to keep the images in a totally separate directory, or am I totally missing something/doing something wrong?Following problem 2: Accepting that images are put in
assets/images
, I want to automatically compress & resize them. It is no problem to change the links in markdown files using event listeners (see also #357 ) and having a blade img templated included for blade files (e.g. like this:, invoked like
.). What is not clear to me is where to hook for the actual image sizing. In the event listener does not work because of #172 . When hooking up webpack by adding
laravel-mix-imagemin
andresponsive-loader
in webpack.mix.js like so:I get tons of image files at tons of different locations:
source/assets/images/
,source/assets/build/
,source/assets/build/images/
,source/assets/build/source/assets/images/
. The same images in all of those directories, except for the directorysource/assets/build/
where I additionally can find the resized ones. Why do I produce such a mess? Is Jigsaw itself copying some images somewhere too during the build process? Can I hook up there? The problem with having the mess is that it takes longer, uses more storage and is confusing. In any case, a workaround would be to script the resizing & compression up separately so that I do not have to worry about any webpack interference, but it feels kindof wrong – any best practices I missed?