在nodejs应用程序中缩小/丑化带有嵌入脚本标签的html页面

问题描述 投票:0回答:1

我有一个 Express 应用程序,除其他外,它还提供一些基于单个车把模板的 html 代码。 对于用例来说,以短延迟交付它会很棒。因此,我在应用程序启动时读取并编译模板,现在我只需调用

res.send(
    compiledTemplateIframeContent({ data: iframeData })
)

所有这些都完美无缺。

问题

现在我想缩小 html 并丑化 js 代码。我尝试使用 html-minifier 但嵌入的 javascript 没有丑化(重命名变量),甚至没有缩小(例如删除空格)。 我猜 uglify-js 没有在后台调用,因为一些配置错误。通过阅读文档我找不到我的错误。

我编写了一些测试 html 代码并在这个在线工具中进行了尝试。它只是 html-minifier 前面的一个简单的 gui,因此可能是测试我的问题的好方法。 在在线版本中,当我将

type="text/javascript"
添加到标签并将
text/javascript
添加到
Process scripts
选项时,我至少可以使其压缩 javascript 代码(即使这在我的 Express 应用程序中不起作用)。

但在在线工具中,

Minify JavaScript
复选框也不会改变任何内容。

我还不知道 uglifyjs 的可能性(html-minifier 的依赖项),但有了这个名字,我会认为它不仅应该压缩,还应该丑化 js 代码。

编辑/更新

我做了更多研究。我通过正则表达式匹配提取了js代码,然后直接用代码调用了uglify-js。车把碎片 {{ }} 存在一些问题。删除它们后,uglif-js 可以在模板的嵌入式 js 部分上工作。

当我为 html-minifier 设置选项

ignoreCustomFragments: [/{{.*}}/g]
时,我想这应该不是问题?!

这里是直接使用uglify-js的部分

function minifyWithUglifyJs(orig: string): string {
    
    const re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
    const match = re.exec(orig);
    if(match == null) {
        throw new Error(`Can't minify js in iframe template as found no match for js script!`);
    }

    const origJs = match[1] as string;
    console.log(origJs);
    const minifyResult = uglifyjs.minify(origJs);

    if(minifyResult.warnings != null) {
        minifyResult.warnings.forEach(logger.warn);
    }
    if(minifyResult.error) {
        throw new Error(`Can't minify the iframe template!`, {cause:minifyResult.error});
    } else {
        // replace orig js with minified js in code
        return orig.replace(origJs, minifyResult.code);
    }

}

总结一下:

  • 有人知道我的 http-minifier 做错了什么吗?

这是我在节点应用程序中缩小的尝试(使用 [email protected]

import htmlMinifier from 'html-minifier';

function minifyWithHtmlMinifier(orig: string):string {
    return htmlMinifier.minify(orig, {
        minifyJS: true,
        processScripts: ["text/javascript"],
        ignoreCustomFragments: [/{{.*}}/g]
    });
}

这是一些可以在在线工具中使用的测试代码

<!DOCTYPE html> <html lang="en"> <head> <title>Test ad</title> </head> <body onload="onLoad()"> <div id="img-container" style="width:100%;height:100%">test text in page</div> <script type="text/javascript"> const longNameThatShouldBeUglified= 12; console.log("test"); //{{another test}} function onLoad() { console.log("longNameThatShouldBeUglified (Not this time as it's a string) "+longNameThatShouldBeUglified); } </script> </body> </html>

    
javascript node.js minify uglifyjs html-minifier
1个回答
1
投票
问题是,当 uglify-js 抛出任何错误时,

html-minifier 不会给你任何警告。我以为我错误配置了 html-minifier,因为它没有缩小。

在分割我的代码以仅获取标签之间的内容并直接使用 uglify-js 后,我看到了问题并可以修复待缩小的代码。一旦它起作用,我就切换回使用 html-minifier 并且它起作用了。

我现在使用以下代码,

告诉 html-minifier 使用包含在某些代码中的 uglify-js 来识别任何问题

function minifyWithHtmlMinifier(orig: string):string { return htmlMinifier.minify(orig, { // I have replaced the default minifyJS usage of the html-minifier // as this silently ignores any uglifyjs errors and just displays // the non-minified code. Has cost me half a day to figure out // that it was not a configuration problem but problem with the // to-be-minified-code. // By setting the call to uglifyjs myself I can catch the errors and // rethrow them, failing fast, as this is much better than recognizing // a not-minified code much later when I don't remember what I changed minifyJS: (text, _inline) => { const minifyResult = uglifyjs.minify(text, { compress: { drop_console: true // remove all console log entries } }); if(minifyResult.warnings != null) { minifyResult.warnings.forEach(logger.warn); } if(minifyResult.error) { // TODO maybe use terser. I think it supports // newer ES versions than uglifyjs throw new Error(`Can't minify the iframe template!`, {cause:minifyResult.error}); } return minifyResult.code; }, minifyCSS: true, ignoreCustomFragments: [/{{.*}}/g], // handlebars fragments collapseBooleanAttributes: true, collapseInlineTagWhitespace: true, collapseWhitespace: true }); }
重要注意事项:
还有 

html-minifier-terser 在我前期研究 Nodejs 中使用什么 Minifier 时并没有出现。也许它可以做更好的报告。

© www.soinside.com 2019 - 2024. All rights reserved.