feat: build without proc macros (#1226)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
chip
2021-03-12 17:10:19 -08:00
committed by GitHub
parent bd1df5d804
commit c88838aa76
137 changed files with 1883 additions and 12090 deletions

3
.gitignore vendored
View File

@@ -85,8 +85,5 @@ target
# todo: needs a proper fic
/cli/tauri.js/tauri.conf.js
# doing this because the task-runner (`mask prepare`) will clone gh:tauri-apps/examples
/examples
# ignore frida handlers
__handlers__/

View File

@@ -4,7 +4,21 @@ members = [
"tauri-api",
"tauri-macros",
"tauri-utils",
# core
"core/tauri-build",
"core/tauri-codegen",
# examples
"examples/api/src-tauri",
"examples/helloworld/src-tauri",
"examples/multiwindow/src-tauri",
]
exclude = [
"examples",
]
# default to small, optimized workspace release binaries
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
incremental = false
opt-level = "s"

View File

@@ -135,8 +135,10 @@ pub fn get_bundler_settings(config: &Config, debug: bool) -> crate::Result<Bundl
}
}
if binaries.len() == 1 {
binaries.get_mut(0).unwrap().set_main(true);
match binaries.len() {
0 => binaries.push(BundleBinary::new(package.name.clone(), true)),
1 => binaries.get_mut(0).unwrap().set_main(true),
_ => {}
}
Ok(BundlerSettings {

View File

@@ -77,29 +77,34 @@ Run \`tauri init --force template\` to overwrite.`)
if (!force) return false
}
const resolveTauriPath = (tauriPath: string): string => {
const resolveTauriPath = (tauriPath: string, crate: string): string => {
const resolvedPath = isAbsolute(tauriPath)
? join(tauriPath, 'tauri') // we received a full path as argument
: join('..', tauriPath, 'tauri') // we received a relative path
? join(tauriPath, crate) // we received a full path as argument
: join('..', tauriPath, crate) // we received a relative path
return resolvedPath.replace(/\\/g, '/')
}
const resolveCurrentTauriVersion = (): string => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
const tauriManifest = require('../../../../tauri/Cargo.toml') as CargoManifest
const resolveCurrentTauriVersion = (crate: string): string => {
const manifestPath = `../../../../${crate}/Cargo.toml`
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access, security/detect-non-literal-require
const tauriManifest = require(manifestPath) as CargoManifest
const version = tauriManifest.package.version
return version.substring(0, version.lastIndexOf('.'))
}
const tauriDep = tauriPath
? `{ path = "${resolveTauriPath(tauriPath)}" }`
: `{ version = "${resolveCurrentTauriVersion()}" }`
? `{ path = "${resolveTauriPath(tauriPath, 'tauri')}" }`
: `{ version = "${resolveCurrentTauriVersion('tauri')}" }`
const tauriBuildDep = tauriPath
? `{ path = "${resolveTauriPath(tauriPath, 'core/tauri-build')}" }`
: `{ version = "${resolveCurrentTauriVersion('core/tauri-build')}" }`
removeSync(dir)
copyTemplates({
source: resolve(__dirname, '../../templates/src-tauri'),
scope: {
tauriDep
tauriDep,
tauriBuildDep
},
target: dir
})

View File

@@ -11,17 +11,17 @@ build = "src/build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
tauri-build = <%= tauriBuildDep %>
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = <%= tauriDep || `{ version = "0.5" }` %>
tauri = <%= tauriDep %>
[target."cfg(windows)".build-dependencies]
winres = "0.1"
[features]
default = [ "custom-protocol" ]
custom-protocol = [ "tauri/custom-protocol" ]
[[bin]]
name = "app"
path = "src/main.rs"

View File

@@ -1,16 +1,3 @@
#[cfg(windows)]
extern crate winres;
#[cfg(windows)]
fn main() {
if std::path::Path::new("icons/icon.ico").exists() {
let mut res = winres::WindowsResource::new();
res.set_icon_with_id("icons/icon.ico", "32512");
res.compile().expect("Unable to find visual studio tools");
} else {
panic!("No Icon.ico found. Please add one or check the path");
}
tauri_build::build()
}
#[cfg(not(windows))]
fn main() {}

View File

@@ -3,12 +3,8 @@
windows_subsystem = "windows"
)]
#[derive(tauri::FromTauriContext)]
struct Context;
fn main() {
tauri::AppBuilder::<Context>::new()
.build()
.unwrap()
.run();
let context = tauri::generate_tauri_context!();
tauri::AppBuilder::default().build(context).run();
}

