Skip to content

Commit

Permalink
feat(rspack_core): configurable tsconfig project references (#4290)
Browse files Browse the repository at this point in the history
closes #4211
  • Loading branch information
Boshen authored Oct 10, 2023
1 parent b29483a commit c0965f1
Show file tree
Hide file tree
Showing 32 changed files with 263 additions and 24 deletions.
30 changes: 15 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -957,14 +957,20 @@ export interface RawResolveOptions {
alias?: Record<string, Array<string | false>>
fallback?: Record<string, Array<string | false>>
symlinks?: boolean
tsConfigPath?: string
tsconfig?: RawResolveTsconfigOptions
modules?: Array<string>
byDependency?: Record<string, RawResolveOptions>
fullySpecified?: boolean
exportsFields?: Array<string>
extensionAlias?: Record<string, Array<string>>
}

export interface RawResolveTsconfigOptions {
configFile: string
referencesType: "auto" | "manual" | "disabled"
references?: Array<string>
}

export interface RawRspackFuture {
newResolver: boolean
newTreeshaking: boolean
Expand Down
43 changes: 39 additions & 4 deletions crates/rspack_binding_options/src/options/raw_resolve.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
use std::collections::HashMap;
use std::{collections::HashMap, path::PathBuf};

use napi_derive::napi;
use rspack_core::{Alias, AliasMap, ByDependency, DependencyCategory, Resolve};
use rspack_core::{
Alias, AliasMap, ByDependency, DependencyCategory, Resolve, TsconfigOptions, TsconfigReferences,
};
use serde::Deserialize;

pub type AliasValue = serde_json::Value;

type RawAliasOption = HashMap<String, Vec<AliasValue>>;

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[napi(object)]
pub struct RawResolveTsconfigOptions {
pub config_file: String,
#[napi(ts_type = r#""auto" | "manual" | "disabled""#)]
pub references_type: String,
pub references: Option<Vec<String>>,
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[napi(object)]
Expand All @@ -24,7 +37,7 @@ pub struct RawResolveOptions {
#[napi(ts_type = "Record<string, Array<string | false>>")]
pub fallback: Option<RawAliasOption>,
pub symlinks: Option<bool>,
pub ts_config_path: Option<String>,
pub tsconfig: Option<RawResolveTsconfigOptions>,
pub modules: Option<Vec<String>>,
pub by_dependency: Option<HashMap<String, RawResolveOptions>>,
pub fully_specified: Option<bool>,
Expand Down Expand Up @@ -82,7 +95,10 @@ impl TryFrom<RawResolveOptions> for Resolve {
let alias = normalize_alias(value.alias)?;
let fallback = normalize_alias(value.fallback)?;
let modules = value.modules;
let tsconfig = value.ts_config_path.map(std::path::PathBuf::from);
let tsconfig = match value.tsconfig {
Some(config) => Some(TsconfigOptions::try_from(config)?),
None => None,
};
let by_dependency = value
.by_dependency
.map(|i| {
Expand Down Expand Up @@ -117,3 +133,22 @@ impl TryFrom<RawResolveOptions> for Resolve {
})
}
}

impl TryFrom<RawResolveTsconfigOptions> for TsconfigOptions {
type Error = rspack_error::Error;
fn try_from(value: RawResolveTsconfigOptions) -> Result<Self, Self::Error> {
let references = match value.references_type.as_str() {
"manual" => TsconfigReferences::Paths(value.references.unwrap_or_default().into_iter().map(PathBuf::from).collect()),
"auto" => TsconfigReferences::Auto,
"disabled" => TsconfigReferences::Disabled,
_ => panic!(
"Failed to resolve the references type {}. Expected type is `auto`, `manual` or `disabled`.",
value.references_type
)
};
Ok(TsconfigOptions {
config_file: PathBuf::from(value.config_file),
references,
})
}
}
2 changes: 1 addition & 1 deletion crates/rspack_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ itertools = { workspace = true }
mime_guess = { workspace = true }
nodejs-resolver = { version = "0.1.0" }
once_cell = { workspace = true }
oxc_resolver = { version = "0.2.0", features = ["tracing-subscriber"] }
oxc_resolver = { version = "0.3.1", features = ["tracing-subscriber"] }
paste = { workspace = true }
petgraph = { version = "0.6.3", features = ["serde-1"] }
rayon = { workspace = true }
Expand Down
45 changes: 44 additions & 1 deletion crates/rspack_core/src/options/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct Resolve {
/// fields are written.
pub condition_names: Option<Vec<String>>,
/// the path of tsconfig.
pub tsconfig: Option<PathBuf>,
pub tsconfig: Option<TsconfigOptions>,
/// A list of directories to resolve modules from, can be absolute path or folder name.
/// Default is `["node_modules"]`
pub modules: Option<Vec<String>>,
Expand All @@ -54,6 +54,49 @@ pub struct Resolve {
pub by_dependency: Option<ByDependency>,
}

/// Tsconfig Options
///
/// Derived from [tsconfig-paths-webpack-plugin](https://github.com/dividab/tsconfig-paths-webpack-plugin#options)
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct TsconfigOptions {
/// Allows you to specify where to find the TypeScript configuration file.
/// You may provide
/// * a relative path to the configuration file. It will be resolved relative to cwd.
/// * an absolute path to the configuration file.
pub config_file: PathBuf,

/// Support for Typescript Project References.
pub references: TsconfigReferences,
}

impl From<TsconfigOptions> for oxc_resolver::TsconfigOptions {
fn from(val: TsconfigOptions) -> Self {
oxc_resolver::TsconfigOptions {
config_file: val.config_file,
references: val.references.into(),
}
}
}

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum TsconfigReferences {
Disabled,
/// Use the `references` field from tsconfig read from `config_file`.
Auto,
/// Manually provided relative or absolute path.
Paths(Vec<PathBuf>),
}

impl From<TsconfigReferences> for oxc_resolver::TsconfigReferences {
fn from(val: TsconfigReferences) -> Self {
match val {
TsconfigReferences::Disabled => oxc_resolver::TsconfigReferences::Disabled,
TsconfigReferences::Auto => oxc_resolver::TsconfigReferences::Auto,
TsconfigReferences::Paths(paths) => oxc_resolver::TsconfigReferences::Paths(paths),
}
}
}

impl Resolve {
pub fn merge_by_dependency(mut self, dependency_type: DependencyCategory) -> Self {
let by_dependency = self
Expand Down
4 changes: 2 additions & 2 deletions crates/rspack_core/src/resolver/resolver_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ fn to_nodejs_resolver_options(
dependency_type: DependencyCategory,
) -> nodejs_resolver::Options {
let options = options.merge_by_dependency(dependency_type);
let tsconfig = options.tsconfig;
let tsconfig = options.tsconfig.map(|c| c.config_file);
let enforce_extension = nodejs_resolver::EnforceExtension::Auto;
let external_cache = Some(cache);
let description_file = String::from("package.json");
Expand Down Expand Up @@ -278,7 +278,7 @@ fn to_oxc_resolver_options(
dependency_type: DependencyCategory,
) -> oxc_resolver::ResolveOptions {
let options = options.merge_by_dependency(dependency_type);
let tsconfig = options.tsconfig;
let tsconfig = options.tsconfig.map(|c| c.into());
let enforce_extension = oxc_resolver::EnforceExtension::Auto;
let description_files = vec!["package.json".to_string()];
let extensions = options.extensions.unwrap_or_else(|| {
Expand Down
10 changes: 10 additions & 0 deletions packages/rspack/src/config/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ function getRawResolveByDependency(
}

function getRawResolve(resolve: Resolve): RawOptions["resolve"] {
let references = resolve.tsConfig?.references;
let tsconfigConfigFile = resolve.tsConfigPath ?? resolve.tsConfig?.configFile;
return {
...resolve,
alias: getRawAlias(resolve.alias),
Expand All @@ -158,6 +160,14 @@ function getRawResolve(resolve: Resolve): RawOptions["resolve"] {
string,
Array<string>
>,
tsconfig: tsconfigConfigFile
? {
configFile: tsconfigConfigFile,
referencesType:
references == "auto" ? "auto" : references ? "manual" : "disabled",
references: references == "auto" ? undefined : references
}
: undefined,
byDependency: getRawResolveByDependency(resolve.byDependency)
};
}
Expand Down
8 changes: 8 additions & 0 deletions packages/rspack/src/config/zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,13 @@ const resolveAlias = z.record(
);
export type ResolveAlias = z.infer<typeof resolveAlias>;

const resolveTsconfig = z.strictObject({
configFile: z.string(),
references: z.array(z.string()).or(z.literal("auto")).optional()
});

export type ResolveTsconfig = z.infer<typeof resolveTsconfig>;

const baseResolveOptions = z.strictObject({
alias: resolveAlias.optional(),
/**
Expand All @@ -324,6 +331,7 @@ const baseResolveOptions = z.strictObject({
modules: z.array(z.string()).optional(),
preferRelative: z.boolean().optional(),
tsConfigPath: z.string().optional(),
tsConfig: resolveTsconfig.optional(),
fullySpecified: z.boolean().optional(),
exportsFields: z.array(z.string()).optional(),
extensionAlias: z.record(z.string().or(z.array(z.string()))).optional()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { a } from "./project_a/src/index";
import { b } from "./project_b/src/index";
// import { c } from './project_c/index'

it("should import the referenced alias", () => {
expect(a).toEqual("a");
expect(b).toEqual("b");
// expect(c).toEqual("c");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"composite": true,
"baseUrl": "./src",
"paths": {
"@/*": ["./aliased/*"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const a = "a";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { a } from "@/index";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const b = "b";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { b } from "@/index";
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"composite": true,
"baseUrl": "./src",
"paths": {
"@/*": ["./aliased/*"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { c } from "@/index";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const c = "c";
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"composite": true,
"paths": {
"@/*": ["./src/aliased/*"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"references": [
{
"path": "./project_a/conf.json"
},
{
"path": "./project_b"
},
{
"path": "./project_c/tsconfig.json"
}
]
}
Loading

0 comments on commit c0965f1

Please sign in to comment.