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

[feat] Add .taurignore and turn off the default behavior of watching all workspace members #4617

Closed
simonhyll opened this issue Jul 7, 2022 · 49 comments

Comments

@simonhyll
Copy link
Sponsor Contributor

simonhyll commented Jul 7, 2022

Describe the problem

I use a monolithic style repository. Crates in my repository can be completely unrelated to the Tauri app, such as the REST API. But even if it's related to the app, for example the frontend resides in a separate workspace member than the Tauri source code. The result of watching all workspace members then is that rather than having hot reloading for my frontend, any change to the frontend results in the Tauri app being rebuilt as well. If I update the API, Tauri rebuilds, for absolutely no good reason. Even if I just change the README in another project, it triggers a rebuild of the Tauri app.

The only solution right now for me that sort of works is by passing an ignore file as an environment variable in the format of TAURI_DEV_WATCHER_IGNORE_FILE=.taurignore. It works, but passing that environment variable is incredibly annoying.

Describe the solution you'd like

  • Disable watching all workspace members by default. Add a CLI flag such as --watch-members to enable it. It's a good feature but I highly doubt most people using workspaces are using every single crate in their workspace for the Tauri project. If you disagree, at least add the reverse option, e.g. --no-watch-members
  • Support reading files in the workspace called .taurignore that disable watchers for ignored files

Alternatives considered

None really. I'll use my workaround until either of the above solutions are implemented, or until someone else suggests something better.

One potential improvement to the watched files could be only watching for changes in *.rs files in other workspace members, since it's pretty much guaranteed that the only reason you want to rebuild your Tauri app based on a workspace member change is when you've updated the Rust code. Icons and such most likely reside in the Tauri project itself so watching the entire Tauri project makes sense, but watching all files in all workspace members is almost guaranteed to be unnecessary and unwanted behavior, watching all Rust files should be the only thing people really need. Ignore files would still be required because again, if I have a REST API, I don't want those Rust source files to rebuild my Tauri app as well, but it'd be a start.

Additional context

No response

@mokeyish
Copy link

mokeyish commented Jul 7, 2022

This feature is very nice. i need it

@lucasfernog
Copy link
Member

What if we add a [tauri] section to the workspace Cargo.toml file where you can configure which packages to include or which packages to ignore?

@simonhyll
Copy link
Sponsor Contributor Author

What if we add a [tauri] section to the workspace Cargo.toml file where you can configure which packages to include or which packages to ignore?

I considered this approach as well but then figured that it's far more standardized to use a .ignore file of some kind. It's an option, but in my opinion it's preferable to add .taurignore anyway because it makes it easier to handle the ignores. The workspace file can get pretty bloated otherwise and it's easier to manage ignores in different crates if each crate has its own .taurignore file.

Yet another option could be [package.metadata.tauri] sections in the Cargo.toml files of each crate, but again, this could very easily get very bloated

@amrbashir amrbashir added scope: cli.rs The tauri-cli rust crate priority: 2 medium labels Jul 7, 2022
@lorenzolewis
Copy link
Member

My only nit-pick feedback is the file name missing an 'i'. I know why (and we do the same with tauricon) but it still seems off. .tauri-ignore is outside the convention given by .gitignore but could it be an option?

@simonhyll
Copy link
Sponsor Contributor Author

Personally I like the name .taurignore more, having .tauriignore looks weird and feels somewhat redundant and annoying to type. If you really don't like turning 2 i's into 1 then .tauri-ignore is at least nicer than .tauriignore, but as you say, it goes against the naming convention of ignore files, and .taurignore is more in line with tauricon so it's also in line with the Tauri project naming conventions.

@lorenzolewis
Copy link
Member

Agree that .tauriignore is a no-go. I think it's just more from a branding/consistency perspective than anything. tauricon is weird to me but I get it's a play on words.

End of the day it doesn't matter, just wanted to put it out there.

@sak96
Copy link

sak96 commented Jul 7, 2022

my vote goes to : .tauri_ignore or .tauri-ignore.

@FabianLars
Copy link
Member

If this feature request turns into a discussion about the name of a file and not about the feature itself we may take the easy route and accept all 4 variants and let each user decide for themself 😆

