Brigad / ideal-image-loader

🖼️ A loader for webpack which handles 2x/3x/webp and works well with gatsby-image and react-ideal-image
MIT License
26 stars 1 forks source link

Provide VueJS example #11

Open GauthierPLM opened 4 years ago

GauthierPLM commented 4 years ago

It would be awesome if a VueJS configuration example was made available.

I am struggling to make it work in a VueJS project: I obtain a build error (TypeError) when building the project:

yarn run v1.21.1
$ vue-cli-service build

 ERROR  Failed to compile with 1 errors

 error  in ./src/assets/logo.png

Module build failed (from ./node_modules/@brigad/ideal-image-loader/src/index.js):
TypeError: Cannot read property '1' of null
    at getSource (/Users/gauthier/WebstormProjects/untitled/node_modules/@brigad/ideal-image-loader/src/index.js:56:52)
    at /Users/gauthier/WebstormProjects/untitled/node_modules/@brigad/ideal-image-loader/src/index.js:138:25
    at Array.map (<anonymous>)
    at /Users/gauthier/WebstormProjects/untitled/node_modules/@brigad/ideal-image-loader/src/index.js:126:32

 @ ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"d4cb25de-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=template&id=7a951895& 1:167-195
 @ ./src/App.vue?vue&type=template&id=7a951895&
 @ ./src/App.vue
 @ ./src/main.js
 @ multi ./src/main.js

info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Here is the fresh VueJS project I used to test with only ideal-image-loader added: https://github.com/GauthierPLM/test-brigad-ideal-image-loader I am not really proficient with Webpack so I probably missed something...?

PS: your loader is the most complete I found matching a workflow integrating Zeplin 👍 Really hope to make it work!

adrienharnay commented 4 years ago

Hey, I have never worked with VueJS but from what I can tell this should work out of the box since it's only tied to Webpack 🙂 Could you please show me your Webpack config? And package.json

GauthierPLM commented 4 years ago

That's what I guessed too, but seems like in the case of VueJS, a particular configuration might be necessary.

Here is the package.json and the webpack config I use for the project. The webpack configuration is a bit different with VueJS as explained in their doc. I could get the final config generated by Vue CLI with vue inspect and added it to the test repository I use.

adrienharnay commented 4 years ago

Ah I see! Could you please install "file-loader": "5.0.2" and try again? It is a peer dependency, and the minimum version required is 5. I'm afraid another dependency is providing it at a lower version.

GauthierPLM commented 4 years ago

Okay, I succeeded to make it work by adding "file-loader": "^5.0.2" as dependency.

Also, I used the following Webpack configuration:

module.exports = {
    chainWebpack: config => {
        config.module
            .rule("images")
            .use("@brigad/ideal-image-loader")
            .loader("@brigad/ideal-image-loader")
            .options({
                name: 'img/[name].[hash:8].[ext]'
            })
            .end();
    }
};

I will make a clean repository tomorrow with an example config, some doc, and open a PR to add it to the readme for future users. Thank you for your help. I keep this issue open until I finished the PR/it's merged.

adrienharnay commented 4 years ago

So glad to hear! Thanks for this, let me know when your PR is ready 😄

GauthierPLM commented 4 years ago

I continued to play with it but i could not make it work properly. First issue I encountered is that the loader does not seems to be correctly called on development mode. The second issue I had is to properly request the image on production.

Unfortunately, my experience with webpack is quite limited and despite learning a lot from this experiment, I couldn't make it work with VueJS, which seems to be more tricky than react due to its default webpack configuration.

adrienharnay commented 4 years ago

Ah, sorry to hear... Configuring loaders with tools that use Webpack and allow for a certain level of configuration is indeed sometimes tricky (if there is a default file loader you need to remove it for example, ...).

For example, to integrate this loader with Gatsby I've had to do this:

webpackConfig.module.rules = webpackConfig.module.rules.filter(
  (rule) => !rule.test || !rule.test.toString().includes('jpg'),
);

If I can help you further, please let me know!

GauthierPLM commented 4 years ago

I succeed to make it work as expected with VueJS and made a PR (#13) to link to the example repository. Let me know if you prefer that I contribute this example directly to your project or not.

I thought adding an external link might avoid you the need of testing the example/maintaining it in the future.

Also, during my work, I was wondering if there was anyway to setup the loader so it does in-place replacement of the link?

For example, the following code:

<img src="logo.png" />

would have its srcset attribute automatically added to obtain:

<img src="logo.[hash].png" srcset="logo.[hash].webp 1x, logo.[hash].png 1x" />

The name is already automatically changed to include the hash with the default setup of VueJS (which uses file-loader), so I guess it would be possible to do it too?

adrienharnay commented 4 years ago

Hey, I'm happy you managed to make it work! Have you looked at the example React component? I think it might be what you're looking for :)