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

chore: pass defineEnv from next.js to rust directly #56216

Merged
merged 12 commits into from
Oct 3, 2023
1 change: 0 additions & 1 deletion Cargo.lock

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

93 changes: 90 additions & 3 deletions packages/next-swc/crates/napi/src/next_api/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use napi::{
JsFunction, Status,
};
use next_api::{
project::{Middleware, ProjectContainer, ProjectOptions},
project::{DefineEnv, Middleware, PartialProjectOptions, ProjectContainer, ProjectOptions},
route::{Endpoint, Route},
};
use next_core::tracing_presets::{
Expand Down Expand Up @@ -44,6 +44,7 @@ use super::{
use crate::register;

#[napi(object)]
#[derive(Clone, Debug)]
pub struct NapiEnvVar {
pub name: String,
pub value: String,
Expand Down Expand Up @@ -74,10 +75,56 @@ pub struct NapiProjectOptions {
/// A map of environment variables to use when compiling code.
pub env: Vec<NapiEnvVar>,

/// A map of environment variables which should get injected at compile
/// time.
pub define_env: NapiDefineEnv,

/// The address of the dev server.
pub server_addr: String,
}

/// [NapiProjectOptions] with all fields optional.
#[napi(object)]
pub struct NapiPartialProjectOptions {
/// A root path from which all files must be nested under. Trying to access
/// a file outside this root will fail. Think of this as a chroot.
pub root_path: Option<String>,

/// A path inside the root_path which contains the app/pages directories.
pub project_path: Option<String>,

/// next.config's distDir. Project initialization occurs eariler than
/// deserializing next.config, so passing it as separate option.
pub dist_dir: Option<Option<String>>,

/// Whether to watch he filesystem for file changes.
pub watch: Option<bool>,

/// The contents of next.config.js, serialized to JSON.
pub next_config: Option<String>,

/// The contents of ts/config read by load-jsconfig, serialized to JSON.
pub js_config: Option<String>,

/// A map of environment variables to use when compiling code.
pub env: Option<Vec<NapiEnvVar>>,

/// A map of environment variables which should get injected at compile
/// time.
pub define_env: Option<NapiDefineEnv>,

/// The address of the dev server.
pub server_addr: Option<String>,
}

#[napi(object)]
#[derive(Clone, Debug)]
pub struct NapiDefineEnv {
pub client: Vec<NapiEnvVar>,
pub edge: Vec<NapiEnvVar>,
pub nodejs: Vec<NapiEnvVar>,
}

#[napi(object)]
pub struct NapiTurboEngineOptions {
/// An upper bound of memory that turbopack will attempt to stay under.
Expand All @@ -95,13 +142,53 @@ impl From<NapiProjectOptions> for ProjectOptions {
env: val
.env
.into_iter()
.map(|NapiEnvVar { name, value }| (name, value))
.map(|var| (var.name, var.value))
.collect(),
define_env: val.define_env.into(),
server_addr: val.server_addr,
}
}
}

impl From<NapiPartialProjectOptions> for PartialProjectOptions {
fn from(val: NapiPartialProjectOptions) -> Self {
PartialProjectOptions {
root_path: val.root_path,
project_path: val.project_path,
watch: val.watch,
next_config: val.next_config,
js_config: val.js_config,
env: val
.env
.map(|env| env.into_iter().map(|var| (var.name, var.value)).collect()),
define_env: val.define_env.map(|env| env.into()),
server_addr: val.server_addr,
}
}
}

impl From<NapiDefineEnv> for DefineEnv {
fn from(val: NapiDefineEnv) -> Self {
DefineEnv {
client: val
.client
.into_iter()
.map(|var| (var.name, var.value))
.collect(),
edge: val
.edge
.into_iter()
.map(|var| (var.name, var.value))
.collect(),
nodejs: val
.nodejs
.into_iter()
.map(|var| (var.name, var.value))
.collect(),
}
}
}

pub struct ProjectInstance {
turbo_tasks: Arc<TurboTasks<MemoryBackend>>,
container: Vc<ProjectContainer>,
Expand Down Expand Up @@ -190,7 +277,7 @@ pub async fn project_new(
#[napi(ts_return_type = "{ __napiType: \"Project\" }")]
pub async fn project_update(
#[napi(ts_arg_type = "{ __napiType: \"Project\" }")] project: External<ProjectInstance>,
options: NapiProjectOptions,
options: NapiPartialProjectOptions,
) -> napi::Result<()> {
let turbo_tasks = project.turbo_tasks.clone();
let options = options.into();
Expand Down
30 changes: 28 additions & 2 deletions packages/next-swc/crates/napi/src/turbopack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ use std::{
use anyhow::Context;
use napi::bindgen_prelude::*;
use next_build::{
build as turbo_next_build, build_options::BuildContext, BuildOptions as NextBuildOptions,
build as turbo_next_build,
build_options::{BuildContext, DefineEnv},
BuildOptions as NextBuildOptions,
};
use next_core::next_config::{Rewrite, Rewrites, RouteHas};

use crate::util::MapErr;
use crate::{next_api::project::NapiDefineEnv, util::MapErr};

#[napi(object, object_to_js = false)]
#[derive(Debug)]
Expand Down Expand Up @@ -38,6 +40,7 @@ pub struct NextBuildContext {
// TODO(alexkirsz) These are used to generate route types.
// pub original_rewrites: Option<Rewrites>,
// pub original_redirects: Option<Vec<Redirect>>,
pub define_env: NapiDefineEnv,
}

impl TryFrom<NextBuildContext> for NextBuildOptions {
Expand All @@ -62,10 +65,33 @@ impl TryFrom<NextBuildContext> for NextBuildOptions {
.context("NextBuildContext must provide rewrites")?
.into(),
}),
define_env: value.define_env.into(),
})
}
}

impl From<NapiDefineEnv> for DefineEnv {
fn from(val: NapiDefineEnv) -> Self {
DefineEnv {
client: val
.client
.into_iter()
.map(|var| (var.name, var.value))
.collect(),
edge: val
.edge
.into_iter()
.map(|var| (var.name, var.value))
.collect(),
nodejs: val
.nodejs
.into_iter()
.map(|var| (var.name, var.value))
.collect(),
}
}
}

/// Keep in sync with [`next_core::next_config::Rewrites`]
#[napi(object, object_to_js = false)]
#[derive(Debug)]
Expand Down
6 changes: 0 additions & 6 deletions packages/next-swc/crates/next-api/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,13 +295,8 @@ impl AppProject {
async fn runtime_entries(self: Vc<Self>) -> Result<Vc<RuntimeEntries>> {
let this = self.await?;
Ok(get_server_runtime_entries(
self.project().project_path(),
// TODO(alexkirsz) Should we pass env here or EnvMap::empty, as is done in
// app_source?
self.project().env(),
Value::new(self.rsc_ty()),
this.mode,
self.project().next_config(),
))
}

Expand Down Expand Up @@ -330,7 +325,6 @@ impl AppProject {
let this = self.await?;
Ok(get_client_runtime_entries(
self.project().project_path(),
self.client_env(),
Value::new(self.client_ty()),
this.mode,
self.project().next_config(),
Expand Down
3 changes: 0 additions & 3 deletions packages/next-swc/crates/next-api/src/middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,8 @@ impl MiddlewareEndpoint {
);

let mut evaluatable_assets = get_server_runtime_entries(
self.project.project_path(),
self.project.env(),
Value::new(ServerContextType::Middleware),
NextMode::Development,
self.project.next_config(),
)
.resolve_entries(self.context)
.await?
Expand Down
7 changes: 0 additions & 7 deletions packages/next-swc/crates/next-api/src/pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,6 @@ impl PagesProject {
let this = self.await?;
let client_runtime_entries = get_client_runtime_entries(
self.project().project_path(),
self.project().env(),
Value::new(ClientContextType::Pages {
pages_dir: self.pages_dir(),
}),
Expand All @@ -421,27 +420,21 @@ impl PagesProject {
async fn runtime_entries(self: Vc<Self>) -> Result<Vc<RuntimeEntries>> {
let this = self.await?;
Ok(get_server_runtime_entries(
self.project().project_path(),
self.project().env(),
Value::new(ServerContextType::Pages {
pages_dir: self.pages_dir(),
}),
this.mode,
self.project().next_config(),
))
}

#[turbo_tasks::function]
async fn data_runtime_entries(self: Vc<Self>) -> Result<Vc<RuntimeEntries>> {
let this = self.await?;
Ok(get_server_runtime_entries(
self.project().project_path(),
self.project().env(),
Value::new(ServerContextType::PagesData {
pages_dir: self.pages_dir(),
}),
this.mode,
self.project().next_config(),
))
}

Expand Down
Loading
Loading