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

/public directory configuration, and module.scss #99

Closed
4 tasks done
jakerdy opened this issue Feb 7, 2023 · 17 comments
Closed
4 tasks done

/public directory configuration, and module.scss #99

jakerdy opened this issue Feb 7, 2023 · 17 comments
Labels
question Further information is requested

Comments

@jakerdy
Copy link

jakerdy commented Feb 7, 2023

Describe the bug

Hi!
I ve trying to port my web app to Electron. Your project looks great and suit my needs pretty well, but i couldn't figure out couple things.

First: Way to handle /public directory which should ships 'as is' without modifications.
With "vanilla" vite, '/public' dir in root of my project has been working with "./public" in vite.conf.js. Also it works for both dev and release modes.
Where should i put it, and how should it be configured?
I have tried root of project next to tsconfig.js, also did put in into /src/renderer/public, but it won't work out of the box.
Also it won't work if i add "./public" into renderer vite config, with both directory placements.
It works in dev (not build) only if i set path in tsconfig like this: path.join(__dirname, "public").
Is this intended way of doing this? Searching docs gives me 0 results.

Second: I am using Sass, and import all my styles as modules from files called like "StyleName.module.scss".
In "vanilla" vite it just works, but with vite-electron it says: Cannot find module './StyleName.module.scss' or its corresponding type declarations..
For now i created file src/renderer/typings.d.ts with declare module "*.module.scss"; but it feels wrong.
What is proper way to handle it?

Thoug i sami-fixed those issues, and make my 'dev' setup working. But when i trying to build shiping version of my app. I got just black screen with errors that says Failed to load resource: net::ERR_FILE_NOT_FOUND. Which clearly means that something wrong with /public directory.

All of this pretty frustrating because i don't know how to resolve it my self, even dont know where to start from.
electron-vite great, hope, you could help me with this.
And, if you could, please explain why all that stuff works in "vanilla" vite and doesn't work here, i think it will greatly improve my understanding of how electron-vite works.

Electron-Vite Version

^1.0.17

Electron Version

^21.3.3

Vite Version

^4.0.4

Validations

@jakerdy jakerdy added the bug Something isn't working label Feb 7, 2023
@jakerdy
Copy link
Author

jakerdy commented Feb 7, 2023

Well, scss module imports will work if next compiler option added into tsconfig.web.json

"types": ["vite/client"],

Looks like there is declarations of *.module.scss inside vite/client types, which make things work as expeted.
Any way, it will be great if such things will be described in docs, or will be default enabled in project template (solid-ts in my case).

@alex8088
Copy link
Owner

alex8088 commented Feb 7, 2023

  1. about public dir, see https://evite.netlify.app/guide/assets.html#public-directory
  2. the scaffolding has added type declarations by default(located src/renderer/src/env.d.ts) What is your IDE? if webstorm, you can remove "files": [], in tsconfig

@alex8088
Copy link
Owner

alex8088 commented Feb 7, 2023

in renderer, use public assets , must be /XXXX ( not /public/XXX), and not support import. related: https://vitejs.dev/guide/assets.html#the-public-directory

@alex8088 alex8088 added question Further information is requested and removed bug Something isn't working labels Feb 7, 2023
@jakerdy
Copy link
Author

jakerdy commented Feb 7, 2023

SCSS

the scaffolding has added type declarations by default(located src/renderer/src/env.d.ts)

Miss that, because after project was created and initialized, i just put my app into renderer dir, completeley replacing it's content.

What is your IDE? if webstorm, you can remove "files": [], in tsconfig

Ok, got you, my ide is vscode.

Anyway issue has been resolved, and now i know two ways to deal with that.

/public

in renderer, use public assets , must be /XXXX ( not /public/XXX), and not support import.

It doesn't work like that. Even your link says:

By default, the working directory of renderers are located in src/renderer, so the public directory needs to be created in this directory. The default public directory is named public, which can also be specified by publicDir

It works only if i put my /public at path /src/renderer/public, i didn't set publicDir in config.js.
Also, It works in dev mode, but packaged electron app doesn't.
It builds fine, without errors, but when i start it, i got blank window, and errors in console which says: Failed to load resource: net::ERR_FILE_NOT_FOUND, path to files looks like file:///D:/icons/svg/IconName.svg if i copy url

The problem is that built app couldn't find files from /public

@jakerdy
Copy link
Author

jakerdy commented Feb 7, 2023

Or, you said about usage of public assets?
If so, yes, i referece those assets using absolute path without dots and with leading slash.
Like that: const pic_url = "/icons/svg/IconLeft.svg"
And it works fine in dev mode.

@alex8088
Copy link
Owner

alex8088 commented Feb 7, 2023

try set browser window webSecurity to false

@jakerdy
Copy link
Author

jakerdy commented Feb 7, 2023

Nope, didnt't helped

In dev tools 'public assets' looks like this:
image

I understand how this hould work in conventional web server. Path to 'public assets' concatenated with domain, and you got valid URLs, but how this should work in electron? Where we have no webserver, at least one we could touch by hand.

Also, where those assets should be putted when app build? Into .asar archive or somewhere near .exe file, or into /resources?
Do you have some working example/test which uses '/public' dir?

@alex8088
Copy link
Owner

alex8088 commented Feb 7, 2023

It seems you don't really understand public dir. You need to distinguish whether these resources are used by the main process or the rendering process. If used for renderer, you need put them into renderer/src/public or customize your public dir. Vite will automatically parse and copy these assets to the outDir (out/renderer, why /xxx but not /public/xxx). Or directly import but not use as public assets, Vite will also handle it.

@alex8088
Copy link
Owner

alex8088 commented Feb 7, 2023

another way: #36

@alex8088
Copy link
Owner

alex8088 commented Feb 7, 2023

@jakerdy
Copy link
Author

jakerdy commented Feb 7, 2023

It seems you don't really understand public dir.

May be. Lets synchronize on this. My understanding of public assets is:

  • They are shiped 'as-is'
  • Vite doesn't modify their names
  • You could modify this assets in after build if you don't change their names
  • URLs to public assets are looks like "https://example.com/path/to/public/asset.png"
    What's wrong with this?

You need to distinguish whether these resources are used by the main process or the rendering process.

Ok, but how is that differs? Aint those assets should be shiped as is? As it works in vite?

If used for renderer, you need put them into renderer/src/public or customize your public dir.

As i did.

Or directly import but not use as public assets, Vite will also handle it.

I wouldn't do this because all assets in my project lives in public directory, and i don't think it will be ever changed.

Vite will automatically parse and copy these assets to the outDir (out/renderer, why /xxx but not /public/xxx).

Yes it has been putted to /out/renderer. But in build app it doesn't work.
I understand that reason of that is how electron works. But i don't exactly understand why. And asking you how i am suppose to configure my project to make it works, like it worked in browser when i used vanilla vite.

As i already said, in dev environment evrything fine.
When i build my app, none of public assets are loaded. Is there anything else that i should do to make it working? Or is there any doc snippet about some parameters, or anything related to than specific moment?

this repo use public dir
https://github.com/DerZwergGimli/resource.capacity.estimator.evite

Guy there using fetch api to get his public asset. It's a little bit different case.


Ok, check this one, i've create clean project from solid-ts template with command:

pnpm create @quick-start/electron my-app --template solid-ts

Then add /public dir to /src/renderer, and put single jpg into this dir.
image

Make my app component very trivial:

export function App()
{
    return <img src="/gem.jpg" />
}

it just directly uses jpg from public assets.

Then, run my app wtih pnpm dev and got this:
image

Ok, work so far.

Then, i build app with pnpm build:win

/out directory looks like this:
image
as you may see .jpg there.

But, if i run my app, it will look like this:
image

Picture is lost. And this is a problem. Because public assets won't show up.


Here is test repo with this app.

https://github.com/jakerdy/vite-electron-MissingPublicAssets


Ok, i might not understand something, but not so much.
Tell me please what i am doing wrong, and why 'dev' working but 'build' not.

@alex8088
Copy link
Owner

alex8088 commented Feb 7, 2023

@jakerdy

This should be a problem with the vite-plugin-solid. You catch it.

In vue or react, It is no problem to use like this:

<img src="/logo.svg" alt="logo" />

But in solid, you can do it like this:

// public assets
<img src={new URL('/logo.svg', import.meta.url).href} alt="logo" />

@jakerdy
Copy link
Author

jakerdy commented Feb 7, 2023

Hm. Ok, going to ask @ryansolid about this...

@jakerdy
Copy link
Author

jakerdy commented Feb 7, 2023

Thanks for helping with that!

@alex8088
Copy link
Owner

alex8088 commented Feb 7, 2023

In vue and react, it will be bundle to new URL('/logo.svg', import.meta.url).href, but not in solid. So based on file://, there will be problems.

@jakerdy
Copy link
Author

jakerdy commented Feb 7, 2023

Yeah, you right.
Just build with new URL and it worked as expected.
image

@Maqsyo
Copy link

Maqsyo commented Dec 19, 2023

I'm a bit late for this party, but the correct answer isn`t here to find.

What you really need to do is this:
go into your electron.vite.config.ts and at following attribute to your renderer-config:

renderer: {
  base: './',
  ...
}

https://vitejs.dev/config/shared-options.html#base

Vite will rewrite all public-paths while building to this base and it will work like a charm.


The reason why it works in dev-mode and not in the production-build is following:
In the dev-mode vite opens an own server which handles all your resources. So /logo.svg will lead to http://localhost:5173/logo.svg - so vite receives the wish to get this file and serves it for you.
In the production-build the file-path is still /logo.svg and windows can't find this file in C:\ (or wherever).

With the base-path ./ vite rewrite all public paths. Your file-path for your logo will become ./logo.svg and windows can find this in the executable folder of your application.

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

No branches or pull requests

3 participants