PostCSS support in next-dev (vercel/turbo#3065)
This adds the ability to add Source transforms on assets, which modify the source code of an asset before parsing. This adds postcss via node.js as first source transform. Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
This commit is contained in:
parent
df7fa75b04
commit
78abb7e5d3
25 changed files with 414 additions and 101 deletions
|
@ -1,9 +1,11 @@
|
||||||
const loadConfig = require("next/dist/server/config").default;
|
import loadConfig from "next/dist/server/config";
|
||||||
const { PHASE_DEVELOPMENT_SERVER } = require("next/dist/shared/lib/constants");
|
import { PHASE_DEVELOPMENT_SERVER } from "next/dist/shared/lib/constants";
|
||||||
|
|
||||||
module.exports = (async () => {
|
const loadNextConfig = async () => {
|
||||||
const nextConfig = await loadConfig(PHASE_DEVELOPMENT_SERVER, process.cwd());
|
const nextConfig = await loadConfig(PHASE_DEVELOPMENT_SERVER, process.cwd());
|
||||||
nextConfig.rewrites = await nextConfig.rewrites?.();
|
nextConfig.rewrites = await nextConfig.rewrites?.();
|
||||||
nextConfig.redirects = await nextConfig.redirects?.();
|
nextConfig.redirects = await nextConfig.redirects?.();
|
||||||
return nextConfig;
|
return nextConfig;
|
||||||
})();
|
};
|
||||||
|
|
||||||
|
export { loadNextConfig as default };
|
||||||
|
|
|
@ -35,9 +35,8 @@ use turbopack_ecmascript::{
|
||||||
};
|
};
|
||||||
use turbopack_env::ProcessEnvAssetVc;
|
use turbopack_env::ProcessEnvAssetVc;
|
||||||
use turbopack_node::{
|
use turbopack_node::{
|
||||||
create_node_rendered_source,
|
execution_context::ExecutionContextVc, render::rendered_source::create_node_rendered_source,
|
||||||
node_entry::{NodeRenderingEntry, NodeRenderingEntryVc},
|
NodeEntry, NodeEntryVc, NodeRenderingEntry, NodeRenderingEntryVc,
|
||||||
NodeEntry, NodeEntryVc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -69,21 +68,22 @@ use crate::{
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
fn next_client_chunks_transition(
|
fn next_client_chunks_transition(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
app_dir: FileSystemPathVc,
|
app_dir: FileSystemPathVc,
|
||||||
server_root: FileSystemPathVc,
|
server_root: FileSystemPathVc,
|
||||||
browserslist_query: &str,
|
browserslist_query: &str,
|
||||||
) -> TransitionVc {
|
) -> TransitionVc {
|
||||||
let ty = Value::new(ContextType::App { app_dir });
|
let ty = Value::new(ContextType::App { app_dir });
|
||||||
let client_chunking_context = get_client_chunking_context(project_root, server_root, ty);
|
let client_chunking_context = get_client_chunking_context(project_path, server_root, ty);
|
||||||
let client_environment = get_client_environment(browserslist_query);
|
let client_environment = get_client_environment(browserslist_query);
|
||||||
|
|
||||||
let client_module_options_context =
|
let client_module_options_context =
|
||||||
get_client_module_options_context(project_root, client_environment, ty);
|
get_client_module_options_context(project_path, execution_context, client_environment, ty);
|
||||||
NextClientChunksTransition {
|
NextClientChunksTransition {
|
||||||
client_chunking_context,
|
client_chunking_context,
|
||||||
client_module_options_context,
|
client_module_options_context,
|
||||||
client_resolve_options_context: get_client_resolve_options_context(project_root, ty),
|
client_resolve_options_context: get_client_resolve_options_context(project_path, ty),
|
||||||
client_environment,
|
client_environment,
|
||||||
server_root,
|
server_root,
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,8 @@ fn next_client_chunks_transition(
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
async fn next_client_transition(
|
async fn next_client_transition(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
server_root: FileSystemPathVc,
|
server_root: FileSystemPathVc,
|
||||||
app_dir: FileSystemPathVc,
|
app_dir: FileSystemPathVc,
|
||||||
env: ProcessEnvVc,
|
env: ProcessEnvVc,
|
||||||
|
@ -101,12 +102,12 @@ async fn next_client_transition(
|
||||||
next_config: NextConfigVc,
|
next_config: NextConfigVc,
|
||||||
) -> Result<TransitionVc> {
|
) -> Result<TransitionVc> {
|
||||||
let ty = Value::new(ContextType::App { app_dir });
|
let ty = Value::new(ContextType::App { app_dir });
|
||||||
let client_chunking_context = get_client_chunking_context(project_root, server_root, ty);
|
let client_chunking_context = get_client_chunking_context(project_path, server_root, ty);
|
||||||
let client_environment = get_client_environment(browserslist_query);
|
let client_environment = get_client_environment(browserslist_query);
|
||||||
let client_module_options_context =
|
let client_module_options_context =
|
||||||
get_client_module_options_context(project_root, client_environment, ty);
|
get_client_module_options_context(project_path, execution_context, client_environment, ty);
|
||||||
let client_runtime_entries = get_client_runtime_entries(project_root, env, ty, next_config);
|
let client_runtime_entries = get_client_runtime_entries(project_path, env, ty, next_config);
|
||||||
let client_resolve_options_context = get_client_resolve_options_context(project_root, ty);
|
let client_resolve_options_context = get_client_resolve_options_context(project_path, ty);
|
||||||
|
|
||||||
Ok(NextClientTransition {
|
Ok(NextClientTransition {
|
||||||
is_app: true,
|
is_app: true,
|
||||||
|
@ -123,16 +124,21 @@ async fn next_client_transition(
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
fn next_ssr_client_module_transition(
|
fn next_ssr_client_module_transition(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
app_dir: FileSystemPathVc,
|
app_dir: FileSystemPathVc,
|
||||||
process_env: ProcessEnvVc,
|
process_env: ProcessEnvVc,
|
||||||
next_config: NextConfigVc,
|
next_config: NextConfigVc,
|
||||||
) -> TransitionVc {
|
) -> TransitionVc {
|
||||||
let ty = Value::new(ServerContextType::AppSSR { app_dir });
|
let ty = Value::new(ServerContextType::AppSSR { app_dir });
|
||||||
NextSSRClientModuleTransition {
|
NextSSRClientModuleTransition {
|
||||||
ssr_module_options_context: get_server_module_options_context(ty),
|
ssr_module_options_context: get_server_module_options_context(
|
||||||
|
project_path,
|
||||||
|
execution_context,
|
||||||
|
ty,
|
||||||
|
),
|
||||||
ssr_resolve_options_context: get_server_resolve_options_context(
|
ssr_resolve_options_context: get_server_resolve_options_context(
|
||||||
project_root,
|
project_path,
|
||||||
ty,
|
ty,
|
||||||
next_config,
|
next_config,
|
||||||
),
|
),
|
||||||
|
@ -144,7 +150,8 @@ fn next_ssr_client_module_transition(
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
fn next_layout_entry_transition(
|
fn next_layout_entry_transition(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
app_dir: FileSystemPathVc,
|
app_dir: FileSystemPathVc,
|
||||||
server_root: FileSystemPathVc,
|
server_root: FileSystemPathVc,
|
||||||
process_env: ProcessEnvVc,
|
process_env: ProcessEnvVc,
|
||||||
|
@ -153,8 +160,9 @@ fn next_layout_entry_transition(
|
||||||
let ty = Value::new(ServerContextType::AppRSC { app_dir });
|
let ty = Value::new(ServerContextType::AppRSC { app_dir });
|
||||||
let rsc_environment = get_server_environment(ty, process_env);
|
let rsc_environment = get_server_environment(ty, process_env);
|
||||||
let rsc_resolve_options_context =
|
let rsc_resolve_options_context =
|
||||||
get_server_resolve_options_context(project_root, ty, next_config);
|
get_server_resolve_options_context(project_path, ty, next_config);
|
||||||
let rsc_module_options_context = get_server_module_options_context(ty);
|
let rsc_module_options_context =
|
||||||
|
get_server_module_options_context(project_path, execution_context, ty);
|
||||||
|
|
||||||
NextLayoutEntryTransition {
|
NextLayoutEntryTransition {
|
||||||
rsc_environment,
|
rsc_environment,
|
||||||
|
@ -168,7 +176,8 @@ fn next_layout_entry_transition(
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
fn app_context(
|
fn app_context(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
server_root: FileSystemPathVc,
|
server_root: FileSystemPathVc,
|
||||||
app_dir: FileSystemPathVc,
|
app_dir: FileSystemPathVc,
|
||||||
env: ProcessEnvVc,
|
env: ProcessEnvVc,
|
||||||
|
@ -181,7 +190,14 @@ fn app_context(
|
||||||
let mut transitions = HashMap::new();
|
let mut transitions = HashMap::new();
|
||||||
transitions.insert(
|
transitions.insert(
|
||||||
"next-layout-entry".to_string(),
|
"next-layout-entry".to_string(),
|
||||||
next_layout_entry_transition(project_root, app_dir, server_root, env, next_config),
|
next_layout_entry_transition(
|
||||||
|
project_path,
|
||||||
|
execution_context,
|
||||||
|
app_dir,
|
||||||
|
server_root,
|
||||||
|
env,
|
||||||
|
next_config,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
transitions.insert(
|
transitions.insert(
|
||||||
"server-to-client".to_string(),
|
"server-to-client".to_string(),
|
||||||
|
@ -190,7 +206,8 @@ fn app_context(
|
||||||
transitions.insert(
|
transitions.insert(
|
||||||
"next-client".to_string(),
|
"next-client".to_string(),
|
||||||
next_client_transition(
|
next_client_transition(
|
||||||
project_root,
|
project_path,
|
||||||
|
execution_context,
|
||||||
server_root,
|
server_root,
|
||||||
app_dir,
|
app_dir,
|
||||||
env,
|
env,
|
||||||
|
@ -200,19 +217,31 @@ fn app_context(
|
||||||
);
|
);
|
||||||
transitions.insert(
|
transitions.insert(
|
||||||
"next-client-chunks".to_string(),
|
"next-client-chunks".to_string(),
|
||||||
next_client_chunks_transition(project_root, app_dir, server_root, browserslist_query),
|
next_client_chunks_transition(
|
||||||
|
project_path,
|
||||||
|
execution_context,
|
||||||
|
app_dir,
|
||||||
|
server_root,
|
||||||
|
browserslist_query,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
transitions.insert(
|
transitions.insert(
|
||||||
"next-ssr-client-module".to_string(),
|
"next-ssr-client-module".to_string(),
|
||||||
next_ssr_client_module_transition(project_root, app_dir, env, next_config),
|
next_ssr_client_module_transition(
|
||||||
|
project_path,
|
||||||
|
execution_context,
|
||||||
|
app_dir,
|
||||||
|
env,
|
||||||
|
next_config,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let ssr_ty = Value::new(ServerContextType::AppSSR { app_dir });
|
let ssr_ty = Value::new(ServerContextType::AppSSR { app_dir });
|
||||||
ModuleAssetContextVc::new(
|
ModuleAssetContextVc::new(
|
||||||
TransitionsByNameVc::cell(transitions),
|
TransitionsByNameVc::cell(transitions),
|
||||||
get_server_environment(ssr_ty, env),
|
get_server_environment(ssr_ty, env),
|
||||||
get_server_module_options_context(ssr_ty),
|
get_server_module_options_context(project_path, execution_context, ssr_ty),
|
||||||
get_server_resolve_options_context(project_root, ssr_ty, next_config),
|
get_server_resolve_options_context(project_path, ssr_ty, next_config),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
@ -222,6 +251,7 @@ fn app_context(
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub async fn create_app_source(
|
pub async fn create_app_source(
|
||||||
project_path: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
output_path: FileSystemPathVc,
|
output_path: FileSystemPathVc,
|
||||||
server_root: FileSystemPathVc,
|
server_root: FileSystemPathVc,
|
||||||
env: ProcessEnvVc,
|
env: ProcessEnvVc,
|
||||||
|
@ -246,6 +276,7 @@ pub async fn create_app_source(
|
||||||
|
|
||||||
let context_ssr = app_context(
|
let context_ssr = app_context(
|
||||||
project_path,
|
project_path,
|
||||||
|
execution_context,
|
||||||
server_root,
|
server_root,
|
||||||
app_dir,
|
app_dir,
|
||||||
env,
|
env,
|
||||||
|
@ -255,6 +286,7 @@ pub async fn create_app_source(
|
||||||
);
|
);
|
||||||
let context = app_context(
|
let context = app_context(
|
||||||
project_path,
|
project_path,
|
||||||
|
execution_context,
|
||||||
server_root,
|
server_root,
|
||||||
app_dir,
|
app_dir,
|
||||||
env,
|
env,
|
||||||
|
@ -271,6 +303,7 @@ pub async fn create_app_source(
|
||||||
|
|
||||||
let fallback_page = get_fallback_page(
|
let fallback_page = get_fallback_page(
|
||||||
project_path,
|
project_path,
|
||||||
|
execution_context,
|
||||||
server_root,
|
server_root,
|
||||||
env,
|
env,
|
||||||
browserslist_query,
|
browserslist_query,
|
||||||
|
@ -298,7 +331,7 @@ pub async fn create_app_source(
|
||||||
async fn create_app_source_for_directory(
|
async fn create_app_source_for_directory(
|
||||||
context_ssr: AssetContextVc,
|
context_ssr: AssetContextVc,
|
||||||
context: AssetContextVc,
|
context: AssetContextVc,
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
specificity: SpecificityVc,
|
specificity: SpecificityVc,
|
||||||
position: u32,
|
position: u32,
|
||||||
input_dir: FileSystemPathVc,
|
input_dir: FileSystemPathVc,
|
||||||
|
@ -392,7 +425,7 @@ async fn create_app_source_for_directory(
|
||||||
layout_path: layouts,
|
layout_path: layouts,
|
||||||
page_path,
|
page_path,
|
||||||
target,
|
target,
|
||||||
project_root,
|
project_path,
|
||||||
intermediate_output_path,
|
intermediate_output_path,
|
||||||
}
|
}
|
||||||
.cell()
|
.cell()
|
||||||
|
@ -422,7 +455,7 @@ async fn create_app_source_for_directory(
|
||||||
create_app_source_for_directory(
|
create_app_source_for_directory(
|
||||||
context_ssr,
|
context_ssr,
|
||||||
context,
|
context,
|
||||||
project_root,
|
project_path,
|
||||||
specificity,
|
specificity,
|
||||||
position,
|
position,
|
||||||
*dir,
|
*dir,
|
||||||
|
@ -449,7 +482,7 @@ struct AppRenderer {
|
||||||
layout_path: LayoutSegmentsVc,
|
layout_path: LayoutSegmentsVc,
|
||||||
page_path: FileSystemPathVc,
|
page_path: FileSystemPathVc,
|
||||||
target: FileSystemPathVc,
|
target: FileSystemPathVc,
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
intermediate_output_path: FileSystemPathVc,
|
intermediate_output_path: FileSystemPathVc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,7 +613,7 @@ import BOOTSTRAP from {};
|
||||||
};
|
};
|
||||||
|
|
||||||
let chunking_context = DevChunkingContextVc::builder(
|
let chunking_context = DevChunkingContextVc::builder(
|
||||||
self.project_root,
|
self.project_path,
|
||||||
intermediate_output_path,
|
intermediate_output_path,
|
||||||
intermediate_output_path.join("chunks"),
|
intermediate_output_path.join("chunks"),
|
||||||
self.server_root.join("_next/static/assets"),
|
self.server_root.join("_next/static/assets"),
|
||||||
|
|
|
@ -13,6 +13,7 @@ use turbopack_core::{
|
||||||
resolve::{options::ImportMap, origin::PlainResolveOriginVc},
|
resolve::{options::ImportMap, origin::PlainResolveOriginVc},
|
||||||
};
|
};
|
||||||
use turbopack_dev_server::html::DevHtmlAssetVc;
|
use turbopack_dev_server::html::DevHtmlAssetVc;
|
||||||
|
use turbopack_node::execution_context::ExecutionContextVc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
next_client::context::{
|
next_client::context::{
|
||||||
|
@ -26,7 +27,8 @@ use crate::{
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub async fn get_fallback_page(
|
pub async fn get_fallback_page(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
dev_server_root: FileSystemPathVc,
|
dev_server_root: FileSystemPathVc,
|
||||||
env: ProcessEnvVc,
|
env: ProcessEnvVc,
|
||||||
browserslist_query: &str,
|
browserslist_query: &str,
|
||||||
|
@ -34,13 +36,14 @@ pub async fn get_fallback_page(
|
||||||
) -> Result<DevHtmlAssetVc> {
|
) -> Result<DevHtmlAssetVc> {
|
||||||
let ty = Value::new(ContextType::Fallback);
|
let ty = Value::new(ContextType::Fallback);
|
||||||
let environment = get_client_environment(browserslist_query);
|
let environment = get_client_environment(browserslist_query);
|
||||||
let resolve_options_context = get_client_resolve_options_context(project_root, ty);
|
let resolve_options_context = get_client_resolve_options_context(project_path, ty);
|
||||||
let module_options_context = get_client_module_options_context(project_root, environment, ty);
|
let module_options_context =
|
||||||
let chunking_context = get_client_chunking_context(project_root, dev_server_root, ty);
|
get_client_module_options_context(project_path, execution_context, environment, ty);
|
||||||
let entries = get_client_runtime_entries(project_root, env, ty, next_config);
|
let chunking_context = get_client_chunking_context(project_path, dev_server_root, ty);
|
||||||
|
let entries = get_client_runtime_entries(project_path, env, ty, next_config);
|
||||||
|
|
||||||
let mut import_map = ImportMap::empty();
|
let mut import_map = ImportMap::empty();
|
||||||
insert_next_shared_aliases(&mut import_map, project_root);
|
insert_next_shared_aliases(&mut import_map, project_path);
|
||||||
|
|
||||||
let context: AssetContextVc = ModuleAssetContextVc::new(
|
let context: AssetContextVc = ModuleAssetContextVc::new(
|
||||||
TransitionsByNameVc::cell(HashMap::new()),
|
TransitionsByNameVc::cell(HashMap::new()),
|
||||||
|
@ -53,7 +56,7 @@ pub async fn get_fallback_page(
|
||||||
let runtime_entries = entries.resolve_entries(context);
|
let runtime_entries = entries.resolve_entries(context);
|
||||||
|
|
||||||
let fallback_chunk = resolve_runtime_request(
|
let fallback_chunk = resolve_runtime_request(
|
||||||
PlainResolveOriginVc::new(context, project_root).into(),
|
PlainResolveOriginVc::new(context, project_path).into(),
|
||||||
"entry/fallback",
|
"entry/fallback",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ mod embed_js;
|
||||||
pub mod env;
|
pub mod env;
|
||||||
mod fallback;
|
mod fallback;
|
||||||
pub mod manifest;
|
pub mod manifest;
|
||||||
|
mod next_build;
|
||||||
pub mod next_client;
|
pub mod next_client;
|
||||||
mod next_client_component;
|
mod next_client_component;
|
||||||
pub mod next_config;
|
pub mod next_config;
|
||||||
|
@ -23,7 +24,6 @@ mod web_entry_source;
|
||||||
|
|
||||||
pub use app_source::create_app_source;
|
pub use app_source::create_app_source;
|
||||||
pub use server_rendered_source::create_server_rendered_source;
|
pub use server_rendered_source::create_server_rendered_source;
|
||||||
pub use turbopack_node::source_map;
|
|
||||||
pub use web_entry_source::create_web_entry_source;
|
pub use web_entry_source::create_web_entry_source;
|
||||||
|
|
||||||
pub fn register() {
|
pub fn register() {
|
||||||
|
@ -31,7 +31,7 @@ pub fn register() {
|
||||||
turbo_tasks_fs::register();
|
turbo_tasks_fs::register();
|
||||||
turbo_tasks_fetch::register();
|
turbo_tasks_fetch::register();
|
||||||
turbopack_dev_server::register();
|
turbopack_dev_server::register();
|
||||||
turbopack::register();
|
|
||||||
turbopack_node::register();
|
turbopack_node::register();
|
||||||
|
turbopack::register();
|
||||||
include!(concat!(env!("OUT_DIR"), "/register.rs"));
|
include!(concat!(env!("OUT_DIR"), "/register.rs"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ use turbopack_core::asset::AssetContentVc;
|
||||||
use turbopack_dev_server::source::{
|
use turbopack_dev_server::source::{
|
||||||
ContentSource, ContentSourceContent, ContentSourceData, ContentSourceResultVc, ContentSourceVc,
|
ContentSource, ContentSourceContent, ContentSourceData, ContentSourceResultVc, ContentSourceVc,
|
||||||
};
|
};
|
||||||
use turbopack_node::{
|
use turbopack_node::render::{
|
||||||
node_api_source::NodeApiContentSourceVc, node_rendered_source::NodeRenderContentSourceVc,
|
node_api_source::NodeApiContentSourceVc, rendered_source::NodeRenderContentSourceVc,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A content source which creates the next.js `_devPagesManifest.json` and
|
/// A content source which creates the next.js `_devPagesManifest.json` and
|
||||||
|
@ -29,6 +29,7 @@ impl DevManifestContentSourceVc {
|
||||||
while let Some(content_source) = queue.pop() {
|
while let Some(content_source) = queue.pop() {
|
||||||
queue.extend(content_source.get_children().await?.iter());
|
queue.extend(content_source.get_children().await?.iter());
|
||||||
|
|
||||||
|
// TODO This shouldn't use casts but an public api instead
|
||||||
if let Some(api_source) = NodeApiContentSourceVc::resolve_from(content_source).await? {
|
if let Some(api_source) = NodeApiContentSourceVc::resolve_from(content_source).await? {
|
||||||
routes.insert(format!("/{}", api_source.get_pathname().await?));
|
routes.insert(format!("/{}", api_source.get_pathname().await?));
|
||||||
|
|
||||||
|
|
49
packages/next-swc/crates/next-core/src/next_build.rs
Normal file
49
packages/next-swc/crates/next-core/src/next_build.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use turbo_tasks::Value;
|
||||||
|
use turbo_tasks_fs::FileSystemPathVc;
|
||||||
|
use turbopack::{resolve_options, resolve_options_context::ResolveOptionsContext};
|
||||||
|
use turbopack_core::resolve::{
|
||||||
|
options::{ImportMapping, ImportMappingVc},
|
||||||
|
parse::RequestVc,
|
||||||
|
pattern::Pattern,
|
||||||
|
resolve,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[turbo_tasks::function]
|
||||||
|
pub async fn get_next_package(project_root: FileSystemPathVc) -> Result<FileSystemPathVc> {
|
||||||
|
let result = resolve(
|
||||||
|
project_root,
|
||||||
|
RequestVc::parse(Value::new(Pattern::Constant(
|
||||||
|
"next/package.json".to_string(),
|
||||||
|
))),
|
||||||
|
resolve_options(
|
||||||
|
project_root,
|
||||||
|
ResolveOptionsContext {
|
||||||
|
enable_node_modules: true,
|
||||||
|
enable_node_native_modules: true,
|
||||||
|
custom_conditions: vec!["development".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.cell(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let assets = result.primary_assets().await?;
|
||||||
|
let asset = assets.first().context("Next.js package not found")?;
|
||||||
|
Ok(asset.path().parent())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[turbo_tasks::function]
|
||||||
|
pub async fn get_postcss_package_mapping(
|
||||||
|
project_path: FileSystemPathVc,
|
||||||
|
) -> Result<ImportMappingVc> {
|
||||||
|
Ok(ImportMapping::Alternatives(vec![
|
||||||
|
// Prefer the local installed version over the next.js version
|
||||||
|
ImportMapping::PrimaryAlternative("postcss".to_string(), Some(project_path)).cell(),
|
||||||
|
ImportMapping::PrimaryAlternative(
|
||||||
|
"postcss".to_string(),
|
||||||
|
Some(get_next_package(project_path)),
|
||||||
|
)
|
||||||
|
.cell(),
|
||||||
|
])
|
||||||
|
.cell())
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ use turbo_tasks_fs::FileSystemPathVc;
|
||||||
use turbopack::{
|
use turbopack::{
|
||||||
module_options::{
|
module_options::{
|
||||||
module_options_context::{ModuleOptionsContext, ModuleOptionsContextVc},
|
module_options_context::{ModuleOptionsContext, ModuleOptionsContextVc},
|
||||||
ModuleRule, ModuleRuleCondition, ModuleRuleEffect,
|
ModuleRule, ModuleRuleCondition, ModuleRuleEffect, PostCssTransformOptions,
|
||||||
},
|
},
|
||||||
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
|
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
|
||||||
transition::TransitionsByNameVc,
|
transition::TransitionsByNameVc,
|
||||||
|
@ -23,10 +23,12 @@ use turbopack_core::{
|
||||||
};
|
};
|
||||||
use turbopack_ecmascript::{EcmascriptInputTransform, EcmascriptInputTransformsVc};
|
use turbopack_ecmascript::{EcmascriptInputTransform, EcmascriptInputTransformsVc};
|
||||||
use turbopack_env::ProcessEnvAssetVc;
|
use turbopack_env::ProcessEnvAssetVc;
|
||||||
|
use turbopack_node::execution_context::ExecutionContextVc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
embed_js::attached_next_js_package_path,
|
embed_js::attached_next_js_package_path,
|
||||||
env::env_for_js,
|
env::env_for_js,
|
||||||
|
next_build::get_postcss_package_mapping,
|
||||||
next_client::runtime_entry::{RuntimeEntriesVc, RuntimeEntry},
|
next_client::runtime_entry::{RuntimeEntriesVc, RuntimeEntry},
|
||||||
next_config::NextConfigVc,
|
next_config::NextConfigVc,
|
||||||
next_import_map::{
|
next_import_map::{
|
||||||
|
@ -63,12 +65,12 @@ pub enum ContextType {
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub fn get_client_resolve_options_context(
|
pub fn get_client_resolve_options_context(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
ty: Value<ContextType>,
|
ty: Value<ContextType>,
|
||||||
) -> ResolveOptionsContextVc {
|
) -> ResolveOptionsContextVc {
|
||||||
let next_client_import_map = get_next_client_import_map(project_root, ty);
|
let next_client_import_map = get_next_client_import_map(project_path, ty);
|
||||||
let next_client_fallback_import_map = get_next_client_fallback_import_map(ty);
|
let next_client_fallback_import_map = get_next_client_fallback_import_map(ty);
|
||||||
let next_client_resolved_map = get_next_client_resolved_map(project_root, project_root);
|
let next_client_resolved_map = get_next_client_resolved_map(project_path, project_path);
|
||||||
ResolveOptionsContext {
|
ResolveOptionsContext {
|
||||||
enable_typescript: true,
|
enable_typescript: true,
|
||||||
enable_react: true,
|
enable_react: true,
|
||||||
|
@ -86,13 +88,14 @@ pub fn get_client_resolve_options_context(
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub async fn get_client_module_options_context(
|
pub async fn get_client_module_options_context(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
env: EnvironmentVc,
|
env: EnvironmentVc,
|
||||||
ty: Value<ContextType>,
|
ty: Value<ContextType>,
|
||||||
) -> Result<ModuleOptionsContextVc> {
|
) -> Result<ModuleOptionsContextVc> {
|
||||||
let resolve_options_context = get_client_resolve_options_context(project_root, ty);
|
let resolve_options_context = get_client_resolve_options_context(project_path, ty);
|
||||||
let enable_react_refresh =
|
let enable_react_refresh =
|
||||||
assert_can_resolve_react_refresh(project_root, resolve_options_context)
|
assert_can_resolve_react_refresh(project_path, resolve_options_context)
|
||||||
.await?
|
.await?
|
||||||
.is_found();
|
.is_found();
|
||||||
|
|
||||||
|
@ -104,8 +107,13 @@ pub async fn get_client_module_options_context(
|
||||||
enable_react_refresh,
|
enable_react_refresh,
|
||||||
enable_styled_components: true,
|
enable_styled_components: true,
|
||||||
enable_styled_jsx: true,
|
enable_styled_jsx: true,
|
||||||
|
enable_postcss_transform: Some(PostCssTransformOptions {
|
||||||
|
postcss_package: Some(get_postcss_package_mapping(project_path)),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
enable_typescript_transform: true,
|
enable_typescript_transform: true,
|
||||||
preset_env_versions: Some(env),
|
preset_env_versions: Some(env),
|
||||||
|
execution_context: Some(execution_context),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,13 +181,15 @@ pub async fn add_next_font_transform(
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub fn get_client_asset_context(
|
pub fn get_client_asset_context(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
browserslist_query: &str,
|
browserslist_query: &str,
|
||||||
ty: Value<ContextType>,
|
ty: Value<ContextType>,
|
||||||
) -> AssetContextVc {
|
) -> AssetContextVc {
|
||||||
let environment = get_client_environment(browserslist_query);
|
let environment = get_client_environment(browserslist_query);
|
||||||
let resolve_options_context = get_client_resolve_options_context(project_root, ty);
|
let resolve_options_context = get_client_resolve_options_context(project_path, ty);
|
||||||
let module_options_context = get_client_module_options_context(project_root, environment, ty);
|
let module_options_context =
|
||||||
|
get_client_module_options_context(project_path, execution_context, environment, ty);
|
||||||
|
|
||||||
let context: AssetContextVc = ModuleAssetContextVc::new(
|
let context: AssetContextVc = ModuleAssetContextVc::new(
|
||||||
TransitionsByNameVc::cell(HashMap::new()),
|
TransitionsByNameVc::cell(HashMap::new()),
|
||||||
|
@ -194,12 +204,12 @@ pub fn get_client_asset_context(
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub fn get_client_chunking_context(
|
pub fn get_client_chunking_context(
|
||||||
project_root: FileSystemPathVc,
|
project_path: FileSystemPathVc,
|
||||||
server_root: FileSystemPathVc,
|
server_root: FileSystemPathVc,
|
||||||
ty: Value<ContextType>,
|
ty: Value<ContextType>,
|
||||||
) -> ChunkingContextVc {
|
) -> ChunkingContextVc {
|
||||||
DevChunkingContextVc::builder(
|
DevChunkingContextVc::builder(
|
||||||
project_root,
|
project_path,
|
||||||
server_root,
|
server_root,
|
||||||
match ty.into_value() {
|
match ty.into_value() {
|
||||||
ContextType::Pages { .. } | ContextType::App { .. } => {
|
ContextType::Pages { .. } | ContextType::App { .. } => {
|
||||||
|
|
|
@ -7,25 +7,25 @@ use turbo_tasks::{
|
||||||
trace::TraceRawVcs,
|
trace::TraceRawVcs,
|
||||||
Value,
|
Value,
|
||||||
};
|
};
|
||||||
use turbo_tasks_fs::{FileSystemEntryType, FileSystemPathVc};
|
use turbo_tasks_fs::FileSystemEntryType;
|
||||||
use turbopack::{transition::TransitionsByNameVc, ModuleAssetContextVc};
|
use turbopack::evaluate_context::node_evaluate_asset_context;
|
||||||
use turbopack_core::{
|
use turbopack_core::{
|
||||||
asset::Asset,
|
asset::Asset,
|
||||||
environment::{EnvironmentIntention, EnvironmentVc, ExecutionEnvironment, NodeJsEnvironment},
|
|
||||||
reference_type::{EntryReferenceSubType, ReferenceType},
|
reference_type::{EntryReferenceSubType, ReferenceType},
|
||||||
|
resolve::options::{ImportMap, ImportMapping},
|
||||||
source_asset::SourceAssetVc,
|
source_asset::SourceAssetVc,
|
||||||
};
|
};
|
||||||
use turbopack_ecmascript::{
|
use turbopack_ecmascript::{
|
||||||
chunk::EcmascriptChunkPlaceablesVc, EcmascriptInputTransformsVc, EcmascriptModuleAssetType,
|
chunk::EcmascriptChunkPlaceablesVc, EcmascriptInputTransformsVc, EcmascriptModuleAssetType,
|
||||||
EcmascriptModuleAssetVc,
|
EcmascriptModuleAssetVc,
|
||||||
};
|
};
|
||||||
use turbopack_node::evaluate::{evaluate, JavaScriptValue};
|
use turbopack_node::{
|
||||||
|
evaluate::{evaluate, JavaScriptValue},
|
||||||
use crate::{
|
execution_context::{ExecutionContext, ExecutionContextVc},
|
||||||
embed_js::next_asset,
|
|
||||||
next_server::{get_build_module_options_context, get_build_resolve_options_context},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::embed_js::next_asset;
|
||||||
|
|
||||||
#[turbo_tasks::value(serialization = "custom")]
|
#[turbo_tasks::value(serialization = "custom")]
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
@ -201,24 +201,19 @@ impl NextConfigVc {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub async fn load_next_config(
|
pub async fn load_next_config(execution_context: ExecutionContextVc) -> Result<NextConfigVc> {
|
||||||
project_path: FileSystemPathVc,
|
let ExecutionContext {
|
||||||
intermediate_output_path: FileSystemPathVc,
|
project_root,
|
||||||
) -> Result<NextConfigVc> {
|
intermediate_output_path,
|
||||||
let context = ModuleAssetContextVc::new(
|
} = *execution_context.await?;
|
||||||
TransitionsByNameVc::cell(Default::default()),
|
let mut import_map = ImportMap::default();
|
||||||
EnvironmentVc::new(
|
|
||||||
Value::new(ExecutionEnvironment::NodeJsBuildTime(
|
import_map.insert_exact_alias("next", ImportMapping::External(None).into());
|
||||||
NodeJsEnvironment::default().cell(),
|
import_map.insert_wildcard_alias("next/", ImportMapping::External(None).into());
|
||||||
)),
|
|
||||||
Value::new(EnvironmentIntention::Build),
|
let context = node_evaluate_asset_context(Some(import_map.cell()));
|
||||||
),
|
let next_config_mjs_path = project_root.join("next.config.mjs").realpath();
|
||||||
get_build_module_options_context(),
|
let next_config_js_path = project_root.join("next.config.js").realpath();
|
||||||
get_build_resolve_options_context(project_path),
|
|
||||||
)
|
|
||||||
.as_asset_context();
|
|
||||||
let next_config_mjs_path = project_path.join("next.config.mjs").realpath();
|
|
||||||
let next_config_js_path = project_path.join("next.config.js").realpath();
|
|
||||||
let config_asset = if matches!(
|
let config_asset = if matches!(
|
||||||
&*next_config_mjs_path.get_type().await?,
|
&*next_config_mjs_path.get_type().await?,
|
||||||
FileSystemEntryType::File
|
FileSystemEntryType::File
|
||||||
|
@ -246,19 +241,20 @@ pub async fn load_next_config(
|
||||||
EcmascriptChunkPlaceablesVc::cell(vec![config_chunk])
|
EcmascriptChunkPlaceablesVc::cell(vec![config_chunk])
|
||||||
});
|
});
|
||||||
let asset_path = config_asset
|
let asset_path = config_asset
|
||||||
.map_or(project_path, |a| a.path())
|
.map_or(project_root, |a| a.path())
|
||||||
.join("load-next-config.js");
|
.join("load-next-config.js");
|
||||||
let load_next_config_asset = context.process(
|
let load_next_config_asset = context.process(
|
||||||
next_asset(asset_path, "entry/config/next.js"),
|
next_asset(asset_path, "entry/config/next.js"),
|
||||||
Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)),
|
Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)),
|
||||||
);
|
);
|
||||||
let config_value = evaluate(
|
let config_value = evaluate(
|
||||||
project_path,
|
project_root,
|
||||||
load_next_config_asset,
|
load_next_config_asset,
|
||||||
project_path,
|
project_root,
|
||||||
context,
|
context,
|
||||||
intermediate_output_path,
|
intermediate_output_path,
|
||||||
runtime_entries,
|
runtime_entries,
|
||||||
|
vec![],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
match &*config_value {
|
match &*config_value {
|
||||||
|
|
|
@ -2,15 +2,17 @@ use turbo_tasks::{primitives::StringVc, Value};
|
||||||
use turbo_tasks_env::ProcessEnvVc;
|
use turbo_tasks_env::ProcessEnvVc;
|
||||||
use turbo_tasks_fs::FileSystemPathVc;
|
use turbo_tasks_fs::FileSystemPathVc;
|
||||||
use turbopack::{
|
use turbopack::{
|
||||||
module_options::{ModuleOptionsContext, ModuleOptionsContextVc},
|
module_options::{ModuleOptionsContext, ModuleOptionsContextVc, PostCssTransformOptions},
|
||||||
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
|
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
|
||||||
};
|
};
|
||||||
use turbopack_core::environment::{
|
use turbopack_core::environment::{
|
||||||
EnvironmentIntention, EnvironmentVc, ExecutionEnvironment, NodeJsEnvironmentVc,
|
EnvironmentIntention, EnvironmentVc, ExecutionEnvironment, NodeJsEnvironmentVc,
|
||||||
};
|
};
|
||||||
use turbopack_ecmascript::EcmascriptInputTransform;
|
use turbopack_ecmascript::EcmascriptInputTransform;
|
||||||
|
use turbopack_node::execution_context::ExecutionContextVc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
next_build::get_postcss_package_mapping,
|
||||||
next_client::context::add_next_font_transform,
|
next_client::context::add_next_font_transform,
|
||||||
next_config::NextConfigVc,
|
next_config::NextConfigVc,
|
||||||
next_import_map::{get_next_build_import_map, get_next_server_import_map},
|
next_import_map::{get_next_build_import_map, get_next_server_import_map},
|
||||||
|
@ -78,23 +80,42 @@ pub fn get_server_environment(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub fn get_server_module_options_context(ty: Value<ServerContextType>) -> ModuleOptionsContextVc {
|
pub fn get_server_module_options_context(
|
||||||
|
project_path: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
|
ty: Value<ServerContextType>,
|
||||||
|
) -> ModuleOptionsContextVc {
|
||||||
let module_options_context = match ty.into_value() {
|
let module_options_context = match ty.into_value() {
|
||||||
ServerContextType::Pages { .. } => ModuleOptionsContext {
|
ServerContextType::Pages { .. } => ModuleOptionsContext {
|
||||||
enable_typescript_transform: true,
|
|
||||||
enable_styled_jsx: true,
|
enable_styled_jsx: true,
|
||||||
|
enable_postcss_transform: Some(PostCssTransformOptions {
|
||||||
|
postcss_package: Some(get_postcss_package_mapping(project_path)),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
enable_typescript_transform: true,
|
||||||
|
execution_context: Some(execution_context),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
ServerContextType::AppSSR { .. } => ModuleOptionsContext {
|
ServerContextType::AppSSR { .. } => ModuleOptionsContext {
|
||||||
enable_styled_jsx: true,
|
enable_styled_jsx: true,
|
||||||
|
enable_postcss_transform: Some(PostCssTransformOptions {
|
||||||
|
postcss_package: Some(get_postcss_package_mapping(project_path)),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
enable_typescript_transform: true,
|
enable_typescript_transform: true,
|
||||||
|
execution_context: Some(execution_context),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
ServerContextType::AppRSC { .. } => ModuleOptionsContext {
|
ServerContextType::AppRSC { .. } => ModuleOptionsContext {
|
||||||
|
enable_postcss_transform: Some(PostCssTransformOptions {
|
||||||
|
postcss_package: Some(get_postcss_package_mapping(project_path)),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
enable_typescript_transform: true,
|
enable_typescript_transform: true,
|
||||||
custom_ecmascript_transforms: vec![EcmascriptInputTransform::ClientDirective(
|
custom_ecmascript_transforms: vec![EcmascriptInputTransform::ClientDirective(
|
||||||
StringVc::cell("server-to-client".to_string()),
|
StringVc::cell("server-to-client".to_string()),
|
||||||
)],
|
)],
|
||||||
|
execution_context: Some(execution_context),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,11 @@ use turbopack_ecmascript::{
|
||||||
};
|
};
|
||||||
use turbopack_env::ProcessEnvAssetVc;
|
use turbopack_env::ProcessEnvAssetVc;
|
||||||
use turbopack_node::{
|
use turbopack_node::{
|
||||||
create_node_api_source, create_node_rendered_source,
|
execution_context::ExecutionContextVc,
|
||||||
node_entry::{NodeRenderingEntry, NodeRenderingEntryVc},
|
render::{
|
||||||
NodeEntry, NodeEntryVc,
|
node_api_source::create_node_api_source, rendered_source::create_node_rendered_source,
|
||||||
|
},
|
||||||
|
NodeEntry, NodeEntryVc, NodeRenderingEntry, NodeRenderingEntryVc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -61,14 +63,15 @@ use crate::{
|
||||||
/// Next.js pages folder.
|
/// Next.js pages folder.
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub async fn create_server_rendered_source(
|
pub async fn create_server_rendered_source(
|
||||||
project_path: FileSystemPathVc,
|
project_root: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
output_path: FileSystemPathVc,
|
output_path: FileSystemPathVc,
|
||||||
server_root: FileSystemPathVc,
|
server_root: FileSystemPathVc,
|
||||||
env: ProcessEnvVc,
|
env: ProcessEnvVc,
|
||||||
browserslist_query: &str,
|
browserslist_query: &str,
|
||||||
next_config: NextConfigVc,
|
next_config: NextConfigVc,
|
||||||
) -> Result<ContentSourceVc> {
|
) -> Result<ContentSourceVc> {
|
||||||
let project_path = wrap_with_next_js_fs(project_path);
|
let project_path = wrap_with_next_js_fs(project_root);
|
||||||
|
|
||||||
let pages = project_path.join("pages");
|
let pages = project_path.join("pages");
|
||||||
let src_pages = project_path.join("src/pages");
|
let src_pages = project_path.join("src/pages");
|
||||||
|
@ -85,7 +88,7 @@ pub async fn create_server_rendered_source(
|
||||||
|
|
||||||
let client_environment = get_client_environment(browserslist_query);
|
let client_environment = get_client_environment(browserslist_query);
|
||||||
let client_module_options_context =
|
let client_module_options_context =
|
||||||
get_client_module_options_context(project_path, client_environment, ty);
|
get_client_module_options_context(project_path, execution_context, client_environment, ty);
|
||||||
let client_module_options_context =
|
let client_module_options_context =
|
||||||
add_next_transforms_to_pages(client_module_options_context, pages_dir);
|
add_next_transforms_to_pages(client_module_options_context, pages_dir);
|
||||||
let client_resolve_options_context = get_client_resolve_options_context(project_path, ty);
|
let client_resolve_options_context = get_client_resolve_options_context(project_path, ty);
|
||||||
|
@ -118,7 +121,7 @@ pub async fn create_server_rendered_source(
|
||||||
let context: AssetContextVc = ModuleAssetContextVc::new(
|
let context: AssetContextVc = ModuleAssetContextVc::new(
|
||||||
TransitionsByNameVc::cell(transitions),
|
TransitionsByNameVc::cell(transitions),
|
||||||
get_server_environment(server_ty, env),
|
get_server_environment(server_ty, env),
|
||||||
get_server_module_options_context(server_ty),
|
get_server_module_options_context(project_path, execution_context, server_ty),
|
||||||
get_server_resolve_options_context(project_path, server_ty, next_config),
|
get_server_resolve_options_context(project_path, server_ty, next_config),
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
|
@ -131,6 +134,7 @@ pub async fn create_server_rendered_source(
|
||||||
|
|
||||||
let fallback_page = get_fallback_page(
|
let fallback_page = get_fallback_page(
|
||||||
project_path,
|
project_path,
|
||||||
|
execution_context,
|
||||||
server_root,
|
server_root,
|
||||||
env,
|
env,
|
||||||
browserslist_query,
|
browserslist_query,
|
||||||
|
|
|
@ -12,6 +12,7 @@ use turbopack_dev_server::{
|
||||||
html::DevHtmlAssetVc,
|
html::DevHtmlAssetVc,
|
||||||
source::{asset_graph::AssetGraphContentSourceVc, ContentSourceVc},
|
source::{asset_graph::AssetGraphContentSourceVc, ContentSourceVc},
|
||||||
};
|
};
|
||||||
|
use turbopack_node::execution_context::ExecutionContextVc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
embed_js::wrap_with_next_js_fs,
|
embed_js::wrap_with_next_js_fs,
|
||||||
|
@ -25,6 +26,7 @@ use crate::{
|
||||||
#[turbo_tasks::function]
|
#[turbo_tasks::function]
|
||||||
pub async fn create_web_entry_source(
|
pub async fn create_web_entry_source(
|
||||||
project_root: FileSystemPathVc,
|
project_root: FileSystemPathVc,
|
||||||
|
execution_context: ExecutionContextVc,
|
||||||
entry_requests: Vec<RequestVc>,
|
entry_requests: Vec<RequestVc>,
|
||||||
server_root: FileSystemPathVc,
|
server_root: FileSystemPathVc,
|
||||||
env: ProcessEnvVc,
|
env: ProcessEnvVc,
|
||||||
|
@ -35,7 +37,7 @@ pub async fn create_web_entry_source(
|
||||||
let project_root = wrap_with_next_js_fs(project_root);
|
let project_root = wrap_with_next_js_fs(project_root);
|
||||||
|
|
||||||
let ty = Value::new(ContextType::Other);
|
let ty = Value::new(ContextType::Other);
|
||||||
let context = get_client_asset_context(project_root, browserslist_query, ty);
|
let context = get_client_asset_context(project_root, execution_context, browserslist_query, ty);
|
||||||
let chunking_context = get_client_chunking_context(project_root, server_root, ty);
|
let chunking_context = get_client_chunking_context(project_root, server_root, ty);
|
||||||
let entries = get_client_runtime_entries(project_root, env, ty, next_config);
|
let entries = get_client_runtime_entries(project_root, env, ty, next_config);
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ turbo-tasks-memory = { path = "../turbo-tasks-memory" }
|
||||||
turbopack-cli-utils = { path = "../turbopack-cli-utils" }
|
turbopack-cli-utils = { path = "../turbopack-cli-utils" }
|
||||||
turbopack-core = { path = "../turbopack-core" }
|
turbopack-core = { path = "../turbopack-core" }
|
||||||
turbopack-dev-server = { path = "../turbopack-dev-server" }
|
turbopack-dev-server = { path = "../turbopack-dev-server" }
|
||||||
|
turbopack-node = { path = "../turbopack-node" }
|
||||||
webbrowser = "0.7.1"
|
webbrowser = "0.7.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -19,7 +19,7 @@ use devserver_options::DevServerOptions;
|
||||||
use next_core::{
|
use next_core::{
|
||||||
create_app_source, create_server_rendered_source, create_web_entry_source, env::load_env,
|
create_app_source, create_server_rendered_source, create_web_entry_source, env::load_env,
|
||||||
manifest::DevManifestContentSource, next_config::load_next_config,
|
manifest::DevManifestContentSource, next_config::load_next_config,
|
||||||
next_image::NextImageContentSourceVc, source_map::NextSourceMapTraceContentSourceVc,
|
next_image::NextImageContentSourceVc,
|
||||||
};
|
};
|
||||||
use owo_colors::OwoColorize;
|
use owo_colors::OwoColorize;
|
||||||
use turbo_malloc::TurboMalloc;
|
use turbo_malloc::TurboMalloc;
|
||||||
|
@ -44,6 +44,9 @@ use turbopack_dev_server::{
|
||||||
},
|
},
|
||||||
DevServer,
|
DevServer,
|
||||||
};
|
};
|
||||||
|
use turbopack_node::{
|
||||||
|
execution_context::ExecutionContextVc, source_map::NextSourceMapTraceContentSourceVc,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum EntryRequest {
|
pub enum EntryRequest {
|
||||||
|
@ -276,8 +279,11 @@ async fn source(
|
||||||
let project_path = fs.root().join(project_relative);
|
let project_path = fs.root().join(project_relative);
|
||||||
|
|
||||||
let env = load_env(project_path);
|
let env = load_env(project_path);
|
||||||
let config_output_root = output_fs.root().join(".next/config");
|
let build_output_root = output_fs.root().join(".next/build");
|
||||||
let next_config = load_next_config(project_path, config_output_root);
|
|
||||||
|
let execution_context = ExecutionContextVc::new(project_path, build_output_root);
|
||||||
|
|
||||||
|
let next_config = load_next_config(execution_context.join("next_config"));
|
||||||
|
|
||||||
let output_root = output_fs.root().join(".next/server");
|
let output_root = output_fs.root().join(".next/server");
|
||||||
|
|
||||||
|
@ -295,6 +301,7 @@ async fn source(
|
||||||
|
|
||||||
let web_source = create_web_entry_source(
|
let web_source = create_web_entry_source(
|
||||||
project_path,
|
project_path,
|
||||||
|
execution_context,
|
||||||
entry_requests,
|
entry_requests,
|
||||||
dev_server_root,
|
dev_server_root,
|
||||||
env,
|
env,
|
||||||
|
@ -304,6 +311,7 @@ async fn source(
|
||||||
);
|
);
|
||||||
let rendered_source = create_server_rendered_source(
|
let rendered_source = create_server_rendered_source(
|
||||||
project_path,
|
project_path,
|
||||||
|
execution_context,
|
||||||
output_root.join("pages"),
|
output_root.join("pages"),
|
||||||
dev_server_root,
|
dev_server_root,
|
||||||
env,
|
env,
|
||||||
|
@ -312,6 +320,7 @@ async fn source(
|
||||||
);
|
);
|
||||||
let app_source = create_app_source(
|
let app_source = create_app_source(
|
||||||
project_path,
|
project_path,
|
||||||
|
execution_context,
|
||||||
output_root.join("app"),
|
output_root.join("app"),
|
||||||
dev_server_root,
|
dev_server_root,
|
||||||
env,
|
env,
|
||||||
|
|
|
@ -146,6 +146,9 @@ async fn run_test(resource: &str) -> JestRunResult {
|
||||||
.eager_compile(false)
|
.eager_compile(false)
|
||||||
.hostname(requested_addr.ip())
|
.hostname(requested_addr.ip())
|
||||||
.port(requested_addr.port())
|
.port(requested_addr.port())
|
||||||
|
.log_level(turbopack_core::issue::IssueSeverity::Warning)
|
||||||
|
.log_detail(true)
|
||||||
|
.show_all(true)
|
||||||
.build()
|
.build()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
module.exports = {
|
||||||
|
reactStrictMode: true,
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
import "../styles/globals.css";
|
||||||
|
import type { AppProps } from "next/app";
|
||||||
|
|
||||||
|
function MyApp({ Component, pageProps }: AppProps) {
|
||||||
|
return <Component {...pageProps} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MyApp;
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||||
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
type Data = {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function handler(
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse<Data>
|
||||||
|
) {
|
||||||
|
res.status(200).json({ name: "John Doe" });
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
import Head from "next/head";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { Deferred } from "@turbo/pack-test-harness/deferred";
|
||||||
|
|
||||||
|
let testResult = new Deferred();
|
||||||
|
|
||||||
|
const Home = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
// Only run on client
|
||||||
|
import("@turbo/pack-test-harness").then(runTests);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-screen flex-col items-center justify-center py-2">
|
||||||
|
<Head>
|
||||||
|
<title>Create Next App</title>
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
</Head>
|
||||||
|
|
||||||
|
<main className="flex w-full flex-1 flex-col items-center justify-center px-20 text-center">
|
||||||
|
<h1 className="text-6xl font-bold">
|
||||||
|
Welcome to{" "}
|
||||||
|
<a className="text-blue-600" href="https://nextjs.org">
|
||||||
|
Next.js!
|
||||||
|
</a>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="mt-3 text-2xl">
|
||||||
|
Get started by editing{" "}
|
||||||
|
<code className="rounded-md bg-gray-100 p-3 font-mono text-lg">
|
||||||
|
pages/index.tsx
|
||||||
|
</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mt-6 flex max-w-4xl flex-wrap items-center justify-around sm:w-full">
|
||||||
|
<a
|
||||||
|
href="https://nextjs.org/docs"
|
||||||
|
className="mt-6 w-96 rounded-xl border p-6 text-left hover:text-blue-600 focus:text-blue-600"
|
||||||
|
>
|
||||||
|
<h3 className="text-2xl font-bold">Documentation →</h3>
|
||||||
|
<p className="mt-4 text-xl">
|
||||||
|
Find in-depth information about Next.js features and its API.
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://nextjs.org/learn"
|
||||||
|
className="mt-6 w-96 rounded-xl border p-6 text-left hover:text-blue-600 focus:text-blue-600"
|
||||||
|
>
|
||||||
|
<h3 className="text-2xl font-bold">Learn →</h3>
|
||||||
|
<p className="mt-4 text-xl">
|
||||||
|
Learn about Next.js in an interactive course with quizzes!
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://github.com/vercel/next.js/tree/canary/examples"
|
||||||
|
className="mt-6 w-96 rounded-xl border p-6 text-left hover:text-blue-600 focus:text-blue-600"
|
||||||
|
>
|
||||||
|
<h3 className="text-2xl font-bold">Examples →</h3>
|
||||||
|
<p className="mt-4 text-xl">
|
||||||
|
Discover and deploy boilerplate example Next.js projects.
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://vercel.com/import?filter=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||||
|
className="mt-6 w-96 rounded-xl border p-6 text-left hover:text-blue-600 focus:text-blue-600"
|
||||||
|
>
|
||||||
|
<h3 className="text-2xl font-bold">Deploy →</h3>
|
||||||
|
<p className="mt-4 text-xl">
|
||||||
|
Instantly deploy your Next.js site to a public URL with Vercel.
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer className="flex h-24 w-full items-center justify-center border-t">
|
||||||
|
<a
|
||||||
|
className="flex items-center justify-center gap-2"
|
||||||
|
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Powered by{" "}
|
||||||
|
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Home;
|
||||||
|
|
||||||
|
globalThis.waitForTests = function () {
|
||||||
|
return testResult.promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
console.log(document.querySelectorAll("footer"));
|
||||||
|
it("it should apply tailwind styles", function () {
|
||||||
|
const footer = document.querySelector("footer");
|
||||||
|
expect(getComputedStyle(footer).alignItems).toBe("center");
|
||||||
|
});
|
||||||
|
testResult.resolve(__jest__.run());
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
|
@ -0,0 +1,12 @@
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: [
|
||||||
|
"./pages/**/*.{js,ts,jsx,tsx}",
|
||||||
|
"./components/**/*.{js,ts,jsx,tsx}",
|
||||||
|
"./app/**/*.{js,ts,jsx,tsx}",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/index.jsx"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
|
@ -2,10 +2,13 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@turbo/pack-test-harness": "*",
|
"@turbo/pack-test-harness": "*",
|
||||||
|
"autoprefixer": "^10.4.13",
|
||||||
"next": "13.0.1",
|
"next": "13.0.1",
|
||||||
|
"postcss": "^8.4.20",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-test-renderer": "^18.2.0",
|
"react-test-renderer": "^18.2.0",
|
||||||
"styled-jsx": "^5.1.0"
|
"styled-jsx": "^5.1.0",
|
||||||
|
"tailwindcss": "^3.2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue