Skip to content

Commit

Permalink
feat(copyRspackPlugin): support transform configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
9aoy committed Apr 26, 2024
1 parent d968a3b commit cd39f50
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 19 deletions.
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.

1 change: 1 addition & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@ export interface RawCopyPattern {
priority: number
globOptions: RawCopyGlobOptions
info?: RawInfo
transform?: (input: string, absoluteFilename: string) => string | Buffer
}

export interface RawCopyRspackPluginOptions {
Expand Down
37 changes: 33 additions & 4 deletions crates/rspack_binding_options/src/options/raw_builtins/raw_copy.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
use std::path::PathBuf;

use derivative::Derivative;
use napi::{bindgen_prelude::Buffer, Either};
use napi_derive::napi;
use rspack_core::rspack_sources::RawSource;
use rspack_napi::threadsafe_function::ThreadsafeFunction;
use rspack_plugin_copy::{
CopyGlobOptions, CopyPattern, CopyRspackPluginOptions, Info, Related, ToType,
CopyGlobOptions, CopyPattern, CopyRspackPluginOptions, Info, Related, ToType, Transformer,
};

#[derive(Debug, Clone)]
#[napi(object)]
type RawTransformer = ThreadsafeFunction<(String, String), Either<String, Buffer>>;

#[derive(Derivative)]
#[derivative(Debug, Clone)]
#[napi(object, object_to_js = false)]
pub struct RawCopyPattern {
pub from: String,
pub to: Option<String>,
Expand All @@ -17,6 +24,9 @@ pub struct RawCopyPattern {
pub priority: i32,
pub glob_options: RawCopyGlobOptions,
pub info: Option<RawInfo>,
#[derivative(Debug = "ignore")]
#[napi(ts_type = "(input: string, absoluteFilename: string) => string | Buffer")]
pub transform: Option<RawTransformer>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -47,7 +57,7 @@ pub struct RawCopyGlobOptions {
}

#[derive(Debug)]
#[napi(object)]
#[napi(object, object_to_js = false)]
pub struct RawCopyRspackPluginOptions {
pub patterns: Vec<RawCopyPattern>,
}
Expand All @@ -64,6 +74,7 @@ impl From<RawCopyPattern> for CopyPattern {
priority,
glob_options,
info,
transform,
} = value;

Self {
Expand Down Expand Up @@ -97,6 +108,24 @@ impl From<RawCopyPattern> for CopyPattern {
.collect()
}),
},
transform: transform.map(|transformer| {
Transformer::Fn(Box::new(move |input, absolute_filename| {
let f = transformer.clone();

fn convert_to_enum(input: Either<String, Buffer>) -> RawSource {
match input {
Either::A(s) => RawSource::Source(s),
Either::B(b) => RawSource::Buffer(b.to_vec()),
}
}

Box::pin(async move {
f.call((input.to_owned(), absolute_filename.to_owned()))
.await
.map(|i| convert_to_enum(i))
})
}))
}),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/rspack_plugin_copy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ version = "0.1.0"

[dependencies]
dashmap = { workspace = true }
derivative = { workspace = true }
futures = { workspace = true }
glob = { workspace = true }
lazy_static = "1.4.0"
pathdiff = { workspace = true }
Expand Down
60 changes: 45 additions & 15 deletions crates/rspack_plugin_copy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use std::{
};

use dashmap::DashSet;
use derivative::Derivative;
use futures::future::BoxFuture;
use glob::{MatchOptions, Pattern as GlobPattern};
use regex::Regex;
use rspack_core::{
Expand All @@ -20,7 +22,7 @@ use rspack_hook::{plugin, plugin_hook};
use rspack_util::infallible::ResultInfallibleExt as _;
use sugar_path::SugarPath;

#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct CopyRspackPluginOptions {
pub patterns: Vec<CopyPattern>,
}
Expand Down Expand Up @@ -66,7 +68,15 @@ impl Display for ToType {
}
}

#[derive(Debug, Clone)]
pub type TransformerFn =
Box<dyn for<'a> Fn(String, &'a str) -> BoxFuture<'a, Result<RawSource>> + Sync + Send>;

pub enum Transformer {
Fn(TransformerFn),
}

