Git Product home page Git Product logo

Comments (20)

gbj avatar gbj commented on May 20, 2024 1

Oh okay yeah it's this:

#[cfg_attr(
any(debug_assertions, feature="ssr"),
::leptos::leptos_dom::tracing::instrument(level = "info", name = #trace_name, skip_all)
)]

Using the tracing::instrument macro requires a root-level tracing dependency that we can't tell to use some other path (like the one reexported from Leptos) instead.

Gating this on the Leptos tracing feature is a breaking change but we're releasing a 0.6 soon so it could be rolled into that.

(In the meantime tracing is a great crate, so either just adding it or running in release mode for a while should work.)

from leptos.

gbj avatar gbj commented on May 20, 2024

I'm sorry, I can't reproduce the issue by starting with one of our starters and removing the tracing dependency. Could you please provide a reproduction, i.e., a minimal GitHub repo, or a complete Cargo.toml and example code. (Please copy and paste rather than screenshotting.)

(And just checking: When you say "see red squiggle," is this just in rust-analyzer or are you getting an error while building, and what is the error?)

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

The red squiggle is rust-analyzer. I will get up a repro. I didn't use a starter.

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Ran cargo build, got same error there as well:

error[E0433]: failed to resolve: use of undeclared crate or module `tracing`
 --> src/components/signup.rs:3:1
  |
3 | #[component]
  | ^^^^^^^^^^^^ use of undeclared crate or module `tracing`

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Upgraded to rust 1.75, build still fails on missing tracing.

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Okay, apparently the issue is with leptos-axum. Adding it triggers the issue

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Cargo.toml:

[package]
name = "leptos-bug"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
leptos = "0.5.4"
# Adding leptos-axum causes component to say missing dependnecy on tracing.
leptos_axum = "0.5.4"

main.rs:

use leptos::{component, view, IntoView};

// When leptos-axum crate is added, #[component] macro errors out about missing tracing dependency unless
// tracing is added at top level
// adding tracing as top-level dep, or removing leptos-axum fixes the issue.
#[component]
fn SignupForm() -> impl IntoView {
    view! {
        <div>
            <h1>{"Hello World"}</h1>
        </div>
    }
}

fn main() {
    println!("Hello, world!");
}

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Hmm, leptos-axum has a hard dependency on tracing, so I don't know if this something that can be fixed in the features system of cargo?

Looking at the Cargo of leptos_axum,

[package]
name = "leptos_axum"
version = { workspace = true }
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"
repository = "https://github.com/leptos-rs/leptos"
description = "Axum integrations for the Leptos web framework."

[dependencies]
axum = { version = "0.6", default-features = false, features = [
	"matched-path",
] }
futures = "0.3"
http = "0.2.11"
hyper = "0.14.23"
# >>> Enabled ssr feature, but not tracing feature? <<<
leptos = { workspace = true, features = ["ssr"] }
leptos_meta = { workspace = true, features = ["ssr"] }
leptos_router = { workspace = true, features = ["ssr"] }
leptos_integration_utils = { workspace = true }
serde_json = "1"
tokio = { version = "1", default-features = false }
parking_lot = "0.12.1"
tokio-util = { version = "0.7.7", features = ["rt"] }
# >>> Hard dep on tracing, not behind feature flag <<<
tracing = "0.1.37"
once_cell = "1.17"
cfg-if = "1.0.0"

[features]
nonce = ["leptos/nonce"]
wasm = []
default = ["tokio/full", "axum/macros"]
experimental-islands = ["leptos_integration_utils/experimental-islands"]

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Hmm, still can't see how this is enabling the tracing feature on leptos itself?

from leptos.

gbj avatar gbj commented on May 20, 2024

Thanks. It's specific to the #[component] macro somewhere.

MRE:

main.rs

use leptos::{component, IntoView};

#[component]
fn SignupForm() -> impl IntoView {}

Cargo.toml

[package]
name = "las"
version = "0.1.0"
edition = "2021"

[dependencies]
leptos = "0.5.4"
leptos_axum = "0.5.4"

cargo check. (Whatever is emitting ::tracing from the component macro is only doing it in debug mode, so cargo check --release is fine.)

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Ahhh

in lib.rs ( but also in many other files)

