loaders: use pre-compiled loader-runner distributed with Next.js (vercel/turbo#3823)
The benefit of this depends on https://github.com/vercel/next.js/pull/45962, but it remains compatible with apps including `loader-runner`. This first attempts to require `loader-runner` from the app's installed version of Next.js, falling back to requiring the package directly. We should probably eventually remove this fallback once all compatible versions of Next.js include the precompiled version, as that has a more predictable version of the package. Test Plan: Linked a local copy of Next.js including https://github.com/vercel/next.js/pull/45962 to an app without `loader-runner` that uses loaders and verified loaders ran.
This commit is contained in:
parent
90675f2a7c
commit
166b3d62cc
4 changed files with 51 additions and 18 deletions
|
@ -1,4 +1,5 @@
|
|||
use anyhow::Result;
|
||||
use turbo_tasks::primitives::StringVc;
|
||||
use turbo_tasks_fs::FileSystemPathVc;
|
||||
use turbopack_core::resolve::options::{ImportMapping, ImportMappingVc};
|
||||
|
||||
|
@ -19,3 +20,17 @@ pub async fn get_postcss_package_mapping(
|
|||
])
|
||||
.cell())
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn get_external_next_compiled_package_mapping(
|
||||
package_name: StringVc,
|
||||
) -> Result<ImportMappingVc> {
|
||||
Ok(
|
||||
ImportMapping::Alternatives(vec![ImportMapping::External(Some(format!(
|
||||
"next/dist/compiled/{}",
|
||||
&*package_name.await?
|
||||
)))
|
||||
.into()])
|
||||
.cell(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,13 +2,13 @@ use core::{default::Default, result::Result::Ok};
|
|||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use turbo_tasks::Value;
|
||||
use turbo_tasks::{primitives::StringVc, Value};
|
||||
use turbo_tasks_env::ProcessEnvVc;
|
||||
use turbo_tasks_fs::FileSystemPathVc;
|
||||
use turbopack::{
|
||||
module_options::{
|
||||
module_options_context::{ModuleOptionsContext, ModuleOptionsContextVc},
|
||||
PostCssTransformOptions,
|
||||
PostCssTransformOptions, WebpackLoadersOptions,
|
||||
},
|
||||
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
|
||||
transition::TransitionsByNameVc,
|
||||
|
@ -28,7 +28,7 @@ use super::transforms::get_next_client_transforms_rules;
|
|||
use crate::{
|
||||
embed_js::attached_next_js_package_path,
|
||||
env::env_for_js,
|
||||
next_build::get_postcss_package_mapping,
|
||||
next_build::{get_external_next_compiled_package_mapping, get_postcss_package_mapping},
|
||||
next_client::runtime_entry::{RuntimeEntriesVc, RuntimeEntry},
|
||||
next_config::NextConfigVc,
|
||||
next_import_map::{
|
||||
|
@ -113,6 +113,16 @@ pub async fn get_client_module_options_context(
|
|||
.await?
|
||||
.is_found();
|
||||
|
||||
let options = &*next_config.webpack_loaders_options().await?;
|
||||
let enable_webpack_loaders = WebpackLoadersOptions {
|
||||
extension_to_loaders: options.clone(),
|
||||
loader_runner_package: Some(get_external_next_compiled_package_mapping(StringVc::cell(
|
||||
"loader-runner".to_owned(),
|
||||
))),
|
||||
placeholder_for_future_extensions: (),
|
||||
}
|
||||
.clone_if();
|
||||
|
||||
let module_options_context = ModuleOptionsContext {
|
||||
preset_env_versions: Some(env),
|
||||
execution_context: Some(execution_context),
|
||||
|
@ -131,7 +141,7 @@ pub async fn get_client_module_options_context(
|
|||
postcss_package: Some(get_postcss_package_mapping(project_path)),
|
||||
..Default::default()
|
||||
}),
|
||||
enable_webpack_loaders: next_config.webpack_loaders_options().await?.clone_if(),
|
||||
enable_webpack_loaders,
|
||||
enable_typescript_transform: true,
|
||||
rules: vec![(
|
||||
foreign_code_context_condition(next_config).await?,
|
||||
|
|
|
@ -9,10 +9,7 @@ use turbo_tasks::{
|
|||
};
|
||||
use turbo_tasks_env::EnvMapVc;
|
||||
use turbo_tasks_fs::json::parse_json_rope_with_source_context;
|
||||
use turbopack::{
|
||||
evaluate_context::node_evaluate_asset_context,
|
||||
module_options::{WebpackLoadersOptions, WebpackLoadersOptionsVc},
|
||||
};
|
||||
use turbopack::evaluate_context::node_evaluate_asset_context;
|
||||
use turbopack_core::{
|
||||
asset::Asset,
|
||||
context::AssetContext,
|
||||
|
@ -446,6 +443,10 @@ pub enum RemoveConsoleConfig {
|
|||
Config { exclude: Option<Vec<String>> },
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[turbo_tasks::value(transparent)]
|
||||
pub struct WebpackExtensionToLoaders(IndexMap<String, WebpackLoaderConfigsVc>);
|
||||
|
||||
#[turbo_tasks::value_impl]
|
||||
impl NextConfigVc {
|
||||
#[turbo_tasks::function]
|
||||
|
@ -500,20 +501,16 @@ impl NextConfigVc {
|
|||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn webpack_loaders_options(self) -> Result<WebpackLoadersOptionsVc> {
|
||||
pub async fn webpack_loaders_options(self) -> Result<WebpackExtensionToLoadersVc> {
|
||||
let this = self.await?;
|
||||
let Some(turbo_loaders) = this.experimental.turbo.as_ref().and_then(|t| t.loaders.as_ref()) else {
|
||||
return Ok(WebpackLoadersOptionsVc::cell(WebpackLoadersOptions::default()));
|
||||
return Ok(WebpackExtensionToLoadersVc::cell(IndexMap::new()));
|
||||
};
|
||||
let mut extension_to_loaders = IndexMap::new();
|
||||
for (ext, loaders) in turbo_loaders {
|
||||
extension_to_loaders.insert(ext.clone(), WebpackLoaderConfigsVc::cell(loaders.clone()));
|
||||
}
|
||||
Ok(WebpackLoadersOptions {
|
||||
extension_to_loaders,
|
||||
..Default::default()
|
||||
}
|
||||
.cell())
|
||||
Ok(WebpackExtensionToLoaders(extension_to_loaders).cell())
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
|
|
|
@ -3,7 +3,10 @@ use turbo_tasks::{primitives::StringVc, Value};
|
|||
use turbo_tasks_env::ProcessEnvVc;
|
||||
use turbo_tasks_fs::FileSystemPathVc;
|
||||
use turbopack::{
|
||||
module_options::{ModuleOptionsContext, ModuleOptionsContextVc, PostCssTransformOptions},
|
||||
module_options::{
|
||||
ModuleOptionsContext, ModuleOptionsContextVc, PostCssTransformOptions,
|
||||
WebpackLoadersOptions,
|
||||
},
|
||||
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
|
||||
};
|
||||
use turbopack_core::{
|
||||
|
@ -20,7 +23,7 @@ use super::{
|
|||
resolve::ExternalCjsModulesResolvePluginVc, transforms::get_next_server_transforms_rules,
|
||||
};
|
||||
use crate::{
|
||||
next_build::get_postcss_package_mapping,
|
||||
next_build::{get_external_next_compiled_package_mapping, get_postcss_package_mapping},
|
||||
next_config::NextConfigVc,
|
||||
next_import_map::{get_next_build_import_map, get_next_server_import_map},
|
||||
util::foreign_code_context_condition,
|
||||
|
@ -173,7 +176,15 @@ pub async fn get_server_module_options_context(
|
|||
postcss_package: Some(get_postcss_package_mapping(project_path)),
|
||||
..Default::default()
|
||||
});
|
||||
let enable_webpack_loaders = next_config.webpack_loaders_options().await?.clone_if();
|
||||
let options = &*next_config.webpack_loaders_options().await?;
|
||||
let enable_webpack_loaders = WebpackLoadersOptions {
|
||||
loader_runner_package: Some(get_external_next_compiled_package_mapping(StringVc::cell(
|
||||
"loader-runner".to_owned(),
|
||||
))),
|
||||
extension_to_loaders: options.clone(),
|
||||
placeholder_for_future_extensions: (),
|
||||
}
|
||||
.clone_if();
|
||||
|
||||
let module_options_context = match ty.into_value() {
|
||||
ServerContextType::Pages { .. } | ServerContextType::PagesData { .. } => {
|
||||
|
|
Loading…
Reference in a new issue