Bump minify-js

This commit is contained in:
Wilson Lin 2022-09-28 12:51:44 +10:00
parent b9dcd6e807
commit 1aea5d1be8
11 changed files with 42 additions and 21 deletions

View File

@ -1,5 +1,10 @@
# minify-html changelog # minify-html changelog
## 0.10.1
- Bump [minify-js](https://github.com/wilsonzlin/minify-js) to 0.2.
- Minify JS as module instead of global script if `type` is `module`.
## 0.10.0 ## 0.10.0
- Drop unmatched closing tags instead of reinterpreting them as opening tags. This avoids the possibility of unintentionally creating a large deep tree due to malformed inputs where there are repeated unmatched closing tags (e.g. broken HTML template). - Drop unmatched closing tags instead of reinterpreting them as opening tags. This avoids the possibility of unintentionally creating a large deep tree due to malformed inputs where there are repeated unmatched closing tags (e.g. broken HTML template).

View File

@ -8,7 +8,6 @@ lazy_static! {
s.insert(b"application/javascript"); s.insert(b"application/javascript");
s.insert(b"application/x-ecmascript"); s.insert(b"application/x-ecmascript");
s.insert(b"application/x-javascript"); s.insert(b"application/x-javascript");
s.insert(b"module");
s.insert(b"text/ecmascript"); s.insert(b"text/ecmascript");
s.insert(b"text/javascript"); s.insert(b"text/javascript");
s.insert(b"text/javascript1.0"); s.insert(b"text/javascript1.0");

View File

@ -18,6 +18,6 @@ maintenance = { status = "actively-developed" }
[dependencies] [dependencies]
aho-corasick = "0.7" aho-corasick = "0.7"
css-minify = "0.2.2" css-minify = "0.2.2"
minify-js = "0.1.1" minify-js = "0.2"
lazy_static = "1.4" lazy_static = "1.4"
memchr = "2" memchr = "2"

View File

@ -19,6 +19,7 @@ pub enum ScriptOrStyleLang {
CSS, CSS,
Data, Data,
JS, JS,
JSModule,
} }
pub struct AttrVal { pub struct AttrVal {

View File

@ -340,8 +340,7 @@ pub fn minify_attr(
|| default_value.filter(|dv| dv == &value_raw).is_some() || default_value.filter(|dv| dv == &value_raw).is_some()
|| (tag == b"script" || (tag == b"script"
&& name == b"type" && name == b"type"
&& JAVASCRIPT_MIME_TYPES.contains(value_raw.as_slice()) && JAVASCRIPT_MIME_TYPES.contains(value_raw.as_slice()))
&& value_raw.as_slice() != b"module")
{ {
return AttrMinified::Redundant; return AttrMinified::Redundant;
}; };

View File

@ -145,7 +145,12 @@ pub fn minify_content(
NodeData::ScriptOrStyleContent { code, lang } => match lang { NodeData::ScriptOrStyleContent { code, lang } => match lang {
ScriptOrStyleLang::CSS => minify_css(cfg, out, &code), ScriptOrStyleLang::CSS => minify_css(cfg, out, &code),
ScriptOrStyleLang::Data => out.extend_from_slice(&code), ScriptOrStyleLang::Data => out.extend_from_slice(&code),
ScriptOrStyleLang::JS => minify_js(cfg, out, &code), ScriptOrStyleLang::JS => {
minify_js(cfg, minify_js::TopLevelMode::Global, out, &code)
}
ScriptOrStyleLang::JSModule => {
minify_js(cfg, minify_js::TopLevelMode::Module, out, &code)
}
}, },
NodeData::Text { value } => out NodeData::Text { value } => out
.extend_from_slice(&CHEVRON_REPLACER.replace_all(&encode_entities(&value, false))), .extend_from_slice(&CHEVRON_REPLACER.replace_all(&encode_entities(&value, false))),

View File

@ -1,13 +1,13 @@
use crate::cfg::Cfg; use crate::cfg::Cfg;
use crate::common::whitespace::trimmed; use crate::common::whitespace::trimmed;
use minify_js::minify as minifier; use minify_js::{minify as minifier, TopLevelMode};
pub fn minify_js(cfg: &Cfg, out: &mut Vec<u8>, code: &[u8]) { pub fn minify_js(cfg: &Cfg, mode: TopLevelMode, out: &mut Vec<u8>, code: &[u8]) {
if cfg.minify_js { if cfg.minify_js {
let source = code.to_vec(); let source = code.to_vec();
// TODO Write to `out` directly, but only if we can guarantee that the length will never exceed the input. // TODO Write to `out` directly, but only if we can guarantee that the length will never exceed the input.
let mut output = Vec::new(); let mut output = Vec::new();
let result = minifier(source, &mut output); let result = minifier(mode, source, &mut output);
// TODO Collect error as warning. // TODO Collect error as warning.
if !result.is_err() && output.len() < code.len() { if !result.is_err() && output.len() < code.len() {
out.extend_from_slice(output.as_slice()); out.extend_from_slice(output.as_slice());

View File

@ -169,6 +169,9 @@ pub fn parse_element(code: &mut Code, ns: Namespace, parent: &[u8]) -> NodeData
Some(mime) if !JAVASCRIPT_MIME_TYPES.contains(mime.as_slice()) => { Some(mime) if !JAVASCRIPT_MIME_TYPES.contains(mime.as_slice()) => {
parse_script_content(code, ScriptOrStyleLang::Data) parse_script_content(code, ScriptOrStyleLang::Data)
} }
Some(typ) if typ.as_slice() == b"module" => {
parse_script_content(code, ScriptOrStyleLang::JSModule)
}
_ => parse_script_content(code, ScriptOrStyleLang::JS), _ => parse_script_content(code, ScriptOrStyleLang::JS),
}, },
b"style" => parse_style_content(code), b"style" => parse_style_content(code),

View File

@ -20,4 +20,4 @@ aho-corasick = "0.7"
css-minify = "0.2.2" css-minify = "0.2.2"
lazy_static = "1.4" lazy_static = "1.4"
memchr = "2" memchr = "2"
minify-js = "0.1.1" minify-js = "0.2"

View File

@ -14,17 +14,22 @@ lazy_static! {
.build(&["</script"]); .build(&["</script"]);
} }
// Provide `None` to `mode` if not JS.
#[inline(always)] #[inline(always)]
pub fn process_script(proc: &mut Processor, cfg: &Cfg, js: bool) -> ProcessingResult<()> { pub fn process_script(
proc: &mut Processor,
cfg: &Cfg,
mode: Option<minify_js::TopLevelMode>,
) -> ProcessingResult<()> {
let start = WriteCheckpoint::new(proc); let start = WriteCheckpoint::new(proc);
proc.require_not_at_end()?; proc.require_not_at_end()?;
let src = proc.m(WhileNotSeq(&SCRIPT_END), Discard); let src = proc.m(WhileNotSeq(&SCRIPT_END), Discard);
// `process_tag` will require closing tag. // `process_tag` will require closing tag.
if js && cfg.minify_js { if cfg.minify_js && mode.is_some() {
// TODO Write to `out` directly, but only if we can guarantee that the length will never exceed the input. // TODO Write to `out` directly, but only if we can guarantee that the length will never exceed the input.
let mut output = Vec::new(); let mut output = Vec::new();
let result = minify_js::minify(proc[src].to_vec(), &mut output); let result = minify_js::minify(mode.unwrap(), proc[src].to_vec(), &mut output);
// TODO Collect error as warning. // TODO Collect error as warning.
if !result.is_err() && output.len() < src.len() { if !result.is_err() && output.len() < src.len() {
proc.write_slice(output.as_slice()); proc.write_slice(output.as_slice());

View File

@ -19,6 +19,7 @@ use crate::unit::style::process_style;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
enum TagType { enum TagType {
ScriptJs, ScriptJs,
ScriptJsModule,
ScriptData, ScriptData,
Style, Style,
Other, Other,
@ -138,14 +139,14 @@ pub fn process_tag(
match (tag_type, &proc[name]) { match (tag_type, &proc[name]) {
// NOTE: We don't support multiple `type` attributes, so can't go from ScriptData => ScriptJs. // NOTE: We don't support multiple `type` attributes, so can't go from ScriptData => ScriptJs.
(TagType::ScriptJs, b"type") => { (TagType::ScriptJs, b"type") => {
// It's JS if the value is empty or one of `JAVASCRIPT_MIME_TYPES`. if value.filter(|v| &proc[*v] == b"module").is_some() {
let script_tag_type_is_js = value tag_type = TagType::ScriptJsModule;
} else if value
.filter(|v| !JAVASCRIPT_MIME_TYPES.contains(&proc[*v])) .filter(|v| !JAVASCRIPT_MIME_TYPES.contains(&proc[*v]))
.is_none(); .is_none()
if script_tag_type_is_js { {
if &proc[value.unwrap()] != b"module" { // The value is empty or one of `JAVASCRIPT_MIME_TYPES`.
erase_attr = true; erase_attr = true;
};
} else { } else {
// Tag does not contain JS, don't minify JS. // Tag does not contain JS, don't minify JS.
tag_type = TagType::ScriptData; tag_type = TagType::ScriptData;
@ -205,8 +206,11 @@ pub fn process_tag(
let mut closing_tag_omitted = false; let mut closing_tag_omitted = false;
match tag_type { match tag_type {
TagType::ScriptData => process_script(proc, cfg, false)?, TagType::ScriptData => process_script(proc, cfg, None)?,
TagType::ScriptJs => process_script(proc, cfg, true)?, TagType::ScriptJs => process_script(proc, cfg, Some(minify_js::TopLevelMode::Global))?,
TagType::ScriptJsModule => {
process_script(proc, cfg, Some(minify_js::TopLevelMode::Module))?
}
TagType::Style => process_style(proc, cfg)?, TagType::Style => process_style(proc, cfg)?,
_ => { _ => {
closing_tag_omitted = closing_tag_omitted =