-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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(es/minifier): support reduce_escaped_newline
#10232
Conversation
🦋 Changeset detectedLatest commit: ea90d46 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
CodSpeed Performance ReportMerging #10232 will improve performances by 1.32%Comparing Summary
Benchmarks breakdown
|
I think we should not add a new option for this |
You mean enable the feature by default and cannot be turned off ? I have the same idea in fact. But considering the stability of the feature, I added that. |
If so, can we have an experimental config instead? Like |
Good idea.I'll try it later. |
I find that let unescape = match c {
'\\' => match iter.next() {
Some(c) => match c {
'n' => Some('\n'),
// ...
},
// ...
},
_ => Some(c),
};
match unescape {
Some('\n') => buf.push('\n'),
// ...
} It’s same as what I do inside It still makes sense to retain |
Maybe add an option to the codegen option? Lines 910 to 917 in b192dc8
|
OK. Maybe we should call it |
…ine` for minifier and `reduce_escaped_newline` for codegen
@@ -137,4 +137,29 @@ impl Optimizer<'_> { | |||
_ => {} | |||
} | |||
} | |||
|
|||
pub(super) fn reduce_escaped_newline_for_str_lit(&mut self, expr: &mut Expr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need this, even with the codegen config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used to transform string literal to template literal. Maybe should rename the method name, it's not clear enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document added.
quasis: vec![TplElement { | ||
span: s.span, | ||
cooked: Some(s.value.clone()), | ||
raw: s.value.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may cause an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function for Tpl#raw
=> Str#value
is at https://rustdoc.swc.rs/swc_core/ecma/utils/swc_ecma_ast/struct.Str.html#method.from_tpl_raw , but let me search for Str
=> Tpl
function...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should use functions at
swc/crates/swc_ecma_minifier/src/compress/pure/strings.rs
Lines 573 to 593 in f33b0bc
pub(super) fn convert_str_value_to_tpl_cooked(value: &Atom) -> Cow<str> { | |
value | |
.replace("\\\\", "\\") | |
.replace("\\`", "`") | |
.replace("\\$", "$") | |
.into() | |
} | |
pub(super) fn convert_str_value_to_tpl_raw(value: &Atom) -> Cow<str> { | |
value | |
.replace('\\', "\\\\") | |
.replace('`', "\\`") | |
.replace('$', "\\$") | |
.replace('\n', "\\n") | |
.replace('\r', "\\r") | |
.into() | |
} | |
pub(super) fn convert_str_raw_to_tpl_raw(value: &str) -> Atom { | |
value.replace('`', "\\`").replace('$', "\\$").into() | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function replace '\n'
to "\\n"
for Tpl#raw
, but I just want to preserve the '\n'
. It seems little bit redundant if replace "\\n"
back to '\n'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If so, can you add test cases for inputs that contain those strings, respectively?
One test per the search text in "", like one for "\$" in convert_str_value_to_tpl_cooked
(you need 3 test cases for the function) and "$" for convert_str_value_to_tpl_raw
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In pure/strings.rs
and pure/misc.rs
, it appears to be invoked with Str#value
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use a new fn to convert Str#value
to Tpl#raw
without replacing for \n
and test for some edge cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the original function need to be fixed in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s fine to skip for this PR unless there’s a test failure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any other suggestions for this review(or above)?
...ecma_minifier/tests/fixture/next/target-es2015/static/chunks/main-04b5934c26266542/output.js
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other things look good. Only one concern about consistency. Thanks!
#[non_exhaustive] | ||
pub struct TerserExperimentalOptions { | ||
#[serde(default = "true_by_default")] | ||
pub reduce_escaped_newline: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub reduce_escaped_newline: bool, | |
pub reduce_escaped_newline: Option<bool>, |
Sorry, I missed this one in the previous review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true_by_default
with bool
means
experimental: {}
=>true
, regardless ofdefaults
experimental: null
=> Usesdefaults
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think those two should behave identically because the user didn't specify the reduce_escaped_newline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's my oversight. Thanks to point out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Description: Add
compress.experimental.reduce_escaped_newline
option to convertStringLiteral
with escaped newline\n
toTemplateLiteral
with newline character(only forcompress.ecma
>= 2015).Default is
true
.BREAKING CHANGE: None.
Related issue (if exists): #10229