View File

@@ -1,10 +1,9 @@
use tauri::ApplicationDispatcherExt;
#[derive(tauri::FromTauriContext)]
struct Context;
fn main() {
tauri::AppBuilder::<tauri::flavors::Wry, Context>::new()
let context = tauri::generate_tauri_context!();
tauri::AppBuilder::default()
.setup(|webview_manager| async move {
let mut webview_manager_ = webview_manager.clone();
tauri::event::listen(String::from("hello"), move |_| {
@@ -24,7 +23,6 @@ fn main() {
webview_manager.close().unwrap();
}
})
.build()
.unwrap()
.build(context)
.run();
}

View File

@@ -0,0 +1,30 @@
[package]
name = "tauri-build"
version = "0.1.0"
authors = [ "Tauri Community" ]
categories = [ "gui", "web-programming" ]
license = "MIT"
homepage = "https://tauri.studio"
repository = "https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build"
description = "build time code to pair with https://crates.io/crates/tauri"
edition = "2018"
[dependencies]
anyhow = "1"
# context dependencies
proc-macro2 = "1"
quote = "1"
tauri-codegen = { path = "../tauri-codegen", optional = true }
[target."cfg(windows)".dependencies]
winres = "0.1"
[features]
# keep context non-default to prevent some relatively large deps being pulled
codegen = ["tauri-codegen"]
# enable feature flags on https://docs.rs/tauri-build
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "doc_cfg"]

View File

@@ -0,0 +1,134 @@
use anyhow::{Context, Result};
use proc_macro2::Ident;
use quote::format_ident;
use std::{
env::var,
fs::{create_dir_all, File},
io::{BufWriter, Write},
path::PathBuf,
};
use tauri_codegen::{context_codegen, ContextData};
/// A builder for generating a Tauri application context during compile time.
///
/// Meant to be used with [`tauri::include_codegen_context!`] inside your application code.
///
/// [`tauri::include_codegen_context!`]: https://docs.rs/tauri/0.12/tauri/macro.include_codegen_context.html
#[cfg_attr(doc_cfg, doc(cfg(feature = "codegen")))]
#[derive(Debug)]
pub struct CodegenContext {
config_path: PathBuf,
struct_ident: Ident,
out_file: PathBuf,
}
impl Default for CodegenContext {
fn default() -> Self {
Self {
config_path: PathBuf::from("tauri.conf.json"),
struct_ident: format_ident!("TauriBuildCodegenContext"),
out_file: PathBuf::from("tauri-build-context.rs"),
}
}
}
impl CodegenContext {
/// Create a new [`CodegenContext`] builder that is already filled with the default options.
pub fn new() -> Self {
Self::default()
}
/// Set the path to the `tauri.conf.json` (relative to the package's directory).
///
/// This defaults to a file called `tauri.conf.json` inside of the current working directory of
/// the package compiling; does not need to be set manually if that config file is in the same
/// directory as your `Cargo.toml`.
pub fn config_path(mut self, config_path: impl Into<PathBuf>) -> Self {
self.config_path = config_path.into();
self
}
/// Set the name of the generated struct.
///
/// Don't set this if you are using [`tauri::include_codegen_context!`] as that helper macro
/// expects the default value. This option can be useful if you are not using the helper and
/// instead using [`std::include!`] on the generated code yourself.
///
/// Defaults to `TauriBuildCodegenContext`.
///
/// [`tauri::include_codegen_context!`]: https://docs.rs/tauri/0.12/tauri/macro.include_codegen_context.html
pub fn struct_ident(mut self, ident: impl AsRef<str>) -> Self {
self.struct_ident = format_ident!("{}", ident.as_ref());
self
}
/// Sets the output file's path.
///
/// **Note:** This path should be relative to the `OUT_DIR`.
///
/// Don't set this if you are using [`tauri::include_codegen_context!`] as that helper macro
/// expects the default value. This option can be useful if you are not using the helper and
/// instead using [`std::include!`] on the generated code yourself.
///
/// Defaults to `tauri-build-context.rs`.
///
/// [`tauri::include_codegen_context!`]: https://docs.rs/tauri/0.12/tauri/macro.include_codegen_context.html
pub fn out_file(mut self, filename: PathBuf) -> Self {
self.out_file = filename;
self
}
/// Generate the code and write it to the output file - returning the path it was saved to.
///
/// Unless you are doing something special with this builder, you don't need to do anything with
/// the returned output path.
///
/// # Panics
///
/// If any parts of the codegen fail, this will panic with the related error message. This is
/// typically desirable when running inside a build script; see [`Self::try_build`] for no panics.
pub fn build(self) -> PathBuf {
match self.try_build() {
Ok(out) => out,
Err(error) => panic!("Error found during Codegen::build: {}", error),
}
}
/// Non-panicking [`Self::build`]
pub fn try_build(self) -> Result<PathBuf> {
let (config, config_parent) = tauri_codegen::get_config(&self.config_path)?;
let code = context_codegen(ContextData {
config,
config_parent,
struct_ident: self.struct_ident.clone(),
})?;
// get the full output file path
let out = var("OUT_DIR")
.map(PathBuf::from)
.map(|path| path.join(&self.out_file))
.with_context(|| "unable to find OUT_DIR during tauri-build")?;
// make sure any nested directories in OUT_DIR are created
let parent = out.parent().with_context(|| {
"`Codegen` could not find the parent to `out_file` while creating the file"
})?;
create_dir_all(parent)?;
let mut file = File::create(&out).map(BufWriter::new).with_context(|| {
format!(
"Unable to create output file during tauri-build {}",
out.display()
)
})?;
writeln!(&mut file, "{}", code).with_context(|| {
format!(
"Unable to write tokenstream to out file during tauri-build {}",
out.display()
)
})?;
Ok(out)
}
}

View File

@@ -0,0 +1 @@
pub(crate) mod context;

View File

@@ -0,0 +1,56 @@
#![cfg_attr(doc_cfg, feature(doc_cfg))]
pub use anyhow::Result;
#[cfg(feature = "codegen")]
mod codegen;
#[cfg(feature = "codegen")]
pub use codegen::context::CodegenContext;
/// Run all build time helpers for your Tauri Application.
///
/// The current helpers include the following:
/// * Generates a Windows Resource file when targeting Windows.
///
/// # Platforms
///
/// [`build()`] should be called inside of `build.rs` regardless of the platform:
/// * New helpers may target more platforms in the future.
/// * Platform specific code is handled by the helpers automatically.
/// * A build script is required in order to activate some cargo environmental variables that are
/// used when generating code and embedding assets - so [`build()`] may as well be called.
///
/// In short, this is saying don't put the call to [`build()`] behind a `#[cfg(windows)]`.
///
/// # Panics
///
/// If any of the build time helpers fail, they will [`std::panic!`] with the related error message.
/// This is typically desirable when running inside a build script; see [`try_build`] for no panics.
pub fn build() {
if let Err(error) = try_build() {
panic!("error found during tauri-build: {}", error);
}
}
/// Non-panicking [`build()`].
pub fn try_build() -> Result<()> {
#[cfg(windows)]
{
use anyhow::{anyhow, Context};
use std::path::Path;
use winres::WindowsResource;
if Path::new("icons/icon.ico").exists() {
let mut res = WindowsResource::new();
res.set_icon_with_id("icons/icon.ico", "32512");
res.compile().with_context(|| {
"failed to compile icons/icon.ico into a Windows Resource file during tauri-build"
})?;
} else {
return Err(anyhow!("no icons/icon.ico file found; required for generating a Windows Resource file during tauri-build"));
}
}
Ok(())
}

View File

@@ -0,0 +1,20 @@
[package]
name = "tauri-codegen"
version = "0.1.0"
authors = [ "Tauri Community" ]
categories = [ "gui", "web-programming" ]
license = "MIT"
homepage = "https://tauri.studio"
repository = "https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen"
description = "code generation meant to be consumed inside of `tauri` through `tauri-build` or `tauri-macros`"
edition = "2018"
[dependencies]
proc-macro2 = "1"
quote = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri-api = { path = "../../tauri-api", features = ["build"] }
thiserror = "1"
walkdir = "2"
zstd = "0.6"

View File

@@ -0,0 +1,69 @@
use crate::embedded_assets::{EmbeddedAssets, EmbeddedAssetsError};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use std::path::PathBuf;
use tauri_api::config::Config;
/// Necessary data needed by [`codegen_context`] to generate code for a Tauri application context.
pub struct ContextData {
pub config: Config,
pub config_parent: PathBuf,
pub struct_ident: Ident,
}
/// Build an `AsTauriContext` implementation for including in application code.
pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsError> {
let ContextData {
config,
config_parent,
struct_ident,
} = data;
let dist_dir = config_parent.join(&config.build.dist_dir);
// generate the assets inside the dist dir into a perfect hash function
let assets = EmbeddedAssets::new(&dist_dir)?;
// handle default window icons for Windows targets
let default_window_icon = if cfg!(windows) {
let icon_path = config_parent.join("icons/icon.ico").display().to_string();
quote!(Some(include_bytes!(#icon_path)))
} else {
quote!(None)
};
let tauri_script_path = dist_dir.join("__tauri.js").display().to_string();
// double braces are purposeful to force the code into a block expression
Ok(quote! {{
use ::tauri::api::private::{OnceCell, AsTauriContext};
static CONFIG: OnceCell<::tauri::api::config::Config>= OnceCell::new();
/// Generated by `tauri-codegen`.
struct #struct_ident;
impl AsTauriContext for #struct_ident {
/// Return a static reference to the config we parsed at build time
fn config() -> &'static ::tauri::api::config::Config {
CONFIG.get_or_init(|| #config)
}
/// Inject assets we generated during build time
fn assets() -> &'static ::tauri::api::assets::EmbeddedAssets {
#assets
}
/// Make the __tauri.js a dependency for the compiler
fn raw_tauri_script() -> &'static str {
include_str!(#tauri_script_path)
}
/// Default window icon to set automatically if exists
fn default_window_icon() -> Option<&'static [u8]> {
#default_window_icon
}
}
#struct_ident {}
}})
}

View File

@@ -0,0 +1,135 @@
use proc_macro2::TokenStream;
use quote::{quote, ToTokens, TokenStreamExt};
use std::{
collections::HashMap,
env::var,
fs::File,
io::BufReader,
path::{Path, PathBuf},
};
use tauri_api::assets::AssetKey;
use thiserror::Error;
use walkdir::WalkDir;
/// (key, (original filepath, compressed bytes))
type Asset = (AssetKey, (String, Vec<u8>));
/// All possible errors while reading and compressing an [`EmbeddedAssets`] directory
#[derive(Debug, Error)]
pub enum EmbeddedAssetsError {
#[error("failed to read asset at {path} because {error}")]
AssetRead {
path: PathBuf,
error: std::io::Error,
},
#[error("failed to write asset from {path} to Vec<u8> because {error}")]
AssetWrite {
path: PathBuf,
error: std::io::Error,
},
#[error("invalid prefix {prefix} used while including path {path}")]
PrefixInvalid { prefix: PathBuf, path: PathBuf },
#[error("failed to walk directory {path} because {error}")]
Walkdir {
path: PathBuf,
error: walkdir::Error,
},
}
/// Represent a directory of assets that are compressed and embedded.
///
/// This is the compile time generation of [`tauri_api::assets::Assets`] from a directory. Assets
/// from the directory are added as compiler dependencies by dummy including the original,
/// uncompressed assets.
///
/// The assets are compressed during this runtime, and can only be represented as a [`TokenStream`]
/// through [`ToTokens`]. The generated code is meant to be injected into an application to include
/// the compressed assets in that application's binary.
pub struct EmbeddedAssets(HashMap<AssetKey, (String, Vec<u8>)>);
impl EmbeddedAssets {
/// Compress a directory of assets, ready to be generated into a [`tauri_api::assets::Assets`].
pub fn new(path: &Path) -> Result<Self, EmbeddedAssetsError> {
WalkDir::new(&path)
.follow_links(true)
.into_iter()
.filter_map(|entry| match entry {
// we only serve files, not directory listings
Ok(entry) if entry.file_type().is_dir() => None,
// compress all files encountered
Ok(entry) => Some(Self::compress_file(path, entry.path())),
// pass down error through filter to fail when encountering any error
Err(error) => Some(Err(EmbeddedAssetsError::Walkdir {
path: path.to_owned(),
error,
})),
})
.collect::<Result<_, _>>()
.map(Self)
}
/// Use highest compression level for release, the fastest one for everything else
fn compression_level() -> i32 {
match var("PROFILE").as_ref().map(String::as_str) {
Ok("release") => 22,
_ => -5,
}
}
/// Compress a file and spit out the information in a [`HashMap`] friendly form.
fn compress_file(prefix: &Path, path: &Path) -> Result<Asset, EmbeddedAssetsError> {
let reader =
File::open(&path)
.map(BufReader::new)
.map_err(|error| EmbeddedAssetsError::AssetRead {
path: path.to_owned(),
error,
})?;
// entirely read compressed asset into bytes
let bytes = zstd::encode_all(reader, Self::compression_level()).map_err(|error| {
EmbeddedAssetsError::AssetWrite {
path: path.to_owned(),
error,
}
})?;
// get a key to the asset path without the asset directory prefix
let key = path
.strip_prefix(prefix)
.map(AssetKey::from) // format the path for use in assets
.map_err(|_| EmbeddedAssetsError::PrefixInvalid {
prefix: prefix.to_owned(),
path: path.to_owned(),
})?;
Ok((key, (path.display().to_string(), bytes)))
}
}
impl ToTokens for EmbeddedAssets {
fn to_tokens(&self, tokens: &mut TokenStream) {
let mut map = TokenStream::new();
for (key, (original, bytes)) in &self.0 {
let key: &str = key.as_ref();
// add original asset as a compiler dependency, rely on dead code elimination to clean it up
map.append_all(quote!(#key => {
const _: &[u8] = include_bytes!(#original);
&[#(#bytes),*]
},));
}
// we expect phf related items to be in path when generating the path code
tokens.append_all(quote! {
use ::tauri::api::assets::{EmbeddedAssets, phf, phf::phf_map};
static ASSETS: EmbeddedAssets = EmbeddedAssets::from_zstd(phf_map! { #map });
&ASSETS
});
}
}

View File

@@ -0,0 +1,80 @@
pub use context::{context_codegen, ContextData};
use std::{
borrow::Cow,
fs::File,
io::BufReader,
path::{Path, PathBuf},
};
pub use tauri_api::config::Config;
use thiserror::Error;
mod context;
pub mod embedded_assets;
/// Represents all the errors that can happen while reading the config.
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("unable to access current working directory: {0}")]
CurrentDir(std::io::Error),
// this error should be "impossible" because we use std::env::current_dir() - cover it anyways
#[error("Tauri config file has no parent, this shouldn't be possible. file an issue on https://github.com/tauri-apps/tauri - target {0}")]
Parent(PathBuf),
#[error("unable to parse inline TAURI_CONFIG env var: {0}")]
FormatInline(serde_json::Error),
#[error("unable to parse Tauri config file at {path} because {error}")]
Format {
path: PathBuf,
error: serde_json::Error,
},
#[error("unable to read Tauri config file at {path} because {error}")]
Io {
path: PathBuf,
error: std::io::Error,
},
}
/// Get the [`Config`] from the `TAURI_CONFIG` environmental variable, or read from the passed path.
///
/// If the passed path is relative, it should be relative to the current working directory of the
/// compiling crate.
pub fn get_config(path: &Path) -> Result<(Config, PathBuf), ConfigError> {
let path = if path.is_relative() {
let cwd = std::env::current_dir().map_err(ConfigError::CurrentDir)?;
Cow::Owned(cwd.join(path))
} else {
Cow::Borrowed(path)
};
// in the future we may want to find a way to not need the TAURI_CONFIG env var so that
// it is impossible for the content of two separate configs to get mixed up. The chances are
// already unlikely unless the developer goes out of their way to run the cli on a different
// project than the target crate.
let config = if let Ok(env) = std::env::var("TAURI_CONFIG") {
serde_json::from_str(&env).map_err(ConfigError::FormatInline)?
} else {
File::open(&path)
.map_err(|error| ConfigError::Io {
path: path.clone().into_owned(),
error,
})
.map(BufReader::new)
.and_then(|file| {
serde_json::from_reader(file).map_err(|error| ConfigError::Format {
path: path.clone().into_owned(),
error,
})
})?
};
// this should be impossible because of the use of `current_dir()` above, but handle it anyways
let parent = path
.parent()
.map(ToOwned::to_owned)
.ok_or_else(|| ConfigError::Parent(path.into_owned()))?;
Ok((config, parent))
}

View File

@@ -5,7 +5,7 @@
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public",
"tauri": "node ../../../cli/tauri.js/bin/tauri"
"tauri": "node ../../cli/tauri.js/bin/tauri"
},
"devDependencies": {
"@rollup/plugin-commonjs": "17.1.0",
@@ -17,7 +17,7 @@
"svelte": "3.35.0"
},
"dependencies": {
"@tauri-apps/api": "link:../../../api",
"@tauri-apps/api": "link:../../api",
"sirv-cli": "1.0.11"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,17 @@
[package]
name = "api"
version = "0.1.0"
description = "An example Tauri Application showcasing the api"
edition = "2018"
[build-dependencies]
tauri-build = { path = "../../../core/tauri-build" }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = [ "derive" ] }
tauri = { path = "../../../tauri", features =["api-all", "cli"]}
[features]
default = [ "custom-protocol" ]
custom-protocol = [ "tauri/custom-protocol" ]

View File

@@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -12,11 +12,10 @@ struct Reply {
data: String,
}
#[derive(tauri::FromTauriContext)]
struct Context;
fn main() {
tauri::AppBuilder::<Context>::new()
let context = tauri::generate_tauri_context!();
tauri::AppBuilder::default()
.setup(|webview_manager| async move {
let dispatcher = webview_manager.current_webview().await.unwrap();
let dispatcher_ = dispatcher.clone();
@@ -35,7 +34,6 @@ fn main() {
cmd::log_operation,
cmd::perform_request
])
.build()
.unwrap()
.build(context)
.run();
}

View File

@@ -62,8 +62,9 @@
estree-walker "^1.0.1"
picomatch "^2.2.2"
"@tauri-apps/api@link:../../../api":
version "0.1.0"
"@tauri-apps/api@link:../../api":
version "0.0.0"
uid ""
"@types/estree@*":
version "0.0.46"

View File

@@ -1,20 +1,16 @@
workspace = { }
[package]
name = "helloworld"
version = "0.1.0"
description = "A Tauri App"
authors = [ "you" ]
license = ""
repository = ""
default-run = "helloworld"
description = "A very simple Tauri Appplication"
edition = "2018"
build = "src/build.rs"
[build-dependencies]
tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ]}
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = [ "derive" ] }
tauri = { path = "../../..", features =["api-all"]}
tauri = { path = "../../../tauri", features =["api-all"]}
[target."cfg(windows)".build-dependencies]
winres = "0.1"
@@ -22,7 +18,3 @@ winres = "0.1"
[features]
default = [ "custom-protocol" ]
custom-protocol = [ "tauri/custom-protocol" ]
[[bin]]
name = "helloworld"
path = "src/main.rs"

