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
[v2] (wails:dev) smart rebuild #1031
Comments
Agreed! Happy to accept a PR for it! |
PR to test: #1071 |
In the last few days, after reviewing #1071 PR and looking at the source code related to the dev command, I found some areas for improvement.
|
Thanks for the feedback! I'll answer each point:
Yeah, we could add this to the config.
If we did the above config we could add this by default
Can you please provide more details on this - thanks!
If you want to code this, I'd be happy to merge it. It's not a small task! |
for quit == false { // Line : 536
select {
case exitCode := <-exitCodeChannel:
// ...
case item := <-watcher.Events:
// ...
case <-timer.C:
// ...
case <-quitChannel:
// ...
}
} need to add code that reads and outputs the error channel. for quit == false { // Line : 536
select {
case exitCode := <-exitCodeChannel:
// ...
++ case err := <-watcher.Errors:
++ LogDarkYellow(err.Error())
case item := <-watcher.Events:
// ...
case <-timer.C:
// ...
case <-quitChannel:
// ...
}
} |
Regarding ignore dirs, we have 2 scenarios: "start with", eg |
I'm ok pushing this out to v2.1 and seeing if we need it then. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
An approach like It is convenient to be able to use wildcards to exclude directories as well as certain types of filenames. For example, a test file like |
Hey @Ironpark! Good to see you! I actually really like this idea, but I'm wondering if we can adopt the same idea but put it in
Thoughts? |
Good to see you too! :D Writing on a single line using "dev:ignore": [
"frontend/my/dir/*.js",
"generated/*.go",
"*_test.go"
], |
Of course 👍 Great idea. |
@leaanthony I came up with a more concrete approach to the AST-based file inspection I proposed last January, and wrote some POC code. package main
import (
"bytes"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"golang.org/x/tools/go/ast/astutil"
"hash/fnv"
"strings"
)
func fileHashWithAST(path string) (uint64, error) {
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, path, nil, 0)
if err != nil {
return 0, err
}
badAst := false
pre := func(c *astutil.Cursor) bool {
switch c.Node().(type) {
case *ast.ImportSpec:
c.Delete()
case *ast.BadExpr, *ast.BadDecl, *ast.BadStmt:
badAst = true
return false
}
return true
}
astutil.Apply(node, pre, nil)
if badAst {
return 0, fmt.Errorf("bad ast")
}
buf := bytes.Buffer{}
if err := format.Node(&buf, fset, node); err != nil {
return 0, err
}
cleanStr := strings.Replace(buf.String(), " ", "", -1)
cleanStr = strings.Replace(cleanStr, "\t", "", -1)
cleanStr = strings.Replace(cleanStr, "\r\n", "", -1)
cleanStr = strings.Replace(cleanStr, "\n", "", -1)
hash := fnv.New64a()
_, _ = hash.Write([]byte(cleanStr))
return hash.Sum64(), nil
}
func main() {
fmt.Println(fileHashWithAST("main.go"))
} The basic idea is this
This hash value is unchanged by comments, newlines, and import statements, so you can check for substantive logic changes. When used in a file watcher // Parsing failed: If the file is still being written,
// a syntax error is assumed to have occurred due to an unfinished write.
if current_hash,err := ast_hash(file);err == nil{
// Trigger a rebuild only if the hash value is different from before.
if current_hash != before_hash[file] {
before_hash[file] = current_hash
// -> build update triggering
}
} |
That's quite impressive! Does it have any benefits over running the file through an md5 hasher? Incidentally, this is how task does file watching. |
Fnv is a non-cryptographic hash function. It has no security requirements, so its implementation is simple and fast. Below is a microbenchmark. It's not very reliable due to the low number of iterations, but it's a good starting point.
|
I took a moment to read the documentation. It looks like there are roughly 2-3 ways to use it with Task runner.
|
The reason I was asking is because we have a similar technique for monitoring |
BackgroundIn fact, MD5 was invented as a cryptographic hash function. However, several security flaws have been found that can quickly discover hash collisions, so it is not recommended for security purposes. However, it is still a hash function, so it's not bad for verifying file checksums, and its speed is not bad either. But if you're considering a non-secure hash algorithm, FNV-1a is a good choice. It's fast with a sufficiently good hash distribution and collision resistance because it is implemented in the Go standard hash package. If you don't care about standard packages, I'm not sure if there are properly implemented packages, but Murmur2/3 is also a good choice. It is faster for hashing large data due to structural advantages and has a slightly better hash distribution. Personal ViewsGiven all of the above, if you're hashing a single package.json file, there's honestly no big deal to use MD5 or not - it's still useful in that use case and provides plenty of speed. For more specific information on this topic, we recommend the following links which-hashing-algorithm-is-best-for-uniqueness-and-speed |
I think we'll look for an existing library for rebuilding the app in v3. Vite already handles HMR for the frontend so we're only really dealing with the Go code. I imagine we'll get the rebuild trigger to run a task by default. |
Currently, the wails dev command rebuilds both the frontend and the backend even if the backend code changes that do not affect the frontend.
When the frontend's code base is light, it's not a big problem, but if the frontend build time exceeds a few minutes, it feels like a big problem in productivity.
How about conditionally skipping the frontend build by checking for changed files or checking if the generated "Wails JS" has changed?
The text was updated successfully, but these errors were encountered: