Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for image optimiziation with image-webpack-loader #675

Closed
wants to merge 11 commits into from
Closed

Added support for image optimiziation with image-webpack-loader #675

wants to merge 11 commits into from

Conversation

aschempp
Copy link

@aschempp aschempp commented Nov 23, 2019

as discussed with @weaverryan here's a first POC for adding image optimization. Looking for general feedback as this is my first time working with Encore, so I'm not sure if my approaches make sense.

The method and feature name are kinda confusing due to the dependencies. We're using image-webpack-loader, which internally uses imagemin to optimize images. Not sure if stuff should be named after the loader (as of now), or rather something like enableImageOptimization() or name the feature imagemin instead of image-webpack

To enable image optimization, install image-webpack-loader and call enableImagemin() in the Encore config. Further image configuration is available by passing options to the method exactly as in image-webpack-loader.

Encore.enableImagemin({
    mozjpeg: {
        progressive: true,
        quality: 65
    },
    // optipng.enabled: false will disable optipng
    optipng: {
        enabled: false,
    },
    pngquant: {
        quality: [0.65, 0.90],
        speed: 4
    },
    gifsicle: {
        interlaced: false,
    },
    // the webp option will enable WEBP
    webp: {
        quality: 75
    }
});

#SymfonyHackday

Copy link
Collaborator

@Lyrkan Lyrkan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @aschempp,

This looks like a nice thing to add, thanks for working on it :)

Also, don't worry about the failing AppVeyor tests, they are not related to your PR.

lib/config-generator.js Outdated Show resolved Hide resolved
index.js Outdated Show resolved Hide resolved
@aschempp aschempp marked this pull request as ready for review January 7, 2020 21:50
@aschempp
Copy link
Author

aschempp commented Jan 7, 2020

I finally got around to update this PR. It's pretty much a rewrite of the original implementation, thanks to the suggestions @Lyrkan. I have also update the initial PR description.

One caveat is that the signature of the images loaders has changes due to the nature of Webpack and chaining loaders. I'm not sure if this is really a problem, and we could try to keep BC of the signature for as long as Imagemin is not enabled if necessary?

@aschempp
Copy link
Author

failing tests don't see related to the PR 🙃

Copy link
Collaborator

@Lyrkan Lyrkan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @aschempp,

Sorry for not reviewing this sooner, I don't think the failing tests are related either.

I've some few comments but that's a great PR :)

One caveat is that the signature of the images loaders has changes due to the nature of Webpack and chaining loaders. I'm not sure if this is really a problem, and we could try to keep BC of the signature for as long as Imagemin is not enabled if necessary?

I would say that's part of Encore's internals and that we shouldn't care too much about BC there... if users are modifying loaders manually they should already know that things could break in a future release (especially when using configureLoaderRule() since it comes with a warning).

index.js Outdated Show resolved Hide resolved
lib/WebpackConfig.js Outdated Show resolved Hide resolved
@aschempp
Copy link
Author

any feedback on this PR? 🙃

@weaverryan
Copy link
Member

Sorry for the delay - I have this on my list to check soon - it's something that I think would be super cool :)

Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow! This is really excellent work - seriously :).

I have one comment on a "decision" you made about disabled. It is the only issue I see with this PR :).

loaderFeatures.ensurePackagesExistAndAreCorrectVersion('imagemin');