#[proc_macro]
#[cfg_attr(
    any(debug_assertions, feature = "ssr"),
    tracing::instrument(level = "trace", skip_all,)
)]
pub fn view(tokens: TokenStream) -> TokenStream {

If ssr feature is enabled, which leptos-axum does, then a dependency on the tracing crate is brought in. ssr feature has a hidden dependency on tracing not expressed in the Cargo files.

while the error is shown as originating on the component macro, the actual issue is with the view!() macro. When this macro is expanded in my code, it injects a direct dependency on tracing in the scope of my code, not

Fix is to have ssr feature also turn on tracing, or rework the cfg_attribute. Have not tested. ymmv

#[cfg_attr(
    any(debug_assertions, all(feature = "ssr", feature = "tracing")), // If test build or ssr & tracing enabled
    tracing::instrument(level = "info", skip_all) // then instrument with tracing because we know 
)]
pub fn view(tokens: TokenStream) -> TokenStream {

Though perhaps all usages of cfg_attr referencing ssr should be fixed up?

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Here is the expanded main.rs

Note that the file now has dependencies on tracing.

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use leptos::{component, view, IntoView};
/// Props for the [`SignupForm`] component.
///
///
#[builder(crate_module_path = ::leptos::typed_builder)]
struct SignupFormProps {}
#[automatically_derived]
impl SignupFormProps {
    /**
                Create a builder for building `SignupFormProps`.
                On the builder, call  to set the values of the fields.
                Finally, call `.build()` to create the instance of `SignupFormProps`.
                */
    #[allow(dead_code, clippy::default_trait_access)]
    fn builder() -> SignupFormPropsBuilder<()> {
        SignupFormPropsBuilder {
            fields: (),
            phantom: ::core::default::Default::default(),
        }
    }
}
#[must_use]
#[doc(hidden)]
#[allow(dead_code, non_camel_case_types, non_snake_case)]
struct SignupFormPropsBuilder<TypedBuilderFields = ()> {
    fields: TypedBuilderFields,
    phantom: ::core::marker::PhantomData<()>,
}
#[automatically_derived]
impl<TypedBuilderFields> Clone for SignupFormPropsBuilder<TypedBuilderFields>
where
    TypedBuilderFields: Clone,
{
    #[allow(clippy::default_trait_access)]
    fn clone(&self) -> Self {
        Self {
            fields: self.fields.clone(),
            phantom: ::core::default::Default::default(),
        }
    }
}
#[allow(dead_code, non_camel_case_types, missing_docs)]
#[automatically_derived]
impl SignupFormPropsBuilder<()> {
    #[allow(clippy::default_trait_access, clippy::used_underscore_binding)]
    pub fn build(self) -> SignupFormProps {
        let () = self.fields;
        #[allow(deprecated)] SignupFormProps {}.into()
    }
}
#[allow(missing_docs)]
impl ::leptos::Props for SignupFormProps {
    type Builder = SignupFormPropsBuilder;
    fn builder() -> Self::Builder {
        SignupFormProps::builder()
    }
}
impl ::leptos::DynAttrs for SignupFormProps {
    fn dyn_attrs(mut self, v: Vec<(&'static str, ::leptos::Attribute)>) -> Self {
        self
    }
}
impl ::leptos::IntoView for SignupFormProps {
    fn into_view(self) -> ::leptos::View {
        SignupForm().into_view()
    }
}
///
#[allow(non_snake_case, clippy::too_many_arguments)]
#[allow(clippy::needless_lifetimes)]
#[allow(clippy::let_with_type_underscore)]
fn SignupForm() -> impl IntoView {
    {}
    #[allow(clippy::suspicious_else_formatting)]
    {
        let __tracing_attr_span;
        let __tracing_attr_guard;
        if tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL
            && tracing::Level::INFO <= ::tracing::level_filters::LevelFilter::current()
            || { false }
        {
            __tracing_attr_span = {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite = {
                    static META: ::tracing::Metadata<'static> = {
                        ::tracing_core::metadata::Metadata::new(
                            "<SignupForm />",
                            "leptos_bug",
                            tracing::Level::INFO,
                            ::core::option::Option::Some("src/main.rs"),
                            ::core::option::Option::Some(3u32),
                            ::core::option::Option::Some("leptos_bug"),
                            ::tracing_core::field::FieldSet::new(
                                &[],
                                ::tracing_core::callsite::Identifier(&__CALLSITE),
                            ),
                            ::tracing::metadata::Kind::SPAN,
                        )
                    };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
                let mut interest = ::tracing::subscriber::Interest::never();
                if tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL
                    && tracing::Level::INFO
                        <= ::tracing::level_filters::LevelFilter::current()
                    && {
                        interest = __CALLSITE.interest();
                        !interest.is_never()
                    }
                    && ::tracing::__macro_support::__is_enabled(
                        __CALLSITE.metadata(),
                        interest,
                    )
                {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) })
                } else {
                    let span = ::tracing::__macro_support::__disabled_span(
                        __CALLSITE.metadata(),
                    );
                    {};
                    span
                }
            };
            __tracing_attr_guard = __tracing_attr_span.enter();
        }
        #[warn(clippy::suspicious_else_formatting)]
        {
            #[allow(
                unknown_lints,
                unreachable_code,
                clippy::diverging_sub_expression,
                clippy::let_unit_value,
                clippy::unreachable,
                clippy::let_with_type_underscore,
                clippy::empty_loop
            )]
            if false {
                let __tracing_attr_fake_return: _ = loop {};
                return __tracing_attr_fake_return;
            }
            {
                let span = ::leptos::leptos_dom::tracing::Span::current();
                ::leptos::leptos_dom::Component::new(
                    "SignupForm",
                    move || {
                        #[cfg(debug_assertions)]
                        let _guard = span.entered();
                        __SignupForm()
                    },
                )
            }
        }
    }
}
#[doc(hidden)]
#[allow(non_snake_case, dead_code, clippy::too_many_arguments)]
fn __SignupForm() -> impl IntoView {
    {
        #[allow(unused_braces)]
        {
            let _ = ::leptos::leptos_dom::html::div;
            let _ = ::leptos::leptos_dom::html::div;
            let _ = ::leptos::leptos_dom::html::h1;
            let _ = ::leptos::leptos_dom::html::h1;
            ::leptos::HtmlElement::from_chunks(
                ::leptos::leptos_dom::html::Div::default(),
                [
                    leptos::leptos_dom::html::StringOrView::String(
                        {
                            let res = ::alloc::fmt::format(
                                format_args!(
                                    "<div{0}><h1{1}>Hello World</h1></div>",
                                    ::leptos::leptos_dom::HydrationCtx::peek().map(| id | { let
                                    res = ::alloc::fmt::format(format_args!(" data-hk=\"{0}\"",
                                    id)); res }).unwrap_or_default(),
                                    ::leptos::leptos_dom::HydrationCtx::id().map(| id | { let
                                    res = ::alloc::fmt::format(format_args!(" data-hk=\"{0}\"",
                                    id)); res }).unwrap_or_default()
                                ),
                            );
                            res
                        }
                            .into(),
                    ),
                ],
            )
        }
    }
}
fn main() {
    {
        ::std::io::_print(format_args!("Hello, world!\n"));
    };
}

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Yeah, I plan on using tracing anyways, but it was weird that adding leptos_axum was breaking for me.

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Sorry didn't see your updates in the midst of my analysis. Anyways more info is always better. :D