@lucasfernog
Copy link
Member

I like .taurignore. And this feature request is so simple that we should discuss the file name instead 😂 😂

@lorenzolewis
Copy link
Member

Regex of /.tauri.?i?gnore/gmi anyone? 😂

@FabianLars
Copy link
Member

FabianLars commented Jul 7, 2022

Shouldn't we much rather discuss this

Disable watching all workspace members by default. Add a CLI flag such as --watch-members to enable it. It's a good feature but I highly doubt most people using workspaces are using every single crate in their workspace for the Tauri project. If you disagree, at least add the reverse option, e.g. --no-watch-members

and this

One potential improvement to the watched files could be only watching for changes in *.rs files in other workspace members

? 😆

P.S. it's 3v2 in favor of .taurignore right now 👀 (Edit: yes, my muscle memory wrote .gitignore)

Regex of /.tauri.?i?gnore/gmi anyone? 😂

Now that's what i'm talking about

@sak96
Copy link

sak96 commented Jul 7, 2022

may be providing a key tauri.conf.json::build.ignorefile and using any default value should be fine.

also one more esoteric name tauri::ignore.

@lucasfernog
Copy link
Member

I think we should disable watching by default (not only on workspaces) and enable it behind a --watch argument.

@FabianLars
Copy link
Member

tauri::ignore

Luckily that one isn't a valid file name 😂

@sak96

This comment was marked as off-topic.

@FabianLars
Copy link
Member

I think we should disable watching by default (not only on workspaces) and enable it behind a --watch argument.

Hmm, not really a fan of that one. imo it would be especially weird for devs with a webtech background (because of the bundlers all having HMR and stuff). They probably don't do much rust dev, but at least change the config somewhat regularly.
Or maybe it's just me being too lazy to type an additional flag.

@simonhyll
Copy link
Sponsor Contributor Author

simonhyll commented Jul 7, 2022

I think watching the Tauri project directory should be on by default, but maybe add an option to disable it with --no-watch I guess just in case someone doesn't want it watched, like, if it's undressing I guess or something and wants some privacy 🤷‍♂️

If you wanna add --watch and -w for the project dir then it'd be --watch-members and -wm for watching members

Or, if you make watching the project the default, you can just have --watch and -w for watching members, project dir is on by default, and --no-watch disables watching both workspace members and the project dir

Regardless of approach chosen for the CLI options I think that at least so far it's clear that some manner of ignore file is desired, and as long as ignore files get added it doesn't matter THAT much which CLI options are added, if everything is watched everywhere by default then you can just work with the ignore files to disable the behavior where it shouldn't be applied

So the most important thing to do right now is discuss the name of the ignore file and implement that function. CLI options are desired but aren't immediately necessary to fix the issue

@lucasfernog
Copy link
Member

Let's go with the ignore file and --no-watch then.

@simonhyll
Copy link
Sponsor Contributor Author

Just to be clear here, when you say --no-watch, which variant? Disabling just the project dir, workspace members, or both? If I had to pick I'd want it to disable members while keeping project watch, or adding both --no-watch and --no-watch-members

@lucasfernog
Copy link
Member

How about no-watch and no-watch-workspace then?

@mokeyish
Copy link

mokeyish commented Jul 8, 2022

It's enought that just no-watch everthing listing in .taurignore

@Beanow
Copy link
Member

Beanow commented Jul 8, 2022

Ok story time.

6 years in the future you're reading this issue, because you just spent the whole day troubleshooting, why watches went weird since about last month at your company. You set out to fix it, once and for all.

It turns out, your monorepo with 50-or-so packages had some quirky git submodules pulled in.
One such submodule being a UI framework mordor-ui and logically they chose as their ignore file .YOU-SHALL-NOT-WATCH.
The other was a pet project from a guy that already left the company who made their own fuse-wtfs-rs (see what I did there?).
It supports emoji expansion in filenames so naturally they chose .ntfs...:puke: to show this feature off.

In fact, even your first attempt didn't work.
Because you started with a search-in-project for: .taurignore (which you have a habit of using in your projects) but that didn't even match half the files because you were supposed to search for /.tauri.?i?gnore/gmi.


