H5原生项目的压缩、混淆(html-minifier 、javascript-obfuscator)

为了防止项目被别人轻松抄袭,所以对代码的压缩、混淆还是很有必要的


一、常见插件介绍

  1. js压缩:terser、uglifyjs
  2. js混淆:javascript-obfuscator
  3. css压缩:postcss、clean-css
  4. html、css、js压缩:html-minifier

这里我们使用 html-minifier(压缩html、css)javascript-obfuscator(js混淆)

二、开始吧

  1. 运行环境:node(v14.17.6)
  2. 安装依赖:npm i html-minifier javascript-obfuscator
  3. 运行:
    1. 根据自己的项目修改根目录修改不进行处理的文件(夹)、修改原样输出的文件(如图片、字体文件、min文件)
    2. node main.js
  4. main.js 代码如下:
const fs = require('fs');
const path = require('path');
const minify = require('html-minifier').minify;
const JO = require("javascript-obfuscator");// 项目根目录
let sRootPath = 'ui'fnTravel(sRootPath, fnCompressHtmlCss)
console.log("文件处理结束")/*** 遍历文件* @params {*} dir 文件夹* @params {*} callback 回调函数*/
function fnTravel(dir, callback) {// 同步读取指定目录的内容let aFiles = fs.readdirSync(dir, 'utf8'), aFilterPath = ['.git', '.idea', 'html', 'README'];aFiles.forEach((file) => {// 获得完整路径let pathname = path.join(dir, file)// 判断是否处理let bIsHandle = aFilterPath.some(item => pathname.includes(item));if(!bIsHandle) {// 同步获取详细信息let stats = fs.statSync(pathname);if (stats.isDirectory()) {// 文件夹fnTravel(pathname, callback)} else {// 文件try {if (pathname.endsWith('js')) {// js 文件fnObfuscatorJs(pathname)} else {// 其他文件callback(pathname)}} catch (e) {console.error("压缩失败:" + pathname);console.error(e);}}}})
}/*** 压缩 html、css 文件方法* @params {*} path 文件路径*/
function fnCompressHtmlCss(path) {let sTargetPath = path.replace('ui', 'dist'),sCompressData = null, data = null;if (!path.includes('img') && !path.includes('fonts')) {// 获取文件内容data = fs.readFileSync(path, 'utf8')if(!path.endsWith('.min.css')) {// 压缩后的文件内容sCompressData = minify(data, {collapseWhitespace: true, // 删除html里的空格 达到html的压缩removeAttributeQuotes: true, // 尽可能删除html标签里的双引号 达到html的压缩removeComments: true, //删除html中的注释removeCommentsFromCDATA: true, //从脚本和样式删除的注释minifyCSS: true, // 压缩css})}}let result = sCompressData ? sCompressData : data;// 将数据同步写入文件fnWriteFileRecursive(path, sTargetPath, result, (err) => {if (err) console.error(err);console.log('compress--[' + path + ']--success');})
}/*** 压缩、混淆js方法* @params {*} path 文件路径*/
function fnObfuscatorJs(path) {let sTargetPath = path.replace('ui', 'dist'),sObfuscateCode = null;// 获取文件内容let data = fs.readFileSync(path, 'utf8')if (!sTargetPath.endsWith('.min.js')) {// 进行混淆sObfuscateCode = JO.obfuscate(data, {compact: true, // 压缩controlFlowFlattening: true,controlFlowFlatteningThreshold: 1,numbersToExpressions: true,simplify: true,shuffleStringArray: true,splitStrings: true,stringArrayThreshold: 1,});}// getObfuscatedCode() 返回混淆后的代码字符串,调用 toString 方法也会返回混淆代码let sResultCode = sObfuscateCode ? sObfuscateCode.getObfuscatedCode() : data;fnWriteFileRecursive(path, sTargetPath, sResultCode, (err) => {if (err) console.error(err);console.log('compress--[' + path + ']--success');})
}/*** 创建目录并写入文件* @params {*} sFromPath 来源路径* @params {*} sTargetPath 目标路径* @params {*} buffer 文件内容* @params {*} callback 回调函数* */
function fnWriteFileRecursive(sFromPath, sTargetPath, buffer, callback) {let lastPath = sTargetPath.substring(0, sTargetPath.lastIndexOf("\\"));// 创建目录fs.mkdir(lastPath, {recursive: true}, (err) => {if (err) return callback(err);if (sTargetPath.includes('img') || sTargetPath.includes('fonts')) {// 处理图片、字体文件let readStream = fs.createReadStream(sFromPath); // 逐块读取文件let writeStream = fs.createWriteStream(sTargetPath); // 对指定文件创建一个“可写数据流”readStream.pipe(writeStream); // 将文件数据流导向 writeStream 对象} else {// 处理html、css、js文件fs.writeFileSync(sTargetPath, buffer, function (err) {if (err) return callback(err);});}});
}

知识点扩展

  1. 在写入文件之前,首先使用 mkdir(第一个参数是目录路径,第二个是权限,第三个是回调函数)方法新建目录,防止因为路径不存在而报错
  2. node.js 内置的 fs模块是文件系统模块,负责读写文件,fs模块还提供了异步和同步的方法
    1. 使用异步方法执行IO(输入/输出)操作时,JS代码不需要等待,在传入回调函数后,会继续执行后续代码
    2. 使用同步方法执行IO时,则需要等待函数返回
  3. node.js 中readFile和createReadStream函数的区别:
    1. readFile函数异步读取文件内容,并存储在内存中,然后才能使用;优点是符合直觉,流程自然。缺点是如果遇到大文件,要花费很长时间,才能进入数据处理的步骤
    2. createReadStream使用一个可读的流,逐块读取文件,而不是全部存储在内存中,同时每当系统读入一小块数据时,就会触发一个事件,只要监听这个事件(data)就能掌握执行进度,做出相应的数据处理,这样一来 createReadStream 使用更少的内存和更快的速度来优化文件的读取操作。

参考文章

https://segmentfault.com/a/1190000040502426
https://blog.csdn.net/qq_37667074/article/details/108356269
https://blog.csdn.net/foupwang/article/details/103306332
https://blog.csdn.net/Liheishuai/article/details/124625069


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部