Repository: vercel/next.js
File: turbopack/crates/turbopack-node/src/transforms/webpack.rs (Rust)

Code before:
                        .encode(file_content.content().to_bytes()),
                ),
            )))),
        };
        let evaluate_context = transform.evaluate_context;

        let webpack_loaders_executor = webpack_loaders_executor(*evaluate_context).module();

        let entries = get_evaluate_entries(webpack_loaders_executor, *evaluate_context, None)
            .to_resolved()
            .await?;

        let module_graph = ModuleGraph::from_modules(entries.graph_entries(), false, false)
            .to_resolved()
            .await?;

        let resource_fs_path = this.source.ident().path().await?;
        let Some(resource_path) = project_path.get_relative_path_to(&resource_fs_path) else {
            bail!(format!(
                "Resource path \"{}\" need to be on project filesystem \"{}\"",
                resource_fs_path, project_path
            ));
        };
        let loaders = transform.loaders.await?;

        let span = tracing::info_span!(
            "webpack loader",
            name = display(ReadRef::<WebpackLoaderItems>::as_raw_ref(&loaders))
        );
        let config_value = async {
            evaluate_webpack_loader(WebpackLoaderContext {
                entries,
                cwd: project_path.clone(),
                env: *env,
                context_source_for_issue: this.source,
                chunking_context: *chunking_context,
                module_graph,
                resolve_options_context: Some(transform.resolve_options_context),
                args: vec![
                    ResolvedVc::cell(content),
                    // We need to pass the query string to the loader
                    ResolvedVc::cell(resource_path.to_string().into()),
                    ResolvedVc::cell(this.source.ident().await?.query.to_string().into()),
                    ResolvedVc::cell(json!(*loaders)),
                    ResolvedVc::cell(transform.source_maps.into()),
                ],
                additional_invalidation: Completion::immutable().to_resolved().await?,
            })
            .await
        }
        .instrument(span)

Review comment (suggestion):
Could you warp the whole `process` method body with the span since it's all related to the webpack loader.

Code after:
                cwd: project_path.clone(),
                env: *env,
                context_source_for_issue: self.source,
                chunking_context: *chunking_context,
                module_graph,
                resolve_options_context: Some(transform.resolve_options_context),
                args: vec![
                    ResolvedVc::cell(content),
                    // We need to pass the query string to the loader
                    ResolvedVc::cell(resource_path.to_string().into()),
                    ResolvedVc::cell(self.source.ident().await?.query.to_string().into()),
                    ResolvedVc::cell(json!(*loaders)),
                    ResolvedVc::cell(transform.source_maps.into()),
                ],
                additional_invalidation: Completion::immutable().to_resolved().await?,
            })
            .await?;

            let Some(val) = &*config_value else {
                // An error happened, which has already been converted into an issue.
                return Ok(ProcessWebpackLoadersResult {
                    content: AssetContent::File(FileContent::NotFound.resolved_cell())
                        .resolved_cell(),
                    assets: Vec::new(),
                    source_map: FileContent::NotFound.resolved_cell(),
                }
                .cell());
            };
            let processed: WebpackLoadersProcessingResult = parse_json_with_source_context(val)
                .context(
                    "Unable to deserializate response from webpack loaders transform operation",
                )?;

            // handle SourceMap
            let source_map = if !transform.source_maps {
                None
            } else {
                processed
                    .map
                    .map(|source_map| Rope::from(source_map.into_owned()))
            };
            let source_map =
                resolve_source_map_sources(source_map.as_ref(), &resource_fs_path).await?;

            let file = match processed.source {
                Either::Left(str) => File::from(str),
                Either::Right(bytes) => File::from(bytes.binary),
            };
            let assets = emitted_assets_to_virtual_sources(processed.assets).await?;

            let content =