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;
|
||||
const { PHASE_DEVELOPMENT_SERVER } = require("next/dist/shared/lib/constants");
|
||||
import loadConfig from "next/dist/server/config";
|
||||
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());
|
||||
nextConfig.rewrites = await nextConfig.rewrites?.();
|
||||
nextConfig.redirects = await nextConfig.redirects?.();
|
||||
return nextConfig;
|
||||
})();
|
||||
};
|
||||
|
||||
export { loadNextConfig as default };
|
||||
|
|
|
@ -35,9 +35,8 @@ use turbopack_ecmascript::{
|
|||
};
|
||||
use turbopack_env::ProcessEnvAssetVc;
|
||||
use turbopack_node::{
|
||||
create_node_rendered_source,
|
||||
node_entry::{NodeRenderingEntry, NodeRenderingEntryVc},
|
||||
NodeEntry, NodeEntryVc,
|
||||
execution_context::ExecutionContextVc, render::rendered_source::create_node_rendered_source,
|
||||
NodeEntry, NodeEntryVc, NodeRenderingEntry, NodeRenderingEntryVc,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -69,21 +68,22 @@ use crate::{
|
|||
|
||||
#[turbo_tasks::function]
|
||||
fn next_client_chunks_transition(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
app_dir: FileSystemPathVc,
|
||||
server_root: FileSystemPathVc,
|
||||
browserslist_query: &str,
|
||||
) -> TransitionVc {
|
||||
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_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 {
|
||||
client_chunking_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,
|
||||
server_root,
|
||||
}
|
||||
|
@ -93,7 +93,8 @@ fn next_client_chunks_transition(
|
|||
|
||||
#[turbo_tasks::function]
|
||||
async fn next_client_transition(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
server_root: FileSystemPathVc,
|
||||
app_dir: FileSystemPathVc,
|
||||
env: ProcessEnvVc,
|
||||
|
@ -101,12 +102,12 @@ async fn next_client_transition(
|
|||
next_config: NextConfigVc,
|
||||
) -> Result<TransitionVc> {
|
||||
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_module_options_context =
|
||||
get_client_module_options_context(project_root, client_environment, ty);
|
||||
let client_runtime_entries = get_client_runtime_entries(project_root, env, ty, next_config);
|
||||
let client_resolve_options_context = get_client_resolve_options_context(project_root, ty);
|
||||
get_client_module_options_context(project_path, execution_context, client_environment, ty);
|
||||
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_path, ty);
|
||||
|
||||
Ok(NextClientTransition {
|
||||
is_app: true,
|
||||
|
@ -123,16 +124,21 @@ async fn next_client_transition(
|
|||
|
||||
#[turbo_tasks::function]
|
||||
fn next_ssr_client_module_transition(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
app_dir: FileSystemPathVc,
|
||||
process_env: ProcessEnvVc,
|
||||
next_config: NextConfigVc,
|
||||
) -> TransitionVc {
|
||||
let ty = Value::new(ServerContextType::AppSSR { app_dir });
|
||||
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(
|
||||
project_root,
|
||||
project_path,
|
||||
ty,
|
||||
next_config,
|
||||
),
|
||||
|
@ -144,7 +150,8 @@ fn next_ssr_client_module_transition(
|
|||
|
||||
#[turbo_tasks::function]
|
||||
fn next_layout_entry_transition(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
app_dir: FileSystemPathVc,
|
||||
server_root: FileSystemPathVc,
|
||||
process_env: ProcessEnvVc,
|
||||
|
@ -153,8 +160,9 @@ fn next_layout_entry_transition(
|
|||
let ty = Value::new(ServerContextType::AppRSC { app_dir });
|
||||
let rsc_environment = get_server_environment(ty, process_env);
|
||||
let rsc_resolve_options_context =
|
||||
get_server_resolve_options_context(project_root, ty, next_config);
|
||||
let rsc_module_options_context = get_server_module_options_context(ty);
|
||||
get_server_resolve_options_context(project_path, ty, next_config);
|
||||
let rsc_module_options_context =
|
||||
get_server_module_options_context(project_path, execution_context, ty);
|
||||
|
||||
NextLayoutEntryTransition {
|
||||
rsc_environment,
|
||||
|
@ -168,7 +176,8 @@ fn next_layout_entry_transition(
|
|||
|
||||
#[turbo_tasks::function]
|
||||
fn app_context(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
server_root: FileSystemPathVc,
|
||||
app_dir: FileSystemPathVc,
|
||||
env: ProcessEnvVc,
|
||||
|
@ -181,7 +190,14 @@ fn app_context(
|
|||
let mut transitions = HashMap::new();
|
||||
transitions.insert(
|
||||
"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(
|
||||
"server-to-client".to_string(),
|
||||
|
@ -190,7 +206,8 @@ fn app_context(
|
|||
transitions.insert(
|
||||
"next-client".to_string(),
|
||||
next_client_transition(
|
||||
project_root,
|
||||
project_path,
|
||||
execution_context,
|
||||
server_root,
|
||||
app_dir,
|
||||
env,
|
||||
|
@ -200,19 +217,31 @@ fn app_context(
|
|||
);
|
||||
transitions.insert(
|
||||
"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(
|
||||
"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 });
|
||||
ModuleAssetContextVc::new(
|
||||
TransitionsByNameVc::cell(transitions),
|
||||
get_server_environment(ssr_ty, env),
|
||||
get_server_module_options_context(ssr_ty),
|
||||
get_server_resolve_options_context(project_root, ssr_ty, next_config),
|
||||
get_server_module_options_context(project_path, execution_context, ssr_ty),
|
||||
get_server_resolve_options_context(project_path, ssr_ty, next_config),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
@ -222,6 +251,7 @@ fn app_context(
|
|||
#[turbo_tasks::function]
|
||||
pub async fn create_app_source(
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
output_path: FileSystemPathVc,
|
||||
server_root: FileSystemPathVc,
|
||||
env: ProcessEnvVc,
|
||||
|
@ -246,6 +276,7 @@ pub async fn create_app_source(
|
|||
|
||||
let context_ssr = app_context(
|
||||
project_path,
|
||||
execution_context,
|
||||
server_root,
|
||||
app_dir,
|
||||
env,
|
||||
|
@ -255,6 +286,7 @@ pub async fn create_app_source(
|
|||
);
|
||||
let context = app_context(
|
||||
project_path,
|
||||
execution_context,
|
||||
server_root,
|
||||
app_dir,
|
||||
env,
|
||||
|
@ -271,6 +303,7 @@ pub async fn create_app_source(
|
|||
|
||||
let fallback_page = get_fallback_page(
|
||||
project_path,
|
||||
execution_context,
|
||||
server_root,
|
||||
env,
|
||||
browserslist_query,
|
||||
|
@ -298,7 +331,7 @@ pub async fn create_app_source(
|
|||
async fn create_app_source_for_directory(
|
||||
context_ssr: AssetContextVc,
|
||||
context: AssetContextVc,
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
specificity: SpecificityVc,
|
||||
position: u32,
|
||||
input_dir: FileSystemPathVc,
|
||||
|
@ -392,7 +425,7 @@ async fn create_app_source_for_directory(
|
|||
layout_path: layouts,
|
||||
page_path,
|
||||
target,
|
||||
project_root,
|
||||
project_path,
|
||||
intermediate_output_path,
|
||||
}
|
||||
.cell()
|
||||
|
@ -422,7 +455,7 @@ async fn create_app_source_for_directory(
|
|||
create_app_source_for_directory(
|
||||
context_ssr,
|
||||
context,
|
||||
project_root,
|
||||
project_path,
|
||||
specificity,
|
||||
position,
|
||||
*dir,
|
||||
|
@ -449,7 +482,7 @@ struct AppRenderer {
|
|||
layout_path: LayoutSegmentsVc,
|
||||
page_path: FileSystemPathVc,
|
||||
target: FileSystemPathVc,
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
intermediate_output_path: FileSystemPathVc,
|
||||
}
|
||||
|
||||
|
@ -580,7 +613,7 @@ import BOOTSTRAP from {};
|
|||
};
|
||||
|
||||
let chunking_context = DevChunkingContextVc::builder(
|
||||
self.project_root,
|
||||
self.project_path,
|
||||
intermediate_output_path,
|
||||
intermediate_output_path.join("chunks"),
|
||||
self.server_root.join("_next/static/assets"),
|
||||
|
|
|
@ -13,6 +13,7 @@ use turbopack_core::{
|
|||
resolve::{options::ImportMap, origin::PlainResolveOriginVc},
|
||||
};
|
||||
use turbopack_dev_server::html::DevHtmlAssetVc;
|
||||
use turbopack_node::execution_context::ExecutionContextVc;
|
||||
|
||||
use crate::{
|
||||
next_client::context::{
|
||||
|
@ -26,7 +27,8 @@ use crate::{
|
|||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn get_fallback_page(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
dev_server_root: FileSystemPathVc,
|
||||
env: ProcessEnvVc,
|
||||
browserslist_query: &str,
|
||||
|
@ -34,13 +36,14 @@ pub async fn get_fallback_page(
|
|||
) -> Result<DevHtmlAssetVc> {
|
||||
let ty = Value::new(ContextType::Fallback);
|
||||
let environment = get_client_environment(browserslist_query);
|
||||
let resolve_options_context = get_client_resolve_options_context(project_root, ty);
|
||||
let module_options_context = get_client_module_options_context(project_root, environment, ty);
|
||||
let chunking_context = get_client_chunking_context(project_root, dev_server_root, ty);
|
||||
let entries = get_client_runtime_entries(project_root, env, ty, next_config);
|
||||
let resolve_options_context = get_client_resolve_options_context(project_path, ty);
|
||||
let module_options_context =
|
||||
get_client_module_options_context(project_path, execution_context, environment, ty);
|
||||
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();
|
||||
insert_next_shared_aliases(&mut import_map, project_root);
|
||||
insert_next_shared_aliases(&mut import_map, project_path);
|
||||
|
||||
let context: AssetContextVc = ModuleAssetContextVc::new(
|
||||
TransitionsByNameVc::cell(HashMap::new()),
|
||||
|
@ -53,7 +56,7 @@ pub async fn get_fallback_page(
|
|||
let runtime_entries = entries.resolve_entries(context);
|
||||
|
||||
let fallback_chunk = resolve_runtime_request(
|
||||
PlainResolveOriginVc::new(context, project_root).into(),
|
||||
PlainResolveOriginVc::new(context, project_path).into(),
|
||||
"entry/fallback",
|
||||
);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ mod embed_js;
|
|||
pub mod env;
|
||||
mod fallback;
|
||||
pub mod manifest;
|
||||
mod next_build;
|
||||
pub mod next_client;
|
||||
mod next_client_component;
|
||||
pub mod next_config;
|
||||
|
@ -23,7 +24,6 @@ mod web_entry_source;
|
|||
|
||||
pub use app_source::create_app_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 fn register() {
|
||||
|
@ -31,7 +31,7 @@ pub fn register() {
|
|||
turbo_tasks_fs::register();
|
||||
turbo_tasks_fetch::register();
|
||||
turbopack_dev_server::register();
|
||||
turbopack::register();
|
||||
turbopack_node::register();
|
||||
turbopack::register();
|
||||
include!(concat!(env!("OUT_DIR"), "/register.rs"));
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ use turbopack_core::asset::AssetContentVc;
|
|||
use turbopack_dev_server::source::{
|
||||
ContentSource, ContentSourceContent, ContentSourceData, ContentSourceResultVc, ContentSourceVc,
|
||||
};
|
||||
use turbopack_node::{
|
||||
node_api_source::NodeApiContentSourceVc, node_rendered_source::NodeRenderContentSourceVc,
|
||||
use turbopack_node::render::{
|
||||
node_api_source::NodeApiContentSourceVc, rendered_source::NodeRenderContentSourceVc,
|
||||
};
|
||||
|
||||
/// A content source which creates the next.js `_devPagesManifest.json` and
|
||||
|
@ -29,6 +29,7 @@ impl DevManifestContentSourceVc {
|
|||
while let Some(content_source) = queue.pop() {
|
||||
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? {
|
||||
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::{
|
||||
module_options::{
|
||||
module_options_context::{ModuleOptionsContext, ModuleOptionsContextVc},
|
||||
ModuleRule, ModuleRuleCondition, ModuleRuleEffect,
|
||||
ModuleRule, ModuleRuleCondition, ModuleRuleEffect, PostCssTransformOptions,
|
||||
},
|
||||
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
|
||||
transition::TransitionsByNameVc,
|
||||
|
@ -23,10 +23,12 @@ use turbopack_core::{
|
|||
};
|
||||
use turbopack_ecmascript::{EcmascriptInputTransform, EcmascriptInputTransformsVc};
|
||||
use turbopack_env::ProcessEnvAssetVc;
|
||||
use turbopack_node::execution_context::ExecutionContextVc;
|
||||
|
||||
use crate::{
|
||||
embed_js::attached_next_js_package_path,
|
||||
env::env_for_js,
|
||||
next_build::get_postcss_package_mapping,
|
||||
next_client::runtime_entry::{RuntimeEntriesVc, RuntimeEntry},
|
||||
next_config::NextConfigVc,
|
||||
next_import_map::{
|
||||
|
@ -63,12 +65,12 @@ pub enum ContextType {
|
|||
|
||||
#[turbo_tasks::function]
|
||||
pub fn get_client_resolve_options_context(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
ty: Value<ContextType>,
|
||||
) -> 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_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 {
|
||||
enable_typescript: true,
|
||||
enable_react: true,
|
||||
|
@ -86,13 +88,14 @@ pub fn get_client_resolve_options_context(
|
|||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn get_client_module_options_context(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
env: EnvironmentVc,
|
||||
ty: Value<ContextType>,
|
||||
) -> 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 =
|
||||
assert_can_resolve_react_refresh(project_root, resolve_options_context)
|
||||
assert_can_resolve_react_refresh(project_path, resolve_options_context)
|
||||
.await?
|
||||
.is_found();
|
||||
|
||||
|
@ -104,8 +107,13 @@ pub async fn get_client_module_options_context(
|
|||
enable_react_refresh,
|
||||
enable_styled_components: 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,
|
||||
preset_env_versions: Some(env),
|
||||
execution_context: Some(execution_context),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -173,13 +181,15 @@ pub async fn add_next_font_transform(
|
|||
|
||||
#[turbo_tasks::function]
|
||||
pub fn get_client_asset_context(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
browserslist_query: &str,
|
||||
ty: Value<ContextType>,
|
||||
) -> AssetContextVc {
|
||||
let environment = get_client_environment(browserslist_query);
|
||||
let resolve_options_context = get_client_resolve_options_context(project_root, ty);
|
||||
let module_options_context = get_client_module_options_context(project_root, environment, ty);
|
||||
let resolve_options_context = get_client_resolve_options_context(project_path, ty);
|
||||
let module_options_context =
|
||||
get_client_module_options_context(project_path, execution_context, environment, ty);
|
||||
|
||||
let context: AssetContextVc = ModuleAssetContextVc::new(
|
||||
TransitionsByNameVc::cell(HashMap::new()),
|
||||
|
@ -194,12 +204,12 @@ pub fn get_client_asset_context(
|
|||
|
||||
#[turbo_tasks::function]
|
||||
pub fn get_client_chunking_context(
|
||||
project_root: FileSystemPathVc,
|
||||
project_path: FileSystemPathVc,
|
||||
server_root: FileSystemPathVc,
|
||||
ty: Value<ContextType>,
|
||||
) -> ChunkingContextVc {
|
||||
DevChunkingContextVc::builder(
|
||||
project_root,
|
||||
project_path,
|
||||
server_root,
|
||||
match ty.into_value() {
|
||||
ContextType::Pages { .. } | ContextType::App { .. } => {
|
||||
|
|
|
@ -7,25 +7,25 @@ use turbo_tasks::{
|
|||
trace::TraceRawVcs,
|
||||
Value,
|
||||
};
|
||||
use turbo_tasks_fs::{FileSystemEntryType, FileSystemPathVc};
|
||||
use turbopack::{transition::TransitionsByNameVc, ModuleAssetContextVc};
|
||||
use turbo_tasks_fs::FileSystemEntryType;
|
||||
use turbopack::evaluate_context::node_evaluate_asset_context;
|
||||
use turbopack_core::{
|
||||
asset::Asset,
|
||||
environment::{EnvironmentIntention, EnvironmentVc, ExecutionEnvironment, NodeJsEnvironment},
|
||||
reference_type::{EntryReferenceSubType, ReferenceType},
|
||||
resolve::options::{ImportMap, ImportMapping},
|
||||
source_asset::SourceAssetVc,
|
||||
};
|
||||
use turbopack_ecmascript::{
|
||||
chunk::EcmascriptChunkPlaceablesVc, EcmascriptInputTransformsVc, EcmascriptModuleAssetType,
|
||||
EcmascriptModuleAssetVc,
|
||||
};
|
||||
use turbopack_node::evaluate::{evaluate, JavaScriptValue};
|
||||
|
||||
use crate::{
|
||||
embed_js::next_asset,
|
||||
next_server::{get_build_module_options_context, get_build_resolve_options_context},
|
||||
use turbopack_node::{
|
||||
evaluate::{evaluate, JavaScriptValue},
|
||||
execution_context::{ExecutionContext, ExecutionContextVc},
|
||||
};
|
||||
|
||||
use crate::embed_js::next_asset;
|
||||
|
||||
#[turbo_tasks::value(serialization = "custom")]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -201,24 +201,19 @@ impl NextConfigVc {
|
|||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn load_next_config(
|
||||
project_path: FileSystemPathVc,
|
||||
intermediate_output_path: FileSystemPathVc,
|
||||
) -> Result<NextConfigVc> {
|
||||
let context = ModuleAssetContextVc::new(
|
||||
TransitionsByNameVc::cell(Default::default()),
|
||||
EnvironmentVc::new(
|
||||
Value::new(ExecutionEnvironment::NodeJsBuildTime(
|
||||
NodeJsEnvironment::default().cell(),
|
||||
)),
|
||||
Value::new(EnvironmentIntention::Build),
|
||||
),
|
||||
get_build_module_options_context(),
|
||||
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();
|
||||
pub async fn load_next_config(execution_context: ExecutionContextVc) -> Result<NextConfigVc> {
|
||||
let ExecutionContext {
|
||||
project_root,
|
||||
intermediate_output_path,
|
||||
} = *execution_context.await?;
|
||||
let mut import_map = ImportMap::default();
|
||||
|
||||
import_map.insert_exact_alias("next", ImportMapping::External(None).into());
|
||||
import_map.insert_wildcard_alias("next/", ImportMapping::External(None).into());
|
||||
|
||||
let context = node_evaluate_asset_context(Some(import_map.cell()));
|
||||
let next_config_mjs_path = project_root.join("next.config.mjs").realpath();
|
||||
let next_config_js_path = project_root.join("next.config.js").realpath();
|
||||
let config_asset = if matches!(
|
||||
&*next_config_mjs_path.get_type().await?,
|
||||
FileSystemEntryType::File
|
||||
|
@ -246,19 +241,20 @@ pub async fn load_next_config(
|
|||
EcmascriptChunkPlaceablesVc::cell(vec![config_chunk])
|
||||
});
|
||||
let asset_path = config_asset
|
||||
.map_or(project_path, |a| a.path())
|
||||
.map_or(project_root, |a| a.path())
|
||||
.join("load-next-config.js");
|
||||
let load_next_config_asset = context.process(
|
||||
next_asset(asset_path, "entry/config/next.js"),
|
||||
Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)),
|
||||
);
|
||||
let config_value = evaluate(
|
||||
project_path,
|
||||
project_root,
|
||||
load_next_config_asset,
|
||||
project_path,
|
||||
project_root,
|
||||
context,
|
||||
intermediate_output_path,
|
||||
runtime_entries,
|
||||
vec![],
|
||||
)
|
||||
.await?;
|
||||
match &*config_value {
|
||||
|
|
|
@ -2,15 +2,17 @@ use turbo_tasks::{primitives::StringVc, Value};
|
|||
use turbo_tasks_env::ProcessEnvVc;
|
||||
use turbo_tasks_fs::FileSystemPathVc;
|
||||
use turbopack::{
|
||||
module_options::{ModuleOptionsContext, ModuleOptionsContextVc},
|
||||
module_options::{ModuleOptionsContext, ModuleOptionsContextVc, PostCssTransformOptions},
|
||||
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
|
||||
};
|
||||
use turbopack_core::environment::{
|
||||
EnvironmentIntention, EnvironmentVc, ExecutionEnvironment, NodeJsEnvironmentVc,
|
||||
};
|
||||
use turbopack_ecmascript::EcmascriptInputTransform;
|
||||
use turbopack_node::execution_context::ExecutionContextVc;
|
||||
|
||||
use crate::{
|
||||
next_build::get_postcss_package_mapping,
|
||||
next_client::context::add_next_font_transform,
|
||||
next_config::NextConfigVc,
|
||||
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]
|
||||
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() {
|
||||
ServerContextType::Pages { .. } => ModuleOptionsContext {
|
||||
enable_typescript_transform: 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()
|
||||
},
|
||||
ServerContextType::AppSSR { .. } => ModuleOptionsContext {
|
||||
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()
|
||||
},
|
||||
ServerContextType::AppRSC { .. } => ModuleOptionsContext {
|
||||
enable_postcss_transform: Some(PostCssTransformOptions {
|
||||
postcss_package: Some(get_postcss_package_mapping(project_path)),
|
||||
..Default::default()
|
||||
}),
|
||||
enable_typescript_transform: true,
|
||||
custom_ecmascript_transforms: vec![EcmascriptInputTransform::ClientDirective(
|
||||
StringVc::cell("server-to-client".to_string()),
|
||||
)],
|
||||
execution_context: Some(execution_context),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
|
|
|
@ -31,9 +31,11 @@ use turbopack_ecmascript::{
|
|||
};
|
||||
use turbopack_env::ProcessEnvAssetVc;
|
||||
use turbopack_node::{
|
||||
create_node_api_source, create_node_rendered_source,
|
||||
node_entry::{NodeRenderingEntry, NodeRenderingEntryVc},
|
||||
NodeEntry, NodeEntryVc,
|
||||
execution_context::ExecutionContextVc,
|
||||
render::{
|
||||
node_api_source::create_node_api_source, rendered_source::create_node_rendered_source,
|
||||
},
|
||||
NodeEntry, NodeEntryVc, NodeRenderingEntry, NodeRenderingEntryVc,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -61,14 +63,15 @@ use crate::{
|
|||
/// Next.js pages folder.
|
||||
#[turbo_tasks::function]
|
||||
pub async fn create_server_rendered_source(
|
||||
project_path: FileSystemPathVc,
|
||||
project_root: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
output_path: FileSystemPathVc,
|
||||
server_root: FileSystemPathVc,
|
||||
env: ProcessEnvVc,
|
||||
browserslist_query: &str,
|
||||
next_config: NextConfigVc,
|
||||
) -> 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 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_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 =
|
||||
add_next_transforms_to_pages(client_module_options_context, pages_dir);
|
||||
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(
|
||||
TransitionsByNameVc::cell(transitions),
|
||||
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),
|
||||
)
|
||||
.into();
|
||||
|
@ -131,6 +134,7 @@ pub async fn create_server_rendered_source(
|
|||
|
||||
let fallback_page = get_fallback_page(
|
||||
project_path,
|
||||
execution_context,
|
||||
server_root,
|
||||
env,
|
||||
browserslist_query,
|
||||
|
|
|
@ -12,6 +12,7 @@ use turbopack_dev_server::{
|
|||
html::DevHtmlAssetVc,
|
||||
source::{asset_graph::AssetGraphContentSourceVc, ContentSourceVc},
|
||||
};
|
||||
use turbopack_node::execution_context::ExecutionContextVc;
|
||||
|
||||
use crate::{
|
||||
embed_js::wrap_with_next_js_fs,
|
||||
|
@ -25,6 +26,7 @@ use crate::{
|
|||
#[turbo_tasks::function]
|
||||
pub async fn create_web_entry_source(
|
||||
project_root: FileSystemPathVc,
|
||||
execution_context: ExecutionContextVc,
|
||||
entry_requests: Vec<RequestVc>,
|
||||
server_root: FileSystemPathVc,
|
||||
env: ProcessEnvVc,
|
||||
|
@ -35,7 +37,7 @@ pub async fn create_web_entry_source(
|
|||
let project_root = wrap_with_next_js_fs(project_root);
|
||||
|
||||
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 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-core = { path = "../turbopack-core" }
|
||||
turbopack-dev-server = { path = "../turbopack-dev-server" }
|
||||
turbopack-node = { path = "../turbopack-node" }
|
||||
webbrowser = "0.7.1"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -19,7 +19,7 @@ use devserver_options::DevServerOptions;
|
|||
use next_core::{
|
||||
create_app_source, create_server_rendered_source, create_web_entry_source, env::load_env,
|
||||
manifest::DevManifestContentSource, next_config::load_next_config,
|
||||
next_image::NextImageContentSourceVc, source_map::NextSourceMapTraceContentSourceVc,
|
||||
next_image::NextImageContentSourceVc,
|
||||
};
|
||||
use owo_colors::OwoColorize;
|
||||
use turbo_malloc::TurboMalloc;
|
||||
|
@ -44,6 +44,9 @@ use turbopack_dev_server::{
|
|||
},
|
||||
DevServer,
|
||||
};
|
||||
use turbopack_node::{
|
||||
execution_context::ExecutionContextVc, source_map::NextSourceMapTraceContentSourceVc,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum EntryRequest {
|
||||
|
@ -276,8 +279,11 @@ async fn source(
|
|||
let project_path = fs.root().join(project_relative);
|
||||
|
||||
let env = load_env(project_path);
|
||||
let config_output_root = output_fs.root().join(".next/config");
|
||||
let next_config = load_next_config(project_path, config_output_root);
|
||||
let build_output_root = output_fs.root().join(".next/build");
|
||||
|
||||
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");
|
||||
|
||||
|
@ -295,6 +301,7 @@ async fn source(
|
|||
|
||||
let web_source = create_web_entry_source(
|
||||
project_path,
|
||||
execution_context,
|
||||
entry_requests,
|
||||
dev_server_root,
|
||||
env,
|
||||
|
@ -304,6 +311,7 @@ async fn source(
|
|||
);
|
||||
let rendered_source = create_server_rendered_source(
|
||||
project_path,
|
||||
execution_context,
|
||||
output_root.join("pages"),
|
||||
dev_server_root,
|
||||
env,
|
||||
|
@ -312,6 +320,7 @@ async fn source(
|
|||
);
|
||||
let app_source = create_app_source(
|
||||
project_path,
|
||||
execution_context,
|
||||
output_root.join("app"),
|
||||
dev_server_root,
|
||||
env,
|
||||
|
|
|
@ -146,6 +146,9 @@ async fn run_test(resource: &str) -> JestRunResult {
|
|||
.eager_compile(false)
|
||||
.hostname(requested_addr.ip())
|
||||
.port(requested_addr.port())
|
||||
.log_level(turbopack_core::issue::IssueSeverity::Warning)
|
||||
.log_detail(true)
|
||||
.show_all(true)
|
||||
.build()
|
||||
.await
|
||||
.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,
|
||||
"devDependencies": {
|
||||
"@turbo/pack-test-harness": "*",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"next": "13.0.1",
|
||||
"postcss": "^8.4.20",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^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