add basic webpack loader support (vercel/turbo#3284)

add the minimum to run a simple raw-loader (see test case)

* add `experimental.turbopackWebpackLoaders` to next.config.js
* key is extension like `".mdx"`, value is an array of loaders like
`["mdx-loader"]`
This commit is contained in:
Tobias Koppers 2023-01-12 21:07:03 +01:00 committed by GitHub
parent 2df0f4838e
commit ccce2d48fb
9 changed files with 48 additions and 5 deletions

View file

@ -127,6 +127,7 @@ pub async fn get_client_module_options_context(
postcss_package: Some(get_postcss_package_mapping(project_path)),
..Default::default()
}),
enable_webpack_loaders: next_config.webpack_loaders_options().await?.clone_if(),
enable_typescript_transform: true,
rules: vec![(
foreign_code_context_condition(next_config).await?,

View file

@ -1,13 +1,17 @@
use std::collections::HashMap;
use anyhow::Result;
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use turbo_tasks::{
primitives::{BoolVc, StringsVc},
trace::TraceRawVcs,
Value,
};
use turbopack::evaluate_context::node_evaluate_asset_context;
use turbopack::{
evaluate_context::node_evaluate_asset_context,
module_options::{WebpackLoadersOptions, WebpackLoadersOptionsVc},
};
use turbopack_core::{
asset::Asset,
reference_type::{EntryReferenceSubType, ReferenceType},
@ -127,11 +131,12 @@ pub enum RemotePatternProtocal {
Https,
}
#[derive(Clone, Debug, Ord, PartialOrd, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)]
#[serde(rename_all = "camelCase")]
pub struct ExperimentalConfig {
pub server_components_external_packages: Option<Vec<String>>,
pub app_dir: Option<bool>,
pub turbopack_webpack_loaders: Option<IndexMap<String, Vec<String>>>,
}
#[derive(Clone, Debug, Ord, PartialOrd, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)]
@ -209,6 +214,23 @@ impl NextConfigVc {
self.await?.transpile_packages.clone().unwrap_or_default(),
))
}
#[turbo_tasks::function]
pub async fn webpack_loaders_options(self) -> Result<WebpackLoadersOptionsVc> {
let this = self.await?;
let Some(turbopack_webpack_loaders) = this.experimental.as_ref().and_then(|experimental| experimental.turbopack_webpack_loaders.as_ref()) else {
return Ok(WebpackLoadersOptionsVc::cell(WebpackLoadersOptions::default()));
};
let mut extension_to_loaders = IndexMap::new();
for (ext, loaders) in turbopack_webpack_loaders {
extension_to_loaders.insert(ext.clone(), StringsVc::cell(loaders.clone()));
}
Ok(WebpackLoadersOptions {
extension_to_loaders,
..Default::default()
}
.cell())
}
}
fn next_configs() -> StringsVc {

View file

@ -118,6 +118,7 @@ pub async fn get_server_module_options_context(
postcss_package: Some(get_postcss_package_mapping(project_path)),
..Default::default()
}),
enable_webpack_loaders: next_config.webpack_loaders_options().await?.clone_if(),
enable_typescript_transform: true,
rules: vec![(
foreign_code_context_condition(next_config).await?,
@ -138,6 +139,7 @@ pub async fn get_server_module_options_context(
postcss_package: Some(get_postcss_package_mapping(project_path)),
..Default::default()
}),
enable_webpack_loaders: next_config.webpack_loaders_options().await?.clone_if(),
enable_typescript_transform: true,
rules: vec![(
foreign_code_context_condition(next_config).await?,
@ -160,6 +162,7 @@ pub async fn get_server_module_options_context(
postcss_package: Some(get_postcss_package_mapping(project_path)),
..Default::default()
}),
enable_webpack_loaders: next_config.webpack_loaders_options().await?.clone_if(),
enable_typescript_transform: true,
rules: vec![(
foreign_code_context_condition(next_config).await?,

View file

@ -35,9 +35,9 @@ use turbopack_core::{
environment::ServerAddr,
issue::IssueSeverity,
resolve::{parse::RequestVc, pattern::QueryMapVc},
server_fs::ServerFileSystemVc,
};
use turbopack_dev_server::{
fs::DevServerFileSystemVc,
introspect::IntrospectionSource,
source::{
combined::CombinedContentSourceVc, router::RouterContentSource,
@ -279,7 +279,7 @@ async fn source(
let output_root = output_fs.root().join(".next/server");
let server_addr = ServerAddr::new(*server_addr).cell();
let dev_server_fs = DevServerFileSystemVc::new().as_file_system();
let dev_server_fs = ServerFileSystemVc::new().as_file_system();
let dev_server_root = dev_server_fs.root();
let entry_requests = entry_requests
.iter()

View file

@ -0,0 +1,5 @@
import source from "./hello.raw";
it("runs a simple loader", () => {
expect(source).toBe("Hello World");
});

View file

@ -0,0 +1,7 @@
module.exports = {
experimental: {
turbopackWebpackLoaders: {
".raw": ["raw-loader"],
},
},
};

View file

@ -0,0 +1,3 @@
module.exports = async (source) => {
return `export default ${JSON.stringify(source.trim())};`
}

View file

@ -4,11 +4,12 @@
"devDependencies": {
"@turbo/pack-test-harness": "*",
"autoprefixer": "^10.4.13",
"loader-runner": "^4.3.0",
"next": "13.0.8-canary.2",
"postcss": "^8.4.20",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-test-renderer": "^18.2.0",
"react": "^18.2.0",
"styled-jsx": "^5.1.0",
"tailwindcss": "^3.2.4"
}