In short, I believe we should pick one name, and be prepared to support it until the end of time.
Because even just supporting .taurignore and .tauri-ignore means a "degraded" collaboration experience where devs should know by heart to glob search for .tauri* at minimum.

While the magic of .gitignore / .dockerignore et. all is that 99% of the time it just keeps on working no matter how many projects you clone from who-knows-where.

@JonasKruckenberg
Copy link
Contributor

JonasKruckenberg commented Jul 8, 2022

I'm completely on board with what @Beanow said, we need to have one format, one filename and very well defined behaviour. So let's think this through proper before merging #4623.

What should it mean for a file to be included in the .taurignore file? Does is simply exclude it from being watched during demoed? Does it exclude the file from being bundled too? How does this interact with the no-bundler option? How does it interact with bundlers? Should we provide env vars to the beforeDev and beforeBuild command to let the know about this?

IMO there is too much left unanswered yet.

Edit: Also what about removing the custom watching feature entirely and just pre-filling the build.rs script with defaults for println!("cargo:rerun-if-changed=<file or folder>");? That would leave the user in control of choosing wether to watch their workspace or not (and it would also remove yet another Tauri specific quirk in favour or a standard solution)

@lucasfernog
Copy link
Member

cargo:rerun-if-changed is only meant to rerun the build script if a file change, it does not watch the file and rebuild the app.

@lucasfernog
Copy link
Member

I think .taurignore should only apply for the dev watcher and app path resolver since the bundler has its own configuration and we can add exclude rules in there later.

@simonhyll
Copy link
Sponsor Contributor Author

simonhyll commented Jul 8, 2022

I agree that .taurignore should just be related to the dev environment, since the bundler has its own configurations in tauri.conf.json. If it becomes relevant later to use .taurignore for the bundler it could be implemented as a CLI option such as --bundler-use-ignore or something like that. The default handling or .taurignore would be to disable watchers, but extra behaviors could just be flags in the CLI. And the reason it makes more sense to use .taurignore for this rather than have options in tauri.conf.json is simply that it's easier to manage, it's logical, it avoids bloating an already fairly bloated config file, and most importantly, it's kinda cool to have your own ignore file for your framework

@mokeyish
Copy link

When will feature .taurignore be released?

@FabianLars
Copy link
Member

@mokeyish It's already a thing. But for now you need to manually specify it via an env var, like described in the original issue description:

The only solution right now for me that sort of works is by passing an ignore file as an environment variable in the format of TAURI_DEV_WATCHER_IGNORE_FILE=.taurignore. It works, but passing that environment variable is incredibly annoying.

@mokeyish
Copy link

Thanks

@mokeyish
Copy link

@FabianLars Hi, Reading ignore files seems not enabled.

builder.require_git(false).ignore(false).max_depth(Some(1));

@FabianLars
Copy link
Member

This is something different. Adding custom ignore files via the env var works (and .gitignore files should work too), this setting is only about automatically reading files named .ignore

@mokeyish
Copy link

mokeyish commented Jul 13, 2022

It dose't work when I add any file to src/ui in my project.

Project structure

.
├── crates                 
├── scripts
│   ├── cross-run.bat            # use git bash to run cross-run.sh on windows.
│   └── cross-run.sh             # load .env if exits
├── src
│   ├── ui                       # web project
│   └── main.rs
├── Cargo.toml
├── .taurignore                  # content: `src/ui/`
├── package.json
├── tauri.conf.json
├── .env                         # conrent: `export TAURI_DEV_WATCHER_IGNORE_FILE=.taurignore`

file: package.json

{
  "license": "MIT",
  "private": true,
  "workspaces": [
    "src/ui"
  ],
  "scripts": {
    "dev": "scripts/cross-run concurrently -k npm:vite-dev npm:tauri-dev",
    "build": "npm run vite-build && npm run tauri-build",
    "tauri-dev": "tauri dev",
    "tauri-build": "tauri build",
    "vite-dev": "vite src/ui",
    "vite-build": "vite build src/ui",
    "vite-preview": "vite preview src/ui"
  }
}

