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 __webpack_get_script_filename__ #7203

Merged
merged 1 commit into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 13 additions & 0 deletions crates/rspack_plugin_javascript/src/parser_plugin/api_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const WEBPACK_NONCE: &str = "__webpack_nonce__";
const WEBPACK_CHUNK_NAME: &str = "__webpack_chunkname__";
const WEBPACK_RUNTIME_ID: &str = "__webpack_runtime_id__";
const WEBPACK_REQUIRE: &str = RuntimeGlobals::REQUIRE.name();
const WEBPACK_GET_SCRIPT_FILENAME: &str = "__webpack_get_script_filename__";
const RSPACK_VERSION: &str = "__rspack_version__";
const RSPACK_UNIQUE_ID: &str = "__rspack_unique_id__";

Expand Down Expand Up @@ -56,6 +57,7 @@ fn get_typeof_evaluate_of_api(sym: &str) -> Option<&str> {
WEBPACK_NONCE => Some("string"),
WEBPACK_CHUNK_NAME => Some("string"),
WEBPACK_RUNTIME_ID => None,
WEBPACK_GET_SCRIPT_FILENAME => Some("function"),
RSPACK_VERSION => Some("string"),
RSPACK_UNIQUE_ID => Some("string"),
_ => None,
Expand Down Expand Up @@ -239,6 +241,17 @@ impl JavascriptParserPlugin for APIPlugin {
)));
Some(true)
}
WEBPACK_GET_SCRIPT_FILENAME => {
parser
.presentational_dependencies
.push(Box::new(ConstDependency::new(
ident.span.real_lo(),
ident.span.real_hi(),
RuntimeGlobals::GET_CHUNK_SCRIPT_FILENAME.name().into(),
Some(RuntimeGlobals::GET_CHUNK_SCRIPT_FILENAME),
)));
Some(true)
}
// rspack specific
RSPACK_VERSION => {
parser
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,16 @@ impl JavascriptParserPlugin for ImportMetaPlugin {

fn evaluate_identifier(
&self,
_parser: &mut JavascriptParser,
parser: &mut JavascriptParser,
ident: &str,
start: u32,
end: u32,
) -> Option<eval::BasicEvaluatedExpression> {
if ident == expr_name::IMPORT_META_WEBPACK {
Some(eval::evaluate_to_number(5_f64, start, end))
} else if ident == expr_name::IMPORT_META_URL {
let url = Url::from_file_path(&parser.resource_data.resource).expect("should be a path");
Some(eval::evaluate_to_string(url.to_string(), start, end))
} else {
None
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::utils::eval::BasicEvaluatedExpression;
const SLICE_METHOD_NAME: &str = "slice";
const REPLACE_METHOD_NAME: &str = "replace";
const CONCAT_METHOD_NAME: &str = "concat";
const INDEXOF_METHOD_NAME: &str = "indexOf";
// TODO: substr, substring

pub struct InitializeEvaluating;

Expand All @@ -17,7 +19,36 @@ impl JavascriptParserPlugin for InitializeEvaluating {
expr: &swc_core::ecma::ast::CallExpr,
param: &BasicEvaluatedExpression,
) -> Option<BasicEvaluatedExpression> {
if property == SLICE_METHOD_NAME
if property == INDEXOF_METHOD_NAME && param.is_string() {
let arg1 = (!expr.args.is_empty()).then_some(true).and_then(|_| {
if expr.args[0].spread.is_some() {
return None;
}
let arg = parser.evaluate_expression(&expr.args[0].expr);
arg.is_string().then_some(arg)
});

let arg2 = (expr.args.len() >= 2).then_some(true).and_then(|_| {
if expr.args[1].spread.is_some() {
return None;
}
let arg = parser.evaluate_expression(&expr.args[1].expr);
arg.is_number().then_some(arg)
});

if let Some(result) = arg1.map(|arg1| {
mock_javascript_indexof(
param.string().as_str(),
arg1.string().as_str(),
arg2.map(|a| a.number()),
)
}) {
let mut res = BasicEvaluatedExpression::with_range(expr.span.real_lo(), expr.span.hi().0);
res.set_number(result as f64);
res.set_side_effects(param.could_have_side_effects());
return Some(res);
}
} else if property == SLICE_METHOD_NAME
&& param.is_string()
&& expr.args.len() == 1
&& expr.args[0].spread.is_none()
Expand Down Expand Up @@ -213,3 +244,57 @@ fn test_mock_javascript_slice() {
assert_eq!(mock_javascript_slice("123", -2.2), "23".to_string());
assert_eq!(mock_javascript_slice("123", -3.), "123".to_string());
}

fn mock_javascript_indexof(str: &str, sub: &str, start: Option<f64>) -> i32 {
let mut start_pos = start.unwrap_or_default().trunc() as i32;
if start_pos < 0 {
start_pos = 0_i32;
}
if start_pos >= str.len() as i32 {
return -1_i32;
}

if let Some(pos) = str[(start_pos as usize)..].find(sub) {
(pos as i32) + start_pos
} else {
-1_i32
}
}

#[test]
fn test_mock_javascript_indexof() {
assert_eq!(mock_javascript_indexof("abcdefg", "cde", None), 2_i32);
assert_eq!(mock_javascript_indexof("abcdefg", "ccc", None), -1_i32);
assert_eq!(mock_javascript_indexof("abcdefg", "abcdefg", None), 0_i32);

assert_eq!(
mock_javascript_indexof("abcdefg", "cde", Some(1_f64)),
2_i32
);
assert_eq!(
mock_javascript_indexof("abcdefg", "cde", Some(1.1_f64)),
2_i32
);
assert_eq!(
mock_javascript_indexof("abcdefg", "cde", Some(3_f64)),
-1_i32
);
assert_eq!(
mock_javascript_indexof("abcdefg", "cde", Some(3.3_f64)),
-1_i32
);
assert_eq!(
mock_javascript_indexof("abcdefg", "cde", Some(2.9_f64)),
2_i32
);

assert_eq!(
mock_javascript_indexof("abcdefg", "cde", Some(7_f64)),
-1_i32
);

assert_eq!(
mock_javascript_indexof("abcdefg", "cde", Some(-1_f64)),
2_i32
);
}
25 changes: 25 additions & 0 deletions crates/rspack_plugin_javascript/src/utils/eval/eval_unary_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,31 @@ pub fn eval_unary_expression(
eval.set_side_effects(arg.could_have_side_effects());
Some(eval)
}
UnaryOp::Tilde => {
let arg = scanner.evaluate_expression(&expr.arg);
let Some(number) = arg.as_int() else {
return None;
};
let mut eval = BasicEvaluatedExpression::with_range(expr.span().real_lo(), expr.span_hi().0);
eval.set_number(!number as f64);
eval.set_side_effects(arg.could_have_side_effects());
Some(eval)
}
UnaryOp::Minus | UnaryOp::Plus => {
let arg = scanner.evaluate_expression(&expr.arg);
let Some(number) = arg.as_number() else {
return None;
};
let res = match &expr.op {
UnaryOp::Minus => -number,
UnaryOp::Plus => number,
_ => unreachable!(),
};
let mut eval = BasicEvaluatedExpression::with_range(expr.span().real_lo(), expr.span_hi().0);
eval.set_number(res);
eval.set_side_effects(arg.could_have_side_effects());
Some(eval)
}
_ => None,
}
}
2 changes: 1 addition & 1 deletion tests/webpack-test/cases/esm/import-meta/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ it("should return correct import.meta.url", () => {
expect(import.meta.url).toBe(url);
expect(import.meta["url"]).toBe(url);
expect("my" + import.meta.url).toBe("my" + url);
// if (import.meta.url.indexOf("index.js") === -1) require("fail");
if (import.meta.url.indexOf("index.js") === -1) require("fail");
});

it("should return correct import.meta.webpack", () => {
Expand Down

This file was deleted.

Loading