View File

@@ -0,0 +1,4 @@
fn main() {
tauri_build::CodegenContext::default().build();
tauri_build::build();
}

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -3,19 +3,16 @@
windows_subsystem = "windows"
)]
#[derive(tauri::FromTauriContext)]
#[config_path = "examples/helloworld/src-tauri/tauri.conf.json"]
struct Context;
#[tauri::command]
fn my_custom_command(argument: String) {
println!("{}", argument);
}
fn main() {
tauri::AppBuilder::<Context>::new()
let context = tauri::generate_tauri_context!();
tauri::AppBuilder::default()
.invoke_handler(tauri::generate_handler![my_custom_command])
.build()
.unwrap()
.build(context)
.run();
}

332
examples/multiwindow/dist/__tauri.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,18 @@
[package]
name = "multiwindow"
version = "0.1.0"
description = "An example Tauri Multi-Window Application"
edition = "2018"
[build-dependencies]
tauri-build = { path = "../../../core/tauri-build", features = ["codegen"] }
[dependencies]
tauri = { path = "../../../tauri", features =["api-all"]}
[target."cfg(windows)".build-dependencies]
winres = "0.1"
[features]
default = [ "custom-protocol" ]
custom-protocol = [ "tauri/custom-protocol" ]

View File

@@ -0,0 +1,4 @@
fn main() {
tauri_build::CodegenContext::default().build();
tauri_build::build();
}

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Some files were not shown because too many files have changed in this diff Show More