file: cross-run.bat

@echo off
chcp 65001 >nul 2>&1

FOR /F "tokens=*" %%g IN ('where git') do (SET GIT_PATH=%%g)
FOR %%i IN ("%GIT_PATH%") DO (SET GIT_DIR=%%~di%%~pi)

SET SHELL_CMD="%GIT_DIR%bash.exe" -c "scripts/cross-run.sh %*"

%SHELL_CMD%

file: cross-run.sh

#!/usr/bin/env bash

if [[ "$1" == "scriptsenv-run" ]]; then
  shift
fi

[ -f .env ] && source .env

cmd=$@

bash -c "$cmd"

@eliaperantoni
Copy link

While not strictly related to .taurignore, I'm having trouble getting any form of ignoring to work.
Here's a minimal working example: https://transfer.sh/0EwbUz/issue.tar.gz
(Sorry for the archive, I know it's not the best but I didn't really want to create a whole new repo just for this)

If I run:

export TAURI_DEV_WATCHER_IGNORE_FILE=$(pwd)/.taurignore
cargo tauri dev

and then edit frontend/dist/index.html, the Tauri watcher is still getting triggered. Am I doing anything wrong?

asciicast

@FabianLars
Copy link
Member

@eliaperantoni i'm not entirely sure and imo the ignore stuff feels a little wonky, but i think the taurignore file needs to be next to the tauri.conf.json file with paths relative to that file (and set the env var to just .taurignore). It's a little unfortunate when the src-tauri dir is not the root, but idk if we can improve the situation with the current dir walker 🤔

p.s. i'm not really experienced with the ignore thingy so maybe i got something wrong, but this is how i made it work for me.

@eliaperantoni
Copy link

I tried your suggestion but it, unfortunately, didn't work 😔. The .taurignore file was already next to tauri.conf.json but I changed the env var to just .taurignore and the contents of the file to ../frontend/dist/index.html. Editing index.html still causes the Tauri watcher to trigger.

I noticed the watcher is implemented using the ignore crate. Whenever a workspace is used, every member's path is recursively walked using a ignore::Walk to get a list of files to watch. This is where all the ignore filters come into play.

fn lookup<F: FnMut(FileType, PathBuf)>(dir: &Path, mut f: F) {
let mut default_gitignore = std::env::temp_dir();
default_gitignore.push(".tauri-dev");
let _ = std::fs::create_dir_all(&default_gitignore);
default_gitignore.push(".gitignore");
if !default_gitignore.exists() {
if let Ok(mut file) = std::fs::File::create(default_gitignore.clone()) {
let _ = file.write_all(crate::dev::TAURI_DEV_WATCHER_GITIGNORE);
}
}
let mut builder = ignore::WalkBuilder::new(dir);
builder.add_custom_ignore_filename(".taurignore");
let _ = builder.add_ignore(default_gitignore);
if let Ok(ignore_file) = std::env::var("TAURI_DEV_WATCHER_IGNORE_FILE") {
builder.add_ignore(ignore_file);
}
builder.require_git(false).ignore(false).max_depth(Some(1));
for entry in builder.build().flatten() {
f(entry.file_type().unwrap(), dir.join(entry.path()));
}
}

Notice builder.add_ignore(default_gitignore), that's where a default filter is loaded:

let _ = builder.add_ignore(default_gitignore);

node_modules/
target/
Cargo.lock

When TAURI_DEV_WATCHER_IGNORE_FILE is provided, the same exact function is called to load it:

if let Ok(ignore_file) = std::env::var("TAURI_DEV_WATCHER_IGNORE_FILE") {
builder.add_ignore(ignore_file);
}

So I did some experimentation:

  • If I have my .taurignore be just *, then it works: no reloading ever happens
  • If I have my .taurignore ignore just a folder like frontend/, it's not really ignored
  • But if I use something like node_modules as my folder name, which is ignored by default, then I get what I want: no reloading when editing files under that directory

The fact that the default filter seems to be working as intended while the custom one doesn't, even though they're loaded in the very same way, is only short of magical 🔮.

