Skip to content

Commit

Permalink
feat: mini-css-extract-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
JSerFeng committed Apr 7, 2024
1 parent 73d1234 commit e943f5e
Show file tree
Hide file tree
Showing 45 changed files with 2,740 additions and 96 deletions.
23 changes: 23 additions & 0 deletions Cargo.lock

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

15 changes: 14 additions & 1 deletion crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ export enum BuiltinPluginName {
SwcJsMinimizerRspackPlugin = 'SwcJsMinimizerRspackPlugin',
SwcCssMinimizerRspackPlugin = 'SwcCssMinimizerRspackPlugin',
BundlerInfoRspackPlugin = 'BundlerInfoRspackPlugin',
JsLoaderRspackPlugin = 'JsLoaderRspackPlugin'
JsLoaderRspackPlugin = 'JsLoaderRspackPlugin',
CssExtractPlugin = 'CssExtractPlugin'
}

export function cleanupGlobalTrace(): void
Expand Down Expand Up @@ -740,6 +741,17 @@ export interface RawCssAutoParserOptions {
namedExports?: boolean
}

export interface RawCssExtractPluginOption {
filename: string
chunkFilename: string
ignoreOrder: boolean
insert?: string
attributes: Record<string, string>
linkType?: string
runtime: boolean
pathinfo: boolean
}

export interface RawCssGeneratorOptions {
exportsConvention?: "as-is" | "camel-case" | "camel-case-only" | "dashes" | "dashes-only"
exportsOnly?: boolean
Expand Down Expand Up @@ -1235,6 +1247,7 @@ export interface RawSplitChunksOptions {
automaticNameDelimiter?: string
maxAsyncRequests?: number
maxInitialRequests?: number
defaultSizeTypes: Array<string>
minChunks?: number
hidePathInfo?: boolean
minSize?: number
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_binding_options/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ rspack_plugin_devtool = { path = "../rspack_plugin_devtool" }
rspack_plugin_ensure_chunk_conditions = { path = "../rspack_plugin_ensure_chunk_conditions" }
rspack_plugin_entry = { path = "../rspack_plugin_entry" }
rspack_plugin_externals = { path = "../rspack_plugin_externals" }
rspack_plugin_extract_css = { path = "../rspack_plugin_extract_css" }
rspack_plugin_hmr = { path = "../rspack_plugin_hmr" }
rspack_plugin_html = { path = "../rspack_plugin_html" }
rspack_plugin_javascript = { path = "../rspack_plugin_javascript" }
Expand Down
10 changes: 10 additions & 0 deletions crates/rspack_binding_options/src/options/raw_builtins/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod raw_banner;
mod raw_bundle_info;
mod raw_copy;
mod raw_css_extract;
mod raw_html;
mod raw_limit_chunk_count;
mod raw_mf;
Expand Down Expand Up @@ -68,6 +69,7 @@ pub use self::{
};
use self::{
raw_bundle_info::{RawBundlerInfoModeWrapper, RawBundlerInfoPluginOptions},
raw_css_extract::RawCssExtractPluginOption,
raw_mf::{RawConsumeSharedPluginOptions, RawContainerReferencePluginOptions, RawProvideOptions},
};
use crate::{
Expand Down Expand Up @@ -144,6 +146,7 @@ pub enum BuiltinPluginName {
// rspack js adapter plugins
// naming format follow XxxRspackPlugin
JsLoaderRspackPlugin,
CssExtractPlugin,
}

#[napi(object)]
Expand Down Expand Up @@ -408,6 +411,13 @@ impl BuiltinPlugin {
JsLoaderResolverPlugin::new(downcast_into::<JsLoaderRunner>(self.options)?).boxed(),
);
}
BuiltinPluginName::CssExtractPlugin => {
let plugin = rspack_plugin_extract_css::plugin::PluginCssExtract::new(
downcast_into::<RawCssExtractPluginOption>(self.options)?.into(),
)
.boxed();
plugins.push(plugin);
}
}
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::collections::HashMap;

use napi_derive::napi;
use rspack_plugin_extract_css::plugin::{CssExtractOptions, InsertType};

#[napi(object)]
pub struct RawCssExtractPluginOption {
pub filename: String,
pub chunk_filename: String,
pub ignore_order: bool,
pub insert: Option<String>,
pub attributes: HashMap<String, String>,
pub link_type: Option<String>,
pub runtime: bool,
pub pathinfo: bool,
}

impl From<RawCssExtractPluginOption> for CssExtractOptions {
fn from(value: RawCssExtractPluginOption) -> Self {
Self {
filename: value.filename,
chunk_filename: value.chunk_filename,
ignore_order: value.ignore_order,
insert: value
.insert
.map(|insert| {
if insert.starts_with("function") || insert.starts_with('(') {
InsertType::Fn(insert)
} else {
InsertType::Selector(insert)
}
})
.unwrap_or(InsertType::Default),
attributes: value.attributes.into_iter().collect(),
link_type: value.link_type,
runtime: value.runtime,
pathinfo: value.pathinfo,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub struct RawSplitChunksOptions {
pub automatic_name_delimiter: Option<String>,
pub max_async_requests: Option<u32>,
pub max_initial_requests: Option<u32>,
// pub default_size_types: Option<Vec<SizeType>>,
pub default_size_types: Vec<String>,
pub min_chunks: Option<u32>,
pub hide_path_info: Option<bool>,
pub min_size: Option<f64>,
Expand Down Expand Up @@ -115,7 +115,11 @@ impl From<RawSplitChunksOptions> for rspack_plugin_split_chunks::PluginOptions {
normalize_raw_chunk_name(name)
});

let default_size_types = [SourceType::JavaScript, SourceType::Unknown];
let default_size_types = raw_opts
.default_size_types
.into_iter()
.map(|size_type| SourceType::from(size_type.as_str()))
.collect::<Vec<_>>();

let create_sizes = |size: Option<f64>| {
size
Expand Down
3 changes: 1 addition & 2 deletions crates/rspack_binding_values/src/chunk_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ pub fn get_chunk_modules_iterable_by_source_type(
.chunk_graph
.get_chunk_modules_iterable_by_source_type(
&ChunkUkey::from(js_chunk_ukey as usize),
SourceType::try_from(source_type.as_str())
.map_err(|e| napi::Error::from_reason(e.to_string()))?,
SourceType::from(source_type.as_str()),
&compilation.get_module_graph(),
)
.filter_map(|module| module.to_js_module().ok())
Expand Down
34 changes: 15 additions & 19 deletions crates/rspack_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ pub enum SourceType {
Remote,
ShareInit,
ConsumeShared,
Custom(Ustr),
#[default]
Unknown,
CssImport,
Expand All @@ -130,30 +131,25 @@ impl std::fmt::Display for SourceType {
SourceType::ConsumeShared => write!(f, "consume-shared"),
SourceType::Unknown => write!(f, "unknown"),
SourceType::CssImport => write!(f, "css-import"),
SourceType::Custom(source_type) => f.write_str(source_type),
}
}
}

impl TryFrom<&str> for SourceType {
type Error = rspack_error::Error;

fn try_from(value: &str) -> Result<Self, Self::Error> {
impl From<&str> for SourceType {
fn from(value: &str) -> Self {
match value {
"javascript" => Ok(Self::JavaScript),
"css" => Ok(Self::Css),
"wasm" => Ok(Self::Wasm),
"asset" => Ok(Self::Asset),
"expose" => Ok(Self::Expose),
"remote" => Ok(Self::Remote),
"share-init" => Ok(Self::ShareInit),
"consume-shared" => Ok(Self::ConsumeShared),
"unknown" => Ok(Self::Unknown),
"css-import" => Ok(Self::CssImport),

_ => {
use rspack_error::error;
Err(error!("invalid source type: {value}"))
}
"javascript" => Self::JavaScript,
"css" => Self::Css,
"wasm" => Self::Wasm,
"asset" => Self::Asset,
"expose" => Self::Expose,
"remote" => Self::Remote,
"share-init" => Self::ShareInit,
"consume-shared" => Self::ConsumeShared,
"unknown" => Self::Unknown,
"css-import" => Self::CssImport,
other => SourceType::Custom(other.into()),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/rspack_core/src/plugin/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rspack_error::{IntoTWithDiagnosticArray, Result, TWithDiagnosticArray};
use rspack_hash::RspackHashDigest;
use rspack_loader_runner::{Content, LoaderContext, ResourceData};
use rspack_sources::BoxSource;
use rustc_hash::FxHashMap;
use rspack_util::fx_dashmap::FxDashMap;

use crate::{
AdditionalChunkRuntimeRequirementsArgs, AdditionalModuleRequirementsArgs, AssetInfo, BoxLoader,
Expand Down Expand Up @@ -319,7 +319,7 @@ pub type BoxedParserAndGeneratorBuilder = Box<

pub struct ApplyContext<'c> {
pub(crate) registered_parser_and_generator_builder:
&'c mut FxHashMap<ModuleType, BoxedParserAndGeneratorBuilder>,
&'c mut FxDashMap<ModuleType, BoxedParserAndGeneratorBuilder>,
pub compiler_hooks: &'c mut CompilerHooks,
pub compilation_hooks: &'c mut CompilationHooks,
pub normal_module_factory_hooks: &'c mut NormalModuleFactoryHooks,
Expand Down
6 changes: 4 additions & 2 deletions crates/rspack_core/src/plugin/plugin_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{

use rspack_error::{Diagnostic, Result, TWithDiagnosticArray};
use rspack_loader_runner::{LoaderContext, ResourceData};
use rspack_util::fx_dashmap::FxDashMap;
use rustc_hash::FxHashMap as HashMap;
use tracing::instrument;

Expand All @@ -28,7 +29,8 @@ pub struct PluginDriver {
pub plugins: Vec<Box<dyn Plugin>>,
pub resolver_factory: Arc<ResolverFactory>,
// pub registered_parser: HashMap<ModuleType, BoxedParser>,
pub registered_parser_and_generator_builder: HashMap<ModuleType, BoxedParserAndGeneratorBuilder>,
pub registered_parser_and_generator_builder:
FxDashMap<ModuleType, BoxedParserAndGeneratorBuilder>,
/// Collecting error generated by plugin phase, e.g., `Syntax Error`
pub diagnostics: Arc<Mutex<Vec<Diagnostic>>>,
pub compiler_hooks: CompilerHooks,
Expand Down Expand Up @@ -59,7 +61,7 @@ impl PluginDriver {
let mut compilation_hooks = Default::default();
let mut normal_module_factory_hooks = Default::default();
let mut context_module_factory_hooks = Default::default();
let mut registered_parser_and_generator_builder = HashMap::default();
let mut registered_parser_and_generator_builder = FxDashMap::default();
let mut apply_context = ApplyContext {
registered_parser_and_generator_builder: &mut registered_parser_and_generator_builder,
compiler_hooks: &mut compiler_hooks,
Expand Down
65 changes: 52 additions & 13 deletions crates/rspack_plugin_css/src/plugin/impl_plugin_for_css_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rspack_core::{
LibIdentOptions, PluginContext, PluginRuntimeRequirementsInTreeOutput, PublicPath,
RuntimeGlobals, RuntimeRequirementsInTreeArgs,
};
use rspack_error::{IntoTWithDiagnosticArray, Result};
use rspack_error::{Diagnostic, IntoTWithDiagnosticArray, Result};
use rspack_hash::RspackHash;
use rspack_hook::{plugin_hook, AsyncSeries2};
use rspack_plugin_runtime::is_enabled_for_chunk;
Expand Down Expand Up @@ -228,7 +228,7 @@ impl Plugin for CssPlugin {
let compilation = &args.compilation;
let chunk = compilation.chunk_by_ukey.expect_get(&args.chunk_ukey);
let module_graph = compilation.get_module_graph();
let ordered_modules = Self::get_ordered_chunk_css_modules(
let (ordered_modules, _) = Self::get_ordered_chunk_css_modules(
chunk,
&compilation.chunk_graph,
&module_graph,
Expand Down Expand Up @@ -270,7 +270,7 @@ impl Plugin for CssPlugin {
return Ok(vec![].with_empty_diagnostic());
}
let module_graph = compilation.get_module_graph();
let ordered_css_modules = Self::get_ordered_chunk_css_modules(
let (ordered_css_modules, conflicts) = Self::get_ordered_chunk_css_modules(
chunk,
&compilation.chunk_graph,
&module_graph,
Expand Down Expand Up @@ -317,16 +317,55 @@ impl Plugin for CssPlugin {
} else {
source.boxed()
};
Ok(
vec![RenderManifestEntry::new(
source.boxed(),
output_path,
asset_info,
false,
false,
)]
.with_empty_diagnostic(),
)
Ok({
if let Some(conflicts) = conflicts {
vec![RenderManifestEntry::new(
source.boxed(),
output_path,
asset_info,
false,
false,
)]
.with_diagnostic(
conflicts
.into_iter()
.map(|conflict| {
let chunk = conflict.chunk.as_ref(&compilation.chunk_by_ukey);
let mg = compilation.get_module_graph();

let failed_module = mg
.module_by_identifier(&conflict.failed_module)
.expect("should have module");
let selected_module = mg
.module_by_identifier(&conflict.selected_module)
.expect("should have module");

Diagnostic::warn(
"Conflicting order".into(),
format!(
"chunk {}\nConflicting order between {} and {}",
chunk
.name
.as_ref()
.unwrap_or(chunk.id.as_ref().expect("should have chunk id")),
failed_module.readable_identifier(&compilation.options.context),
selected_module.readable_identifier(&compilation.options.context)
),
)
})
.collect(),
)
} else {
vec![RenderManifestEntry::new(
source.boxed(),
output_path,
asset_info,
false,
false,
)]
.with_empty_diagnostic()
}
})
}

async fn runtime_requirements_in_tree(
Expand Down
Loading

0 comments on commit e943f5e

Please sign in to comment.