Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support test, include and exclude options for SwcCssMinimizerRspackPlugin #7111

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,12 @@ export interface RawStatsOptions {
colors: boolean
}

export interface RawSwcCssMinimizerRspackPluginOptions {
test?: string | RegExp | (string | RegExp)[]
include?: string | RegExp | (string | RegExp)[]
exclude?: string | RegExp | (string | RegExp)[]
}

export interface RawSwcJsMinimizerRspackPluginOptions {
extractComments?: RawExtractComments
compress: any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ mod raw_mf;
mod raw_progress;
mod raw_runtime_chunk;
mod raw_size_limits;
mod raw_swc_css_minimizer;
mod raw_swc_js_minimizer;

use napi::{bindgen_prelude::FromNapiValue, Env, JsUnknown};
use napi_derive::napi;
use raw_lightning_css_minimizer::RawLightningCssMinimizerRspackPluginOptions;
use raw_swc_css_minimizer::RawSwcCssMinimizerRspackPluginOptions;
use rspack_core::{BoxPlugin, Plugin, PluginExt};
use rspack_error::Result;
use rspack_ids::{
Expand Down Expand Up @@ -447,7 +449,11 @@ impl BuiltinPlugin {
plugins.push(plugin);
}
BuiltinPluginName::SwcCssMinimizerRspackPlugin => {
plugins.push(SwcCssMinimizerRspackPlugin::default().boxed())
let plugin = SwcCssMinimizerRspackPlugin::new(
downcast_into::<RawSwcCssMinimizerRspackPluginOptions>(self.options)?.try_into()?,
)
.boxed();
plugins.push(plugin);
}
BuiltinPluginName::LightningCssMinimizerRspackPlugin => plugins.push(
LightningCssMinimizerRspackPlugin::new(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use napi::{bindgen_prelude::Either3, Either};
use napi_derive::napi;
use rspack_error::Result;
use rspack_napi::regexp::{JsRegExp, JsRegExpExt};
use rspack_plugin_swc_css_minimizer::{
SwcCssMinimizerRspackPluginOptions, SwcCssMinimizerRule, SwcCssMinimizerRules,
};

type RawSwcCssMinimizerRule = Either<String, JsRegExp>;
type RawSwcCssMinimizerRules = Either3<String, JsRegExp, Vec<RawSwcCssMinimizerRule>>;
struct RawSwcCssMinimizerRuleWrapper(RawSwcCssMinimizerRule);
struct RawSwcCssMinimizerRulesWrapper(RawSwcCssMinimizerRules);

#[derive(Debug)]
#[napi(object, object_to_js = false)]
pub struct RawSwcCssMinimizerRspackPluginOptions {
#[napi(ts_type = "string | RegExp | (string | RegExp)[]")]
pub test: Option<RawSwcCssMinimizerRules>,
#[napi(ts_type = "string | RegExp | (string | RegExp)[]")]
pub include: Option<RawSwcCssMinimizerRules>,
#[napi(ts_type = "string | RegExp | (string | RegExp)[]")]
pub exclude: Option<RawSwcCssMinimizerRules>,
}

fn into_condition(c: Option<RawSwcCssMinimizerRules>) -> Option<SwcCssMinimizerRules> {
c.map(|test| RawSwcCssMinimizerRulesWrapper(test).into())
}

impl TryFrom<RawSwcCssMinimizerRspackPluginOptions> for SwcCssMinimizerRspackPluginOptions {
type Error = rspack_error::Error;

fn try_from(value: RawSwcCssMinimizerRspackPluginOptions) -> Result<Self> {
Ok(Self {
test: into_condition(value.test),
include: into_condition(value.include),
exclude: into_condition(value.exclude),
})
}
}

impl From<RawSwcCssMinimizerRuleWrapper> for SwcCssMinimizerRule {
fn from(x: RawSwcCssMinimizerRuleWrapper) -> Self {
match x.0 {
Either::A(v) => Self::String(v),
Either::B(v) => Self::Regexp(v.to_rspack_regex()),
}
}
}

impl From<RawSwcCssMinimizerRulesWrapper> for SwcCssMinimizerRules {
fn from(value: RawSwcCssMinimizerRulesWrapper) -> Self {
match value.0 {
Either3::A(v) => Self::String(v),
Either3::B(v) => Self::Regexp(v.to_rspack_regex()),
Either3::C(v) => Self::Array(
v.into_iter()
.map(|v| RawSwcCssMinimizerRuleWrapper(v).into())
.collect(),
),
}
}
}
2 changes: 2 additions & 0 deletions crates/rspack_plugin_swc_css_minimizer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ rspack_error = { path = "../rspack_error" }
rspack_hook = { path = "../rspack_hook" }
swc_core = { workspace = true, features = ["css_codegen", "css_parser", "css_minifier"] }
tracing = { workspace = true }
rspack_regex = { path = "../rspack_regex" }
rspack_util = { path = "../rspack_util" }

[package.metadata.cargo-shear]
ignored = ["tracing"]
87 changes: 85 additions & 2 deletions crates/rspack_plugin_swc_css_minimizer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,53 @@ use regex::Regex;
use rspack_core::{rspack_sources::MapOptions, Compilation, CompilationProcessAssets, Plugin};
use rspack_error::Result;
use rspack_hook::{plugin, plugin_hook};
use rspack_regex::RspackRegex;
use rspack_util::try_any_sync;
use swc_css_compiler::{SwcCssCompiler, SwcCssSourceMapGenConfig};

static CSS_ASSET_REGEXP: Lazy<Regex> =
Lazy::new(|| Regex::new(r"\.css(\?.*)?$").expect("Invalid RegExp"));

#[derive(Debug, Default)]
pub struct SwcCssMinimizerRspackPluginOptions {
pub test: Option<SwcCssMinimizerRules>,
pub include: Option<SwcCssMinimizerRules>,
pub exclude: Option<SwcCssMinimizerRules>,
}


#[plugin]
#[derive(Debug, Default)]
pub struct SwcCssMinimizerRspackPlugin;
pub struct SwcCssMinimizerRspackPlugin {
options: SwcCssMinimizerRspackPluginOptions,
}

impl SwcCssMinimizerRspackPlugin {
pub fn new(options: SwcCssMinimizerRspackPluginOptions) -> Self {
Self::new_inner(options)
}
}

#[plugin_hook(CompilationProcessAssets for SwcCssMinimizerRspackPlugin, stage = Compilation::PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE)]
async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> {
let minify_options = &self.options;

compilation
.assets_mut()
.par_iter_mut()
.filter(|(filename, _)| CSS_ASSET_REGEXP.is_match(filename))
.filter(|(filename, original)| {
if !CSS_ASSET_REGEXP.is_match(filename) {
return false;
}

let is_matched = match_object(minify_options, filename).unwrap_or(false);

if !is_matched || original.get_info().minimized {
return false;
}

true
})
.try_for_each(|(filename, original)| -> Result<()> {
if original.get_info().minimized {
return Ok(());
Expand Down Expand Up @@ -69,3 +101,54 @@ impl Plugin for SwcCssMinimizerRspackPlugin {

// TODO: chunk hash
}

#[derive(Debug, Clone, Hash)]
pub enum SwcCssMinimizerRule {
String(String),
Regexp(RspackRegex),
}

impl SwcCssMinimizerRule {
pub fn try_match(&self, data: &str) -> rspack_error::Result<bool> {
match self {
Self::String(s) => Ok(data.starts_with(s)),
Self::Regexp(r) => Ok(r.test(data)),
}
}
}

#[derive(Debug, Clone, Hash)]
pub enum SwcCssMinimizerRules {
String(String),
Regexp(rspack_regex::RspackRegex),
Array(Vec<SwcCssMinimizerRule>),
}

impl SwcCssMinimizerRules {
pub fn try_match(&self, data: &str) -> rspack_error::Result<bool> {
match self {
Self::String(s) => Ok(data.starts_with(s)),
Self::Regexp(r) => Ok(r.test(data)),
Self::Array(l) => try_any_sync(l, |i| i.try_match(data)),
}
}
}

pub fn match_object(obj: &SwcCssMinimizerRspackPluginOptions, str: &str) -> Result<bool> {
if let Some(condition) = &obj.test {
if !condition.try_match(str)? {
return Ok(false);
}
}
if let Some(condition) = &obj.include {
if !condition.try_match(str)? {
return Ok(false);
}
}
if let Some(condition) = &obj.exclude {
if condition.try_match(str)? {
return Ok(false);
}
}
Ok(true)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
html {
margin: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require("./a.css");
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
html {
margin: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require("./b.css");
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const fs = require("fs");
const path = require("path");

it("[minify-exclude-css]: chunk a should be minified", () => {
const content = fs.readFileSync(path.resolve(__dirname, "a.css"), "utf-8");
expect(content).not.toMatch("\n");
});

it("[minify-exclude-css]: chunk b should not be minified", () => {
const content = fs.readFileSync(path.resolve(__dirname, "b.css"), "utf-8");
expect(content).toMatch("\n");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const rspack = require("@rspack/core");
/**
* @type {import("@rspack/core").Configuration}
*/
module.exports = {
entry: {
a: "./a.js",
b: "./b.js",
main: "./index.js"
},
output: {
filename: "[name].js"
},
module: {
generator: {
"css/auto": {
exportsOnly: false
}
}
},
optimization: {
minimize: true,
minimizer: [
new rspack.SwcCssMinimizerRspackPlugin({
exclude: [/b\.css/]
})
]
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import("../../../..").TConfigCaseConfig} */
module.exports = {
findBundle: (i, options) => {
return ["main.js"];
}
};
17 changes: 15 additions & 2 deletions packages/rspack/etc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5004,9 +5004,15 @@ const matchPart: (str: string, test: Matcher) => boolean;
// @public (undocumented)
type MinifyCondition = string | RegExp;

// @public (undocumented)
type MinifyCondition_2 = string | RegExp;

// @public (undocumented)
type MinifyConditions = MinifyCondition | MinifyCondition[];

// @public (undocumented)
type MinifyConditions_2 = MinifyCondition_2 | MinifyCondition_2[];

// @public (undocumented)
export type Mode = z.infer<typeof mode>;

Expand Down Expand Up @@ -13143,15 +13149,22 @@ const strictModuleExceptionHandling: z.ZodBoolean;

// @public (undocumented)
export const SwcCssMinimizerRspackPlugin: {
new (options?: any): {
new (options?: SwcCssMinimizerRspackPluginOptions | undefined): {
name: BuiltinPluginName;
_args: [options?: any];
_args: [options?: SwcCssMinimizerRspackPluginOptions | undefined];
affectedHooks: "done" | "compilation" | "failed" | "environment" | "emit" | "make" | "compile" | "afterEmit" | "invalid" | "thisCompilation" | "afterDone" | "normalModuleFactory" | "contextModuleFactory" | "initialize" | "shouldEmit" | "infrastructureLog" | "beforeRun" | "run" | "assetEmitted" | "shutdown" | "watchRun" | "watchClose" | "afterEnvironment" | "afterPlugins" | "afterResolvers" | "beforeCompile" | "afterCompile" | "finishMake" | "entryOption" | undefined;
raw(compiler: Compiler_2): BuiltinPlugin;
apply(compiler: Compiler_2): void;
};
};

// @public (undocumented)
type SwcCssMinimizerRspackPluginOptions = {
test?: MinifyConditions_2;
exclude?: MinifyConditions_2;
include?: MinifyConditions_2;
};

// @public (undocumented)
export const SwcJsMinimizerRspackPlugin: {
new (options?: SwcJsMinimizerRspackPluginOptions | undefined): {
Expand Down
24 changes: 22 additions & 2 deletions packages/rspack/src/builtin-plugin/SwcCssMinimizerPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
import { BuiltinPluginName } from "@rspack/binding";
import {
BuiltinPluginName,
RawSwcCssMinimizerRspackPluginOptions
} from "@rspack/binding";

import { create } from "./base";

type MinifyCondition = string | RegExp;
type MinifyConditions = MinifyCondition | MinifyCondition[];

export type SwcCssMinimizerRspackPluginOptions = {
test?: MinifyConditions;
exclude?: MinifyConditions;
include?: MinifyConditions;
};

export const SwcCssMinimizerRspackPlugin = create(
BuiltinPluginName.SwcCssMinimizerRspackPlugin,
(options?: any /* TODO: extend more options */) => undefined
(
options?: SwcCssMinimizerRspackPluginOptions
): RawSwcCssMinimizerRspackPluginOptions => {
return {
test: options?.test,
include: options?.include,
exclude: options?.exclude
};
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,22 @@ This plugin can be used to compress CSS assets. See [optimization.minimizer](/co
module.exports = {
// ...
optimization: {
minimizer: [new rspack.SwcCssMinimizerRspackPlugin()],
minimizer: [new rspack.SwcCssMinimizerRspackPlugin(options)],
},
};
```

- options

- **Type:**

```ts
type SwcCssMinimizerRspackPluginOptions = {
test?: MinifyConditions;
exclude?: MinifyConditions;
include?: MinifyConditions;
};

type MinifyCondition = string | RegExp;
type MinifyConditions = MinifyCondition | MinifyCondition[];
```
Loading