Possible workarounds:

  • Turn off watching with --no-watch. That's what I'm doing for now
  • If the directory you want to ignore is a workspace member that doesn't strictly need to be such (for example a UI built with Yew.rs), remove that from the workspace and make it a standalone crate
  • Name your crate node_modules 😂

If this is affecting more people I'd be happy to investigate further on the issue and, possibly, come up with a PR. If anyone else could try running the minimal example I provided in #4617 (comment) to see if it works, that could be useful. Although I think it's unlikely this issue is related to my machine.

@numfin
Copy link

numfin commented Oct 15, 2022

If anyone will come here in future confused as me -> here's the solution 👇
My Setup:
Tauri + Trunk + Your favourite rust wasm framework (i'm using dominator)

/ (workspace)
/frontend (workspace member)
/src-tauri (workspace member)

At first trunk serve compiled all dependencies each time i press save: as i found out cargo clippy (triggered by rust-analyzer) in my vscode triggered it. The solution was to create .cargo/config.toml for root and each member of workspace so you have something like:

/.cargo/config.toml
[build]
target = "x86_64-unknown-linux-gnu"
/frontend/.cargo/config.toml
[build]
target = "wasm32-unknown-unknown"
/src-tauri/.cargo/config.toml
[build]
target = "x86_64-unknown-linux-gnu"

Next problem was that tauri decided to do the same 😄 I'm not gonna waste my time figuring out why but i decided to move dist folder to root and here is what i did:

/Trunk.toml
[build]
target = "frontend/index.html"
dist = "dist"
/.taurignore
dist/*
frontend/*
target/*

After this i had perfect setup, where my tauri window reloads only when src-tauri folder updated and when frontend folder updated - it only triggers content (html) to update.

Tauri please add somewhere docs about how to configure multi member projects.

@JiveyGuy
Copy link

JiveyGuy commented Apr 22, 2023

Was just reading this discussion because I knew .taurignore existed but wasn't sure what dir it was in,

For those here, it is in the root dir of the project at the same level as .gitignore.

@Maruchero
Copy link

Finally after hours of attempts and research I found the correct placement for .taurignore file in a stackoverflow question with 0 upvotes. I want to share it so you don't have to waste your time like I did.

you can completely disable the watcher by using the --no-dev-watcher flag when running tauri dev. Alternatively you can create a .taurignore file next to your tauri.conf.json file in which you can tell tauri to ignore the path of your image similar to how .gitignore files work.

@sak96
Copy link

sak96 commented Jul 20, 2023

Finally after hours of attempts and research I found the correct placement for .taurignore file in a stackoverflow question with 0 upvotes. I want to share it so you don't have to waste your time like I did.

you can completely disable the watcher by using the --no-dev-watcher flag when running tauri dev. Alternatively you can create a .taurignore file next to your tauri.conf.json file in which you can tell tauri to ignore the path of your image similar to how .gitignore files work.

sorry to bump the thread.

But i think i now use https://github.com/tauri-apps/create-tauri-app for generatign the yew + tauri project that reduce the issues.

cargo install create-tauri-app
cargo create-tauri-app

@Lovely-Ruby
Copy link

thanks for your advice,it work!!

@boan-anbo
Copy link

boan-anbo commented Mar 11, 2024

This definitely needs to be documented for people using Rust workspace.

To add a few examples:

Say your src-tauri is within a workspace with a peer workspace member crate_one whose folder is C:\project\members\crate_one

In taurignore, placed next to tauri.conf.json, these work:

// absolute path works of course, but mostly useless.
C:/project/crate_one

// this works, ignoring everything under `crate_one`
**/crate_one/

// this also works, same as above
**/crate_one/**

// or if you specifically want to unwatch subfolder changes, 
// but keep watching every child directly under `crate_one` folder:
**/crate_one/**/**

// this is slightly different from the one above, 
// only ignoring the direct children of every child folder of `crate_one`, 
// but keep watching everything else
**/crate_one/**/*

These don't work:

// using * instead of ** doesn't work
*/crate_one/
*/crate_one/**/*

surprisingly, if you specifically want to NOT to watch a subfolder under crate_one, you can't

// this doesn't work
**/crate_one/sub_folder/subsubfolder_to_unwatch/**

// this doesn't work either
**/crate_one/**/subsubfolder_to_unwatch/**

@FabianLars
Copy link
Member

This definitely needs to be documented for people using Rust workspace.

I agree but where would you expect to find this in the docs? Genuine question as we're currently rewriting the docs and i have no idea where to put this.

@JiveyGuy
Copy link

This definitely needs to be documented for people using Rust workspace.

I agree but where would you expect to find this in the docs? Genuine question as we're currently rewriting the docs and i have no idea where to put this.

I would suggest maybe a note under getting started you could include a note for .gitignore and a .tauriignore section about setting up the dev environment.

@boan-anbo
Copy link

boan-anbo commented Mar 12, 2024

This definitely needs to be documented for people using Rust workspace.

I agree but where would you expect to find this in the docs? Genuine question as we're currently rewriting the docs and i have no idea where to put this.

I would imagine a sub-section or a separate page under develop such as here:

https://beta.tauri.app/guides/develop/

Which is about the DX experience, including things like setting up IDEs for Tauri dev., where best to place shared env variables and keys, how to set up auto-reloads (where .taurignore fits), etc.

@FabianLars
Copy link
Member

Hmm yeah, i like that. Thank you!

@justingolden21
Copy link

justingolden21 commented Aug 20, 2024

I'm trying to ignore everything in my /static/img/screenshots directory and I tried adding .taurignore with both /static/img/screenshots and static/img/screenshots to both root and inside my src-tauri/ directory and it still builds them in. I also tried .tauriignore and no luck.

It seems like this was closed and merged 2 years ago. I can't seem to find any documentation online other than this thread. Help appreciated!

I found a mention of it in these release notes: https://tauri.app/blog/2022/09/15/tauri-1-1/ I'm using "@tauri-apps/cli": "^1.5.13"

EDIT: found this guy saying the trailing asterisk is necessary: https://github.com/eliaperantoni/spaceman/blob/main/.taurignore I've now tried

static/img/screenshots
/static/img/screenshots

static/img/screenshots/
/static/img/screenshots/

static/img/screenshots/*
/static/img/screenshots/*

and it still doesn't ignore that folder

Everyone here says to place it in root, but this tweet says to place it inside src-tauri https://x.com/CrabNebulaDev/status/1743297603213935063

@FabianLars
Copy link
Member

@justingolden21

and it still builds them in

Assuming i understand you correctly then this is not what .taurignore is about. The ignore file is only for the file system watcher to ignore changes to the ignored paths so that the app doesn't get recompiled. It does not influence what files are built or included in builds.

If you want to exclude files from your devPath/distDir then this is up to your frontend bundler (if you use just tauri and no frontend bundler then tauri can't do it).

@justingolden21
Copy link

justingolden21 commented Aug 20, 2024

@justingolden21

and it still builds them in

Assuming i understand you correctly then this is not what .taurignore is about. The ignore file is only for the file system watcher to ignore changes to the ignored paths so that the app doesn't get recompiled. It does not influence what files are built or included in builds.

If you want to exclude files from your devPath/distDir then this is up to your frontend bundler (if you use just tauri and no frontend bundler then tauri can't do it).

Ah, yeah I think I misunderstood what the file is for. I just wanted to ignore some screenshots that are used for SEO only. Thanks for the quick and well explained reply!

I'll look into my bundler. Thanks again.

@justingolden21
Copy link

I ended up doing it in a node script:

// Delete files that aren't necessary for tauri so they don't get bundled with the tauri app
import fs from 'fs';

// Delete img folder
const paths = ['build/img'];
for (const path of paths) {
	if (fs.existsSync(path)) {
		fs.rmSync(path, { recursive: true });
		console.log(`Deleted ${path}`);
	}
}

And then calling that before build in tauri.conf.json:

"beforeBuildCommand": "npm run build && node infrastructure/clean-tauri.js"

This way it first builds, then removes the built screenshots and then builds tauri, so the source screenshots aren't deleted and I don't need to manually do anything or touch the normal app logic. Also no dependencies. Of course you could just use rm linux command, but this is cross platform and built in to node.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests