After upgrading to Laravel Mix 6 my build runs successfully but images referenced from the assets folder no longer are loading.
Running an existing Laravel v8.21.0 project with Laravel/UI Vue auth scaffolding, after upgrading Laravel Mix to version 6 images referenced from the assets folder in Vue don't err out on build but display as broken images in the browser.
Referencing images as such:
<img src="../assets/logo.png" alt="Logo">
When I inspect the image I see this:
<img src="[object Module]" alt="Logo">
Any help would be greatly appreciated. Thanks!
Hi,
I faced a similar issue yesterday.
The assets were copied successfully but the src path were not correctly rendered (object instead of a string)
It turned out this was caused by the embedded file-loader, which by default output files with ES6 syntax.
So I had to override the original configuration
mix.override(webpackConfig => {
// Firstly try to find the rule(s) where the file-loader is implyed
console.log(webpackConfig.modules.rules)
// Then modify the loader configuration
webpackConfig.module.rules[2].use[0].options.esModule = false;
});
Hope it can help.
@Aiwings Thanks for the response.
I was also able to get the image loaded by doing this:
<img :src="require('./assets/logo.png').default" alt="Logo">
Both of these solutions feel kinda ugly to me tbh.
Apparently its a bug with vue-loader which Mix uses. Here is my workaround solution. This only sets esModule to false on the images file-loader.
mix.override(webpackConfig => {
// BUG: vue-loader doesn't handle file-loader's default esModule:true setting properly causing
// <img src="[object module]" /> to be output from vue templates.
// WORKAROUND: Override mixs and turn off esModule support on images.
// FIX: When vue-loader fixes their bug AND laravel-mix updates to the fixed version
// this can be removed
webpackConfig.module.rules.forEach(rule => {
if (rule.test.toString() === '/(\\.(png|jpe?g|gif|webp)$|^((?!font).)*\\.svg$)/') {
if (Array.isArray(rule.use)) {
rule.use.forEach(ruleUse => {
if (ruleUse.loader === 'file-loader') {
ruleUse.options.esModule = false;
}
});
}
}
});
});
@tinyfly you have a link to an open issue for that?
@ethanclevenger91 Here you go: https://github.com/vuejs/vue-loader/issues/1612
Apparently its a bug with vue-loader which Mix uses. Here is my workaround solution. This only sets esModule to false on the images file-loader.
mix.override(webpackConfig => { // BUG: vue-loader doesn't handle file-loader's default esModule:true setting properly causing // <img src="[object module]" /> to be output from vue templates. // WORKAROUND: Override mixs and turn off esModule support on images. // FIX: When vue-loader fixes their bug AND laravel-mix updates to the fixed version // this can be removed webpackConfig.module.rules.forEach(rule => { if (rule.test.toString() === '/(\\.(png|jpe?g|gif|webp)$|^((?!font).)*\\.svg$)/') { if (Array.isArray(rule.use)) { rule.use.forEach(ruleUse => { if (ruleUse.loader === 'file-loader') { ruleUse.options.esModule = false; } }); } } }); });
I had this issue when i've updated laravel mix from 5 to 6
Got some [object Module] urls for thirds libraries like trumbowyg or remixicons and this solved the issue
Thanks, i hope there will be a fix for this or an option to set the esModule option for file-loader !
@tinyfly I finally got around to implementing your solution and it works great! Thank you for that and for linking to the issue in vue-loader.
Most helpful comment
Apparently its a bug with vue-loader which Mix uses. Here is my workaround solution. This only sets esModule to false on the images file-loader.