add typescript support (vercel/turbo#370)

picked typescript transform from https://github.com/vercel/turbo-tooling/pull/341

add resolve options context as global resolve config

enable typescript only for next-dev

move emulating logic from environment to resolve options context

Co-authored-by: Leah <8845940+ForsakenHarmony@users.noreply.github.com>
This commit is contained in:
Tobias Koppers 2022-09-16 11:22:37 +02:00 committed by GitHub
parent 86f1831b06
commit 7795fafdc7
4 changed files with 69 additions and 17 deletions

View file

@ -7,6 +7,7 @@ use turbo_tasks_fs::{File, FileContent, FileContentVc, FileSystemPathVc};
use turbopack::{
ecmascript::chunk_group_files_asset::ChunkGroupFilesAsset,
module_options::ModuleOptionsContextVc,
resolve_options_context::ResolveOptionsContextVc,
transition::{Transition, TransitionVc},
ModuleAssetContextVc,
};
@ -45,6 +46,7 @@ pub enum RuntimeReference {
pub struct NextClientTransition {
pub client_environment: EnvironmentVc,
pub client_module_options_context: ModuleOptionsContextVc,
pub client_resolve_options_context: ResolveOptionsContextVc,
pub client_chunking_context: ChunkingContextVc,
pub server_root: FileSystemPathVc,
pub runtime_references: Vec<RuntimeReference>,

View file

@ -1,13 +1,18 @@
use anyhow::{anyhow, Result};
use turbo_tasks::primitives::{BoolVc, StringVc};
use turbo_tasks::{
debug::ValueDebug,
primitives::{BoolVc, StringVc},
};
use turbo_tasks_fs::FileSystemPathVc;
use turbopack::ecmascript::{
chunk::EcmascriptChunkPlaceableVc,
resolve::{apply_cjs_specific_options, cjs_resolve},
use turbopack::{
ecmascript::{
chunk::EcmascriptChunkPlaceableVc,
resolve::{apply_cjs_specific_options, cjs_resolve},
},
resolve_options_context::ResolveOptionsContextVc,
};
use turbopack_core::{
context::AssetContextVc,
environment::EnvironmentVc,
issue::{Issue, IssueSeverity, IssueSeverityVc, IssueVc},
resolve::{parse::RequestVc, ResolveResult},
};
@ -25,20 +30,22 @@ pub fn react_refresh_request() -> RequestVc {
#[turbo_tasks::function]
pub async fn assert_can_resolve_react_refresh(
path: FileSystemPathVc,
environment: EnvironmentVc,
resolve_options_context: ResolveOptionsContextVc,
) -> Result<BoolVc> {
let resolve_options = apply_cjs_specific_options(turbopack::resolve_options(path, environment));
let resolve_options =
apply_cjs_specific_options(turbopack::resolve_options(path, resolve_options_context));
let result = turbopack_core::resolve::resolve(path, react_refresh_request(), resolve_options);
Ok(match &*result.await? {
ResolveResult::Single(_, _) => BoolVc::cell(true),
ResolveResult::Single(_, _) | ResolveResult::Alternatives(_, _) => BoolVc::cell(true),
_ => {
ReactRefreshResolvingIssue {
path,
description: StringVc::cell(
"could not resolve the `@next/react-refresh-utils/dist/runtime` module"
.to_string(),
),
description: StringVc::cell(format!(
"could not resolve the `@next/react-refresh-utils/dist/runtime` \
module\nresolve options: {:?}",
resolve_options.dbg().await?
)),
}
.cell()
.as_issue()
@ -59,6 +66,15 @@ pub async fn resolve_react_refresh(context: AssetContextVc) -> Result<Ecmascript
Err(anyhow!("React Refresh runtime asset is not placeable"))
}
}
ResolveResult::Alternatives(assets, _) if !assets.is_empty() => {
if let Some(placeable) =
EcmascriptChunkPlaceableVc::resolve_from(assets.iter().next().unwrap()).await?
{
Ok(placeable)
} else {
Err(anyhow!("React Refresh runtime asset is not placeable"))
}
}
// The react-refresh-runtime module is not installed.
ResolveResult::Unresolveable(_) => Err(anyhow!(
"could not resolve the `@next/react-refresh-utils/dist/runtime` module"

View file

@ -4,7 +4,8 @@ use anyhow::Result;
use turbo_tasks::{primitives::StringVc, Value};
use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, FileSystemEntryType, FileSystemPathVc};
use turbopack::{
module_options::ModuleOptionsContext, transition::TransitionsByNameVc, ModuleAssetContextVc,
module_options::ModuleOptionsContext, resolve_options_context::ResolveOptionsContext,
transition::TransitionsByNameVc, ModuleAssetContextVc,
};
use turbopack_core::{
chunk::dev::DevChunkingContext,
@ -69,8 +70,16 @@ pub async fn create_server_rendered_source(
)),
Value::new(EnvironmentIntention::Client),
);
let client_resolve_options_context = ResolveOptionsContext {
enable_typescript: true,
enable_react: true,
enable_node_modules: true,
custom_conditions: vec!["development".to_string()],
..Default::default()
}
.cell();
let enable_react_refresh =
*assert_can_resolve_react_refresh(root_path, client_environment).await?;
*assert_can_resolve_react_refresh(root_path, client_resolve_options_context).await?;
let runtime_references = if enable_react_refresh {
vec![
RuntimeReference::Request(react_refresh_request(), root_path),
@ -88,11 +97,14 @@ pub async fn create_server_rendered_source(
let client_module_options_context = ModuleOptionsContext {
enable_react_refresh,
enable_styled_jsx: true,
enable_typescript_transform: true,
..Default::default()
}
.cell();
let next_client_transition = NextClientTransition {
client_chunking_context,
client_module_options_context,
client_resolve_options_context,
client_environment,
server_root: target_root,
runtime_references,
@ -110,13 +122,22 @@ pub async fn create_server_rendered_source(
NodeJsEnvironment {
compile_target: CompileTargetVc::current(),
node_version: 0,
typescript_enabled: false,
}
.into(),
)),
Value::new(EnvironmentIntention::Client),
),
ModuleOptionsContext {
enable_typescript_transform: true,
..Default::default()
}
.cell(),
ResolveOptionsContext {
enable_typescript: true,
enable_react: true,
enable_node_modules: true,
enable_node_native_modules: true,
custom_conditions: vec!["development".to_string()],
..Default::default()
}
.cell(),

View file

@ -6,6 +6,7 @@ use turbo_tasks_fs::{FileSystemPathVc, FileSystemVc};
use turbopack::{
ecmascript::{chunk::EcmascriptChunkPlaceablesVc, EcmascriptModuleAssetVc},
module_options::ModuleOptionsContext,
resolve_options_context::ResolveOptionsContext,
transition::TransitionsByNameVc,
ModuleAssetContextVc,
};
@ -46,7 +47,16 @@ pub async fn create_web_entry_source(
Value::new(EnvironmentIntention::Client),
);
let enable_react_refresh = *assert_can_resolve_react_refresh(root, environment).await?;
let resolve_options_context = ResolveOptionsContext {
enable_typescript: true,
enable_react: true,
enable_node_modules: true,
custom_conditions: vec!["development".to_string()],
..Default::default()
}
.cell();
let enable_react_refresh =
*assert_can_resolve_react_refresh(root, resolve_options_context).await?;
let context: AssetContextVc = ModuleAssetContextVc::new(
TransitionsByNameVc::cell(HashMap::new()),
@ -58,8 +68,11 @@ pub async fn create_web_entry_source(
// the modules.
enable_react_refresh,
enable_styled_jsx: true,
enable_typescript_transform: true,
..Default::default()
}
.into(),
.cell(),
resolve_options_context,
)
.into();