electron-userland / electron-webpack

Scripts and configurations to compile Electron applications using webpack
https://webpack.electron.build/
903 stars 170 forks source link

Upgrade to v2.8.2 breaks asset loading via ~@/assets/ #363

Open jmeinke opened 4 years ago

jmeinke commented 4 years ago

Upgrading electron-webpack from v2.7.4 to v2.8.2 leads to ~@/assets/ not being converted to the proper paths anymore. The problem might be related to the upgrade of html-loader from v1.0.0-alpha.0 to 1.1.0 in electron-webpack?

Input: <img src="~@/assets/Logo.svg" alt="Logo" style="width: 320px;" />

Expected HTML output: <img data-v-e9ddaef6="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz...." alt="Logo" style="width: 320px;">

Actual HTML output: <img data-v-e9ddaef6="" src="[object Module]" alt="Logo" style="width: 320px;">

jmeinke commented 4 years ago

As a side info: I'm also using the following:

"electron-webpack-eslint": "^6.0.0",
"electron-webpack-ts": "^4.0.1",
"electron-webpack-vue": "^2.4.0",
jmeinke commented 4 years ago

@develar @loopmode Would sponsoring help to get help on this one? :) EDIT: Just donated. Thanks for maintaining this project!

zlzdp commented 4 years ago

I have the same problem: I can see the error src: <img src="[object Module]"> img 404, can't loaded

jmeinke commented 4 years ago

The following also leads to the same error:

<img
  :src="require('../../assets/Icon.svg')"
/>

Using png instead of svg does not help either...

loopmode commented 4 years ago

Hmm just a hunch but...based on this issue.. Could you try pinning extract-loader to version 2? Put this in the package.json:

"resolutions": {
  "extract-loader": "2.0.0"
}

Then delete yarn.lock and run yarn install. Does it help?

I apologise for not actively investigating despite of the donation, but I haven't worked with electron in a long time and got my plate full with my regular job. I hope to be able to do some coding/debugging again soon. Until then, I'll try what I always did in this project: Google the right places with my mobile after working times and hopefully find and share some helpful clues..

loopmode commented 4 years ago

Based on electron-webpack-quick-start, with some image src/renderer/img.png:

// src/renderer/index.js
const app = document.getElementById('app');
const img = document.createElement('img');
// img.src = require('./img.png'); // does not work, [object Module] problem
img.src = require('./img.png').default; // works
app.appendChild(img);
loopmode commented 4 years ago

@jmeinke @zlzdp Please check whether using the .default property helps. I am not sure what caused this change in behaviour, but I'm pretty sure it's not a change in electron-webpack sources but rather in an updated dependency (at least so it seems, after looking over the recent commit history)

josephlarralde commented 3 years ago

I experience the same error with font-face urls in css files and style elements:

@font-face {
  font-family: Montserrat;
  src: url([object Module]) format("truetype");
}

I tried to put the css file and the fonts in static (using relative paths in the css), but importing the css from the renderer's index.js still triggers the buggy url rewriting.
Pinning extract-loader to v2.0.0 didn't help, and I don't see how I could use the .default property here.
BTW, I'm also using electron-webpack-vue, don't know if this could be related ... any hints appreciated.

update :

I tried to downgrade electron-webpack to v2.8.0 and the bundling failed with the following error :

ValidationError: Invalid options object. HTML Loader has been initialized usin  g an options object that does not match the API schema.
     - options has an unknown property 'url'. These properties are valid:
       object { preprocessor?, attributes?, minimize?, esModule? }

Don't know if this helps much ... it happens when using <style scoped> sections as well as when importing css files.

update 2 :

I solved my problem thanks to reading issue #397 : I added the getStatic function in renderer/utils and added the following code in renderer's index.js (my fonts.css file is located at the root of static and the font-face urls are relative to my fonts directory, also located in static) :

import getStatic from './utils/getStatic';

let cssPath = getStatic("fonts.css");

let linkElt = document.createElement("link");
linkElt.setAttribute("rel", "stylesheet");
linkElt.setAttribute("type", "text/css");
linkElt.setAttribute("href", cssPath);
document.head.appendChild(linkElt);

That's not too ugly for a workaround, but it would be nice if the bug was fixed someday (still no precise idea of what is causing this, I feel it might be related to this commit : 0053adb)

Maus3rSR commented 3 years ago

Same here. Upgrading to

{
        "electron-webpack": "^2.8.2",
        "electron-webpack-vue": "^2.4.0"
}

Broke my images src defined like this:

<img class="card-img" src="~@images/software/competition-bg.png">

@images is a simple alias defined in my webpack.renderer.additions.js

const path = require('path')

module.exports = {
    resolve: {
        alias: {
            '@src': path.join(__dirname, '../src'),
            '@root': path.join(__dirname, '../src/renderer'),
            '@database': path.join(__dirname, '../src/renderer/database'),
            '@config': path.join(__dirname, '../src/renderer/config'),
            '@lang': path.join(__dirname, '../src/renderer/lang'),
            '@screens': path.join(__dirname, '../src/renderer/screens'),
            '@partials': path.join(__dirname, '../src/renderer/screens/partials'),
            '@themes': path.join(__dirname, '../src/renderer/themes'),
            '@assets': path.join(__dirname, '../src/renderer/assets'),
            '@images': path.join(__dirname, '../src/renderer/assets/img'),
            '@css': path.join(__dirname, '../src/renderer/assets/css'),
            '@scss': path.join(__dirname, '../src/renderer/assets/scss'),
        }
    }
}

Any ideas about how to fix this issue? @jmeinke did you solved your problem?

Best regards

loopmode commented 3 years ago

@Maus3rSR not sure whether it's an option for your project, but you could switch from strings to actual require statements: src={require('@your/images.png').default}

Maus3rSR commented 3 years ago

@loopmode thank you for your answer.

I could resolve my issue by setting esModule: false to the url-loader. I copied the test and use from node_modules\electron-webpack\out\targets\RendererTarget.js

            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                use: {
                    loader: "url-loader",
                    options: {
                        esModule: false
                    }
                }
            }

Thanks to https://github.com/vuejs/vue-loader/issues/1612#issuecomment-559366730

loopmode commented 3 years ago

Good to know!