from leptos.

gbj avatar gbj commented on May 20, 2024

Note that none of the cfg_attr instances you cite above cause an issue, because tracing is already a dependency of leptos, so it's available. It's specifically the fact that the tracing::instrument macro emits ::tracing, which means you need to have it in your Cargo.toml.

I'm honestly not sure why adding leptos_axum or not triggers the issue.

A PR would be welcome to fix this, although as I said I probably can't merge it until 0.6 (in the next few weeks).

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

Leptos_axum enables ssr feature on leptos, ssr via cfg-attr on view macro emits tracing calls when view!() macro is used.

So yes, its the cfg_attr emitting tracing attribute macros on the view macro when ssr is enabled.

from leptos.

DanielJoyce avatar DanielJoyce commented on May 20, 2024

leptos_auxm enables ssr on leptos

leptos ssr feature enables ssr on leptos_macro

leptos_macro, lib.rs:

#[proc_macro]
#[cfg_attr(
    any(debug_assertions, feature = "ssr"), // If Testing, or ssr feature enabled, then emit tracing 
    tracing::instrument(level = "trace", skip_all,)
)]
pub fn view(tokens: TokenStream) -> TokenStream {

from leptos.

NfNitLoop avatar NfNitLoop commented on May 20, 2024

FWIW, I'm running into this issue as well. Yep, it's enabling ssr or debug_assertions that causes the issue. I'm seeing it without leptos axum (I'm currently using actix.)

Glad to see it's already triaged for 0.6! ❤️ And thanks for including the workaround!

from leptos.

NfNitLoop avatar NfNitLoop commented on May 20, 2024

Just wanted to add, this was all working fine for me when I had my #[component]s defined in my top-level lib.rs. It only cropped up when I refactored them into a crate::views::foo module.

Might the fix be as simple as changing the import to ::tracing so that it's always treated as an extern?

from leptos.

gbj avatar gbj commented on May 20, 2024

I was wrong about this one: what I noted was already gated on the tracing feature on leptos, but that was being enabled accidentally by leptos_meta, which is imported by leptos_axum.

I believe #2211 fixes this (or at least it does in the repro above).

from leptos.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.