const imageminOptions = {
disable: !webpackConfig.isProduction(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm not sure about this. I could see a user enabling this feature while developing, then checking the images and saying "yep! they look ok still!. Then on deploy, their images are now a "lower quality". I think we should just allow the user to control whether or not this is disabled entirely.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 that should just be the default value, and one can just override that in the webpack/encore configuration?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I call Encore.enableImagemin(), I would expect that my images would be optimized. NOT optimizing them is unexpected. So I think Encore needs to not have this disable option at all. Nice and simple: if they call Encore.enableImagemin(), we enable it. Then, if they choose to, they could decide to disable in dev.

I do realize why you're doing this... it's just too unexpected. One other option would be to add an isEnabled flag as the first argument to Encore.enableImagemin(). Then we would document you using it like this:

Encore.enableImagemin(Encore.isProduction());

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. I decided to remove the disabled-in-dev default. You're probably right that it's unexpected, and it's easy to add. I thought about the additional option as well, but it just adds unnecessary complexity, I can achieve the same using an options object.

@weaverryan
Copy link
Member

Ping! I think we're close - but there is one last big issue :)

@aschempp
Copy link
Author

Finally, tests are fixed! Not sure how to fix the frozen yarn file (I'm not using yarn 🙈 )

@Kocal
Copy link
Contributor

Kocal commented Jun 11, 2020

I'm not using yarn

But you should! 😄

The error happens because --frozen-lockfile actually check if the package.json and yarn.lock files are synchronized. If it's not the case, it fails. It's the equivalent of npm ci.

Here, it's not the case. You've added image-webpack-loader dependency in the package.json file (https://github.com/symfony/webpack-encore/pull/675/files#diff-b9cfc7f2cdf78a7f4b91a753d10865a2) but the yarn.lock file has not been updated.

You need to run yarn and commit updates, but the next time please run yarn add --dev image-webpack-loader directly.

@aschempp
Copy link
Author

I'm not using yarn

But you should! 😄

haha, yeah, that's an opinion 😝

You need to run yarn and commit updates, but the next time please run yarn add --dev image-webpack-loader.

I do basically understand why this happens (I'm familiar with lock files). I'm wondering about the work flow, do I need to rebase on every commit to master to re-generate the lock file? That seems pretty cumbersome, is there a documentation what these tests are for?

@Kocal
Copy link
Contributor

Kocal commented Jun 11, 2020

Yes the ideal is to rebase on master, yarn.lock conflicts won't be an issue since Yarn resolves them easily.

It seems that you already rebased your PR, so just run yarn and it should be fine.

@stof
Copy link
Member

stof commented Jun 11, 2020

haha, yeah, that's an opinion stuck_out_tongue_closed_eyes

no. That's a fact. The webpack-encore project uses Yarn (Classic) for its dependency management. So when contributing to the project, you need to use it.

@aschempp
Copy link
Author

no. That's a fact. The webpack-encore project uses Yarn (Classic) for its dependency management. So when contributing to the project, you need to use it.

Obviously. I was referring to the 😄 emoji looking more like a general hint 😉

yarn.lock updated in 14595cf

@taylankasap
Copy link

What is this waiting for? Anything I (a random developer) can help with?

@Rodrigo001-dev

This comment has been minimized.

@infabo
Copy link

infabo commented Jul 4, 2020

@Rodrigo001-de awesome non-related spam comment!

@Rodrigo001-dev
Copy link

@infabo sorry

@aschempp
Copy link
Author

aschempp commented Oct 1, 2020

Updated to fix conflicts. Any news on merging this?

@georgringer
Copy link

hey @weaverryan it would be great if you could review this, let's merge that nice feature

@weaverryan weaverryan changed the base branch from master to main November 18, 2020 18:24
@joworeiter
Copy link

hi, anything new, when the feature gets merged?

@jb-thery
Copy link

jb-thery commented Mar 7, 2021

Hi, any update on this ?

@Jupi007
Copy link

Jupi007 commented Jun 26, 2021

Hi, it is planed to fix conflicts and merge this soon?

@aschempp
Copy link
Author

Unfortunately, this PR has become unusable due to a lot of changes/improvements in Encore. I guess I can re-implement the feature but I don't like to spend the time if it's not gonna be merged for another year… @weaverryan ?

@Jupi007
Copy link

Jupi007 commented Jun 28, 2021

Unfortunately, this PR has become unusable due to a lot of changes/improvements in Encore. I guess I can re-implement the feature but I don't like to spend the time if it's not gonna be merged for another year… @weaverryan ?

That's sad, this feature could be awesome for many people.

Currently I manually optimize my images and just copy them into /public/build. Sorry for the offtopic @aschempp, but do you know how to manually integrate image-webpack-loader into encore?

@aschempp
Copy link
Author

Sorry for the offtopic @aschempp, but do you know how to manually integrate image-webpack-loader into encore?

This is what I have in all my webpack.config.js (in addition to requiring image-webpack-loader in the package.json). Unfortunately it does not seem to work with copyFiles() but only assets that were required in scripts and stylesheets.

    // optimize and minify images
    .addLoader({
        test: /\.(gif|png|jpe?g|svg)$/i,
        use: [ 'image-webpack-loader' ]
    })

@Jupi007
Copy link

Jupi007 commented Jun 28, 2021

Thanks a lot @aschempp :)

@weaverryan
Copy link
Member

Hi!

yes, sorry to let this completely get stuck - that’s my fault. Per the last comment from @aschempp, since this is quite conflicted now and enabling it is so straightforward on your app, another option is just to document it.

I’m going to close for now. If someone wants to reopen with the updated version - or make a docs PR, that would be great. Again, my apologies @aschempp - you did really nice work here, sometimes it’s hard for me to keep up - sorry :/

@weaverryan weaverryan closed this Jun 29, 2021
@aschempp
Copy link
Author

no hard feelings @weaverryan, one more thing off my plate myself 😆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet