wailsapp / wails

Create beautiful applications using Go
https://wails.io
MIT License
25.39k stars 1.23k forks source link

Cannot start wails + create-react-app #923

Closed AlienRecall closed 2 years ago

AlienRecall commented 3 years ago

Description I really don't know if this is a bug or simply wails does not supports react

To Reproduce Steps to reproduce the behaviour:

  1. Init a wails project
  2. Create a react app in the frontend folder
  3. Add frontend build as assetdir in wails.json
  4. Add npm install as frontend:install
  5. Add npm run build as frontend:dev/frontend:build
  6. Executewails dev and wait or wails build an open the application

Expected behaviour A correct opening of the application

Screenshots If applicable, add screenshots to help explain your problem.

System Details (running wails doctor) System

OS: MacOS Version: 11.6 ID: 199506 Go Version: go1.17.2 Platform: darwin Architecture: amd64

Additional context This is what I get when running wails dev (I see the same error when starting the application after wails build

Executing: go mod tidy
Executing: wails generate module
Running frontend dev command: 'npm run build'
Building application for development...
Installing frontend dependencies: Done.
Compiling frontend: 
> frontend@0.1.0 build
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  41.33 KB  build/static/js/2.c2ca528f.chunk.js
  1.62 KB   build/static/js/3.1ef4b814.chunk.js
  1.16 KB   build/static/js/runtime-main.ff5ca5cf.js
  588 B     build/static/js/main.044cc9db.chunk.js
  531 B     build/static/css/main.8c8b27cf.chunk.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build

Find out more about deployment here:

  https://cra.link/deployment

Done.
Compiling application: Dev command exited!
Done.

DEB | [DesktopAssetServer] Loading assets from: %PROJECTPATH%/frontend/build
panic: runtime error: index out of range [0] with length 0

goroutine 1 [running, locked to thread]:
github.com/wailsapp/wails/v2/internal/frontend/assetserver.PathToIndexHTML({0xc000307ce0})
        %USERPATH%/go/pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.19/internal/frontend/assetserver/assetserver_desktop.go:84 +0x156
github.com/wailsapp/wails/v2/internal/frontend/assetserver.processAssets({0xc000307ce0})
        %USERPATH%/go/pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.19/internal/frontend/assetserver/assetserver_desktop.go:95 +0x39
github.com/wailsapp/wails/v2/internal/frontend/assetserver.(*DesktopAssetServer).init(...)
        %USERPATH%/go/pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.19/internal/frontend/assetserver/assetserver_desktop.go:105
github.com/wailsapp/wails/v2/internal/frontend/assetserver.NewDesktopAssetServer({0x4567200, 0xc0001eb9b0}, {0x4558c80}, {0xc000310000, 0x6f})
        %USERPATH%/go/pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.19/internal/frontend/assetserver/assetserver_desktop.go:47 +0x2d2
github.com/wailsapp/wails/v2/internal/frontend/desktop/darwin.NewFrontend({0x4567200, 0xc0001eb9b0}, 0xc0001ce0c0, 0xc0000bcb10, 0xc0000ce500, {0x455e160, 0xc0001eb9e0})
        %USERPATH%/go/pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.19/internal/frontend/desktop/darwin/frontend.go:84 +0x1cb
github.com/wailsapp/wails/v2/internal/frontend/desktop.NewFrontend(...)
        %USERPATH%/go/pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.19/internal/frontend/desktop/desktop_darwin.go:18
github.com/wailsapp/wails/v2/internal/appng.CreateApp(0xc0001ce0c0)
        %USERPATH%/go/pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.19/internal/appng/app_dev.go:118 +0x6cb
github.com/wailsapp/wails/v2.Run(0xc0000001a0)
        %USERPATH%/go/pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.19/wails.go:19 +0x19
main.main()
        %USERPATH%/Documents/golang/provoon/main.go:26 +0x385
Watching (sub)/directory: %USERPATH%/Documents/golang/provoon
Using Dev Server URL: http://localhost:34115
Using reload debounce setting of 100 milliseconds
^C
Caught quit
Development mode exited

If Wails is useful to you or your company, please consider sponsoring the project:
https://github.com/sponsors/leaanthony

Thanks in advance for your help, I really appreciate your work and love this project. I'll surely make a react template after this issue has been solved

leaanthony commented 3 years ago

I literally fixed a bug in the last 10 mins that I think will address this. Please try latest beta using wails update -pre. A react template would be fantastic!

AlienRecall commented 3 years ago

I'm on v2.0.0-beta.19

leaanthony commented 3 years ago

Ah I see you're using the latest. Please try removing the "frontend:dev" part of your wails.json and let me know.

leaanthony commented 3 years ago

%PROJECTPATH%/frontend/build might be the issue

AlienRecall commented 3 years ago

I replaced the full path with %PROJECTPATH% manually to clear the full issue, by the way I've tried removing frontend:dev from wails.json and I get the same issue with both dev command and built application

leaanthony commented 3 years ago

I probably should say the idea of the dev server is experimental. People are keen for an external server but there's things to work out yet.

If you generate a project and just use wails dev with the assetdir set, does that work? Dies a standard build work?

leaanthony commented 3 years ago

Also, sorry, I have no idea about react. If you can get your project to build using npm run build and update assetdir to point to your compiled assets, it absolutely should work šŸ‘

AlienRecall commented 3 years ago

I remember that on v1 it was working with this settings in project.json

image

Also on the old v2 updates the settings was

image

So I've tried to do the same on this version, will try my best to get it working, but I'm not an expert into frontend development

AlienRecall commented 3 years ago

Hi, I've tried to go deep into this error and done some debug on the wails source by adding fmt.Println(path) on line 72 in internal/frontend/assetserver/assetserver_desktop.go and seems like wails is searching the index.html file in the frontend/src folder instead the frontend/build as I said in the assetdir param in wails.json. Can you help me on this?

leaanthony commented 3 years ago

Yes, absolutely. The default svelte template has this distinction so does that work as expected for you?

AlienRecall commented 3 years ago

It should enter in the build folder instead src, how can i make it enter in the build folder?

leaanthony commented 3 years ago

Is your project online?

AlienRecall commented 3 years ago

I've also noticed that every time I run wails build it creates the wailsjs folder outside the /frontend folder, this not happens with wails dev (maybe could be why is crashes)

AlienRecall commented 3 years ago

Is your project online?

No, it's not online, but I can create a repo if you want

AlienRecall commented 3 years ago

I've created the repo and invited you @leaanthony

leaanthony commented 3 years ago

Hard to help without it

leaanthony commented 3 years ago

I get 404

AlienRecall commented 3 years ago

try now

leaanthony commented 3 years ago

You didn't check in your build directory. I'll have to check it tomorrow.

AlienRecall commented 3 years ago

I'm sorry I don't understand what you mean, what I was supposed to do with the build directory?

KoduIsGreat commented 3 years ago

fwiw i'm having the same issue

KoduIsGreat commented 3 years ago

@AlienRecall make sure you not only update the settings in the wails.json but also the embed go path in your main.go file. eg:

//go:embed frontend/build
var assets embed.FS

If you point it to the right spot, you should get a window.

however @leaanthony , even if i do this, and I get a window it dies immediately, with something like TypeError: undfined is not an object (evaluating 'windows.wails._.Init') which seems to be stemming from the wails/runtime js library

My react App code looks like the following


import React from 'react';
import ReactDOM from 'react-dom';
import 'core-js/stable';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import "bootstrap/dist/css/bootstrap.min.css"
// import './bootstrap.min.css'
import * as Wails from '@wailsapp/runtime';

Wails.Init(() => {
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("app")
  );
});

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
AlienRecall commented 3 years ago

@AlienRecall make sure you not only update the settings in the wails.json but also the embed go path in your main.go file. eg:

//go:embed frontend/build
var assets embed.FS

If you point it to the right spot, you should get a window.

however @leaanthony , even if i do this, and I get a window it dies immediately, with something like TypeError: undfined is not an object (evaluating 'windows.wails._.Init') which seems to be stemming from the wails/runtime js library

My react App code looks like the following

import React from 'react';
import ReactDOM from 'react-dom';
import 'core-js/stable';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import "bootstrap/dist/css/bootstrap.min.css"
// import './bootstrap.min.css'
import * as Wails from '@wailsapp/runtime';

Wails.Init(() => {
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("app")
  );
});

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

This solved my issue, really thanks The app is executing normally

AlienRecall commented 3 years ago

@leaanthony changing //go:embed frontend/src to //go:embed frontend/build solved my issue, frontend and backend seems communicating perfectly, will push and example to our repo so you can retrieve a template from it

AlienRecall commented 3 years ago

@AlienRecall make sure you not only update the settings in the wails.json but also the embed go path in your main.go file. eg:

//go:embed frontend/build
var assets embed.FS

If you point it to the right spot, you should get a window.

however @leaanthony , even if i do this, and I get a window it dies immediately, with something like TypeError: undfined is not an object (evaluating 'windows.wails._.Init') which seems to be stemming from the wails/runtime js library

My react App code looks like the following

import React from 'react';
import ReactDOM from 'react-dom';
import 'core-js/stable';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import "bootstrap/dist/css/bootstrap.min.css"
// import './bootstrap.min.css'
import * as Wails from '@wailsapp/runtime';

Wails.Init(() => {
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("app")
  );
});

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

Just remove the Wails.Init function, you do not need it on Wails 2.0

This is my index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
KoduIsGreat commented 3 years ago

I dont understand how that would work, how does your react app get access to the wails runtime? I read the section on injecting scripts, I guess wails dev does that for us?

leaanthony commented 3 years ago

It sounds like you're trying to compile a v1 project in v2. There's no need to wrap your code in Init(). The migration guide is here: https://wails.io/docs/guides/migrating - I can see that there's no mention of removing that wrapping code so I'll look to fix that. If you find any other gaps in the migration guide, please add it to this ticket.

leaanthony commented 3 years ago

I dont understand how that would work, how does your react app get access to the wails runtime? I read the section on injecting scripts, I guess wails dev does that for us?

@KoduIsGreat The runtime is available to your code on window.runtime. It's there before your code runs. If you're a typescript person, have a look at the code that's generated in wailsjs/runtime šŸ˜‰

leaanthony commented 3 years ago

@leaanthony changing //go:embed frontend/src to //go:embed frontend/build solved my issue, frontend and backend seems communicating perfectly, will push and example to our repo so you can retrieve a template from it

@AlienRecall - That's amazing! We need a react template! Couple of things:

AlienRecall commented 3 years ago

@leaanthony changing //go:embed frontend/src to //go:embed frontend/build solved my issue, frontend and backend seems communicating perfectly, will push and example to our repo so you can retrieve a template from it

@AlienRecall - That's amazing! We need a react template! Couple of things:

  • Would you be interesting in writing a "How to write a template" guide? It can just be bullet points, but would be an amazing contribution to the community
  • Are there any gaps in existing documentation that hindered the process of creating the template?
  • Finally: It would be amazing to get the template working with the experimental "devserverurl" config. If you are keen to get this working, we can continue on the discussions board and I'll do everything I can to get it working (This scenario is in demand!)

Pushed the template on my repo if you can take a look. Do you want a guide like:

I'm sorry but I'm not so expert at it

AlienRecall commented 3 years ago

Is there a guide on how to setup properly the wails events? I can't get it working, I'm only getting

TypeError: window.wails.EventsOn is not a function. (In 'window.wails.EventsOn("testEvent",function(e){c(e)})', 'window.wails.EventsOn' is undefined)
leaanthony commented 3 years ago

Where did you read that events are accessed like that? Maybe the docs aren't clear? https://wails.io/docs/reference/runtime/intro for frontend: window.runtime.EventsOn()

leaanthony commented 3 years ago

@AlienRecall genuinely curious if the docs weren't clear enough. Docs need love too!

AlienRecall commented 3 years ago

@AlienRecall genuinely curious if the docs weren't clear enough. Docs need love too!

My bad, I directly jumped to the Events page without reading the Introduction. Also GoLand was suggesting me wails.EventsOn so I was thinking it was the right way. I'll be more careful next time

KoduIsGreat commented 3 years ago

Where did you read that events are accessed like that? Maybe the docs aren't clear? https://wails.io/docs/reference/runtime/intro for frontend: window.runtime.EventsOn()

fwiw I find code examples to be easier to digest then API documentation at least in the case of API changes

KoduIsGreat commented 3 years ago

@leaanthony I'd like to get some clarification (and potentially offer some feedback) In the above discussion we both got our apps working (I think) based on the minified directory aka frontend/build eg: wails.json

  "assetdir": "frontend/build",
  "frontend:build": "npm run build",
  "frontend:install": "npm install",
  "frontend:dev": "",

main.go

  //go:embed frontend/build
var assets embed.FS

In my case, this project was bootstraped via create-react-app.

My application works however, using wails dev, javascript code changes in frontend/src do not cause the dev server to update because the above config is pointing at the output of our npm run build, that is to say its watching for changes in the minified dir and not the src dir.

we also cant watch the frontend/src directory because wails is looking for an index.html at the root of whatever the asset directory provided, and at least for CRA the index is located at frontend/src/public/index.html.

I've seen mention of vite, in other discussions and issues, I was considering trying that because vite has some diifferences that might allow me to work around this issue. if there is a react template I think it should be setup so that it uses whatever tools necessary to provide the same developer experience as the other templates have.

What do you think?

leaanthony commented 3 years ago

Agree. The ideal scenario is using the framework provided dev experience. There's a "devserverurl" option which is a step towards that. The trick is injecting the bindings and runtime. If you look at the wailsjs dir, there's some "dev" versions of the scripts. The intent there is to allow someone to compile in the scripts. Let me know if you're keen on picking this up. I am.

KoduIsGreat commented 3 years ago

I see, thats what i figured, and what i tried intiially but my react dev server could never propertly inject the bindings. I tried a few things but maybe i was looking at the wrong things.

If perhaps you can give me a specific example I can try again I'd be happy to help.

e8panse commented 3 years ago

@KoduIsGreat I have the same issue with react app - there is no injections of wails scripts into the app. "runtime", "go" are not available on window object.

e8panse commented 3 years ago

@KoduIsGreat I finally made it work.

So my recipe for React App CRA:

  1. assetdir in wails.json ./frontend/build
  2. in main.go //go:embed frontend/build
  3. frontend:dev in wails.json yarn build

This way running wails dev we firstly build frontend, then wails inject its scripts.

If your frontend/build folder is empty, it can cause error - wails will complain that it doesn't have embeddable files, just run yarn build in frontend folder, then cd ../ && wails dev

***Using typescript in react app I declare window and runtime as:

//imports

declare const window: any;
declare const runtime: any;

//use these variables
leaanthony commented 3 years ago

You can always opens browser to localhost:34115 see the scripts injected in the head of index.HTML then have them in your react HTML šŸ˜ƒ