node 脚本压缩html, js, css

244 阅读1分钟

使用html-minifier , clean-css , terser node包压缩前端文本文件

脱离传统webpack打包形式, 直接压缩文本

compress.js 文件代码如下:

const fs = require("fs-extra");
// const { exec } = require('child_process');

const htmlMinify = require("html-minifier").minify;
const CleanCSS = require("clean-css");
const terser = require("terser");
const path = require("path");

// 压缩 HTML 文件
function compressHTML(inputFile, outputFile) {
  const html = fs.readFileSync(inputFile, "utf8");
  const options = {
    collapseWhitespace: true,
    removeComments: true,
    minifyCSS: true,
    minifyJS: true,
  };
  const compressedHTML = htmlMinify(html, options);
  fs.outputFileSync(outputFile, compressedHTML); //fs.wirteFile不行, 路径必须存在
  console.log(`HTML 压缩完成![${outputFile}]`);
}

// 压缩 CSS 文件
function compressCSS(inputFile, outputFile) {
  const css = fs.readFileSync(inputFile, "utf8");
  const options = {};
  const output = new CleanCSS().minify(css);
  fs.outputFileSync(outputFile, output.styles);
  console.log(`CSS 压缩完成![${outputFile}]`);
}

// 压缩 JavaScript 文件
function compressJS(inputFile, outputFile) {
  const code = fs.readFileSync(inputFile, "utf8");
  const options = {
    compress: {
      dead_code: true,
      drop_console: true,
    },
    mangle: true,
    output: {
      comments: false,
    },
    sourceMap: false, // 不生成 source map
  };
  const result = terser.minify_sync(code, options);
  if (result.error) {
    console.error(`压缩 JavaScript 文件 [${inputFile}] 时出错:`, result.error);
  } else {
    fs.outputFileSync(outputFile, result.code);
    console.log(`JavaScript 文件压缩完成![${outputFile}]`);
  }
}

// 压缩 HTML、CSS 和 JavaScript
// function compressFiles(htmlFile, cssFile, jsFile) {
//   const compressedHtmlFile = 'compressed.html';
//   const compressedCssFile = 'compressed.css';
//   const compressedJsFile = 'compressed.js';

//   compressHTML(htmlFile, compressedHtmlFile);
//   compressCSS(cssFile, compressedCssFile);
//   compressJS(jsFile, compressedJsFile);
// }

// // 在这里指定要压缩的文件路径
// const htmlFile = 'input.html';
// const cssFile = 'styles.css';
// const jsFile = 'script.js';

// 执行压缩
// compressFiles(htmlFile, cssFile, jsFile);
//这个方法暂时不用
async function traverseFiles(directory, suffix = ".html") {
  let fileList = [];
  const files = await fs.readdir(directory);
  // console.log(files, 111);
  for (const file of files) {
    const fullPath = path.join(directory, file);
    // const stats = await fs.stat(fullPath);
    // if (stats.isDirectory()) {
    //   fileList = fileList.concat(await traverseFiles(fullPath));
    // } else
    if (path.extname(fullPath) === suffix) {
      fileList.push({ name: file, path: fullPath });
    }
  }
  return fileList;
}

module.exports = {
  compressCSS,
  compressJS,
  compressHTML,
  traverseFiles,
};


index.js如下:

const path = require("path");
const fs = require("fs-extra");
const zlib = require("zlib");

const { compressCSS, compressJS, compressHTML } = require("./compress");

// console.log(__dirname,path.resolve(__dirname,'../'),path.join(__dirname,'/'));

const funcMap = {
  ".html": compressHTML,
  ".js": compressJS,
  ".css": compressCSS,
};

function compressZip(fullPath, name) {
  const readStream = fs.createReadStream(fullPath);
  fs.ensureDirSync(path.resolve(__dirname, `./dist/gzip`)); //创建目录
  const writeStream = fs.createWriteStream(
    path.resolve(__dirname, `./dist/gzip/${name}.gz`)
    // `${fullPath}.gz`
  );
  const gzip = zlib.createGzip();
  readStream.pipe(gzip).pipe(writeStream);
}

async function traverseFiles(directory) {
  const files = await fs.readdir(directory);
  for (const file of files) {
    const fullPath = path.join(directory, file);
    const suffix = path.extname(fullPath);
    if (Object.keys(funcMap).includes(suffix)) {
      funcMap[suffix](fullPath, `./dist/${file}`);
      compressZip(fullPath, file);
    }
  }
}

async function main() {
  const inputPath = path.resolve(__dirname, "../");
  await traverseFiles(inputPath);
}

main();

其中 compressZip()函数 用于将压缩后的文件, 再次通过gzip压缩成对应的.gz 文件