#[derive(Derivative)]
#[derivative(Debug)]
pub struct CopyPattern {
pub from: String,
pub to: Option<String>,
Expand All @@ -77,6 +87,8 @@ pub struct CopyPattern {
pub force: bool,
pub priority: i32,
pub glob_options: CopyGlobOptions,
#[derivative(Debug = "ignore")]
pub transform: Option<Transformer>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -227,7 +239,7 @@ impl CopyRspackPlugin {
logger.debug(format!("reading '{}'...", absolute_filename.display()));
// TODO inputFileSystem

let source = match tokio::fs::read(absolute_filename.clone()).await {
let mut source = match tokio::fs::read(absolute_filename.clone()).await {
Ok(data) => {
logger.debug(format!("read '{}'...", absolute_filename.display()));

Expand All @@ -244,6 +256,23 @@ impl CopyRspackPlugin {
}
};

if let Some(transform) = &pattern.transform {
if let Some(absolute_filename) = absolute_filename.to_str() {
let content = match source {
RawSource::Source(code) => code,
RawSource::Buffer(buffer) => String::from_utf8(buffer).unwrap(),

Check failure on line 263 in crates/rspack_plugin_copy/src/lib.rs

View workflow job for this annotation

GitHub Actions / Rust check

used `unwrap()` on a `Result` value
};

match transform {
Transformer::Fn(transformer) => {
source = transformer(content, absolute_filename)
.await
.expect("run copy transformer error");
}
}
}
}

let filename = if matches!(&to_type, ToType::Template) {
logger.log(format!(
"interpolating template '{}' for '${}'...`",
Expand Down Expand Up @@ -300,15 +329,25 @@ impl CopyRspackPlugin {
) -> Option<Vec<Option<RunPatternResult>>> {
let orig_from = &pattern.from;
let normalized_orig_from = PathBuf::from(orig_from);
let mut context = pattern
.context

let pattern_context = if pattern.context.is_none() {
Some(compilation.options.context.as_path().into())
} else if let Some(ctx) = pattern.context.clone()
&& !ctx.is_absolute()
{
Some(compilation.options.context.as_path().join(ctx))
} else {
pattern.context.clone()
};

let mut context = pattern_context
.clone()
.unwrap_or(compilation.options.context.as_path().to_path_buf());

logger.log(format!(
"starting to process a pattern from '{}' using '{:?}' context",
normalized_orig_from.display(),
pattern.context.as_ref().map(|p| p.display())
pattern_context.as_ref().map(|p| p.display())
));

let abs_from = if normalized_orig_from.is_absolute() {
Expand Down Expand Up @@ -520,15 +559,6 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> {
.iter()
.enumerate()
.map(|(index, pattern)| {
let mut pattern = pattern.clone();
if pattern.context.is_none() {
pattern.context = Some(compilation.options.context.as_path().into());
} else if let Some(ctx) = pattern.context.clone()
&& !ctx.is_absolute()
{
pattern.context = Some(compilation.options.context.as_path().join(ctx))
};

CopyRspackPlugin::run_patter(
compilation,
&pattern,

Check failure on line 564 in crates/rspack_plugin_copy/src/lib.rs

View workflow job for this annotation

GitHub Actions / Rust check

this expression creates a reference which is immediately dereferenced by the compiler
Expand Down
33 changes: 33 additions & 0 deletions plugin-test/copy-plugin/CopyPlugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,39 @@ describe("CopyPlugin", () => {
);
});
});

it("should work with transform fn", async () => {
const compiler = rspack([
{
mode: "development",
context: path.resolve(__dirname, "./fixtures"),
plugins: [
new rspack.CopyRspackPlugin({
patterns: [
{
from: path.resolve(__dirname, "./fixtures/directory"),
transform: source => {
return source + "transform aaaa";
}
}
]
})
],
entry: path.resolve(__dirname, "./helpers/enter.js"),
output: {
path: path.resolve(__dirname, "./outputs/dist/b")
}
}
]);

const { stats } = await compile(compiler);

stats.stats.forEach((item, index) => {
expect(readAssets(compiler.compilers[index], item)).toMatchSnapshot(
"assets"
);
});
});
});

describe("watch mode", () => {
Expand Down
10 changes: 10 additions & 0 deletions plugin-test/copy-plugin/__snapshots__/CopyPlugin.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ exports[`CopyPlugin basic should work with multi compiler mode: warnings 1`] = `

exports[`CopyPlugin basic should work with multi compiler mode: warnings 2`] = `Array []`;

exports[`CopyPlugin basic should work with transform fn: assets 1`] = `
Object {
".dottedfile": "dottedfile contents
transform aaaa",
"directoryfile.txt": "newtransform aaaa",
"nested/deep-nested/deepnested.txt": "transform aaaa",
"nested/nestedfile.txt": "transform aaaa",
}
`;

exports[`CopyPlugin stats should minify: assets 1`] = `
Object {
"asset-modules/deepnested.txt": "",
Expand Down
10 changes: 10 additions & 0 deletions website/docs/en/plugins/rspack/copy-rspack-plugin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ new rspack.CopyRspackPlugin(options);
dot?: boolean; // Default to true
ignore?: string[]; // ignore specific path
};
transform?: (
input: string,
absoluteFilename: string,
) => string | Buffer;
}
)[];
};
Expand Down Expand Up @@ -116,6 +120,12 @@ new rspack.CopyRspackPlugin(options);
description:
'The configuration for glob queries: `caseSensitiveMatch` determines whether the matching is case sensitive, and `dot` determines whether files starting with . are matched. `ignore` is an array of strings in glob format that can be used to ignore specific paths.',
},
{
name: '`transform`',
type: '`function`',
default: 'undefined',
description: 'Allows to modify the file contents.',
},
]}
/>

Expand Down
10 changes: 10 additions & 0 deletions website/docs/zh/plugins/rspack/copy-rspack-plugin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ new rspack.CopyRspackPlugin(options);
dot?: boolean; // 默认 true
ignore?: string[]; // 忽略特定路径
};
transform?: (
input: string,
absoluteFilename: string,
) => string | Buffer;
}
)[];
};
Expand Down Expand Up @@ -115,6 +119,12 @@ new rspack.CopyRspackPlugin(options);
description:
'glob 查询选项,`caseSensitiveMatch` 决定是否大小写敏感,`dot` 决定是否匹配以 `.` 开头的文件,`ignore` 是 glob 形式的字符串数组,可以使用该配置忽略部分特定路径。',
},
{
name: '`transform`',
type: '`function`',
default: 'undefined',
description: '允许修改文件内容。',
},
]}
/>

Expand Down

0 comments on commit cd39f50

Please sign in to comment.