Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rspack_core): configurable tsconfig project references #4290

Merged
merged 1 commit into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(),
chenjiahan marked this conversation as resolved.
Show resolved Hide resolved
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
Loading