or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-uglify-save-license

License detector for UglifyJS that identifies and preserves license comments during minification

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/uglify-save-license@0.4.x

To install, run

npx @tessl/cli install tessl/npm-uglify-save-license@0.4.0

index.mddocs/

uglify-save-license

uglify-save-license is a license detector that identifies and preserves license comments during UglifyJS minification. It analyzes JavaScript comment tokens to intelligently determine which comments contain license information that should be preserved during code compression.

Package Information

  • Package Name: uglify-save-license
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install uglify-save-license

Core Imports

const saveLicense = require('uglify-save-license');

ES modules (if supported by your environment):

import saveLicense from 'uglify-save-license';

Basic Usage

const UglifyJS = require('uglify-js');
const saveLicense = require('uglify-save-license');

// Use with UglifyJS2
const result = UglifyJS.minify('file.js', {
  output: {
    comments: saveLicense
  }
});

// Use with grunt-contrib-uglify
grunt.initConfig({
  uglify: {
    my_target: {
      options: {
        preserveComments: saveLicense
      },
      src: ['src/app.js'],
      dest: 'dest/app.min.js'
    }
  }
});

Capabilities

License Detection Function

The main export function that determines whether a comment should be preserved during minification based on license detection heuristics.

/**
 * Determines whether a comment should be preserved as a license comment
 * @param {Object} node - UglifyJS AST node (currently unused but part of callback signature)
 * @param {Object} comment - UglifyJS comment token with the following properties:
 *   @param {string} comment.file - Name of the file being processed
 *   @param {string} comment.value - Content of the comment
 *   @param {string} comment.type - Comment type ('comment1' for //, 'comment2' for /* */)
 *   @param {number} comment.line - Line number where comment appears
 * @returns {boolean} - Returns true if comment should be preserved, false otherwise
 */
function saveLicense(node, comment)

The function identifies license comments using these detection criteria:

  1. Pattern Matching: Comments matching the license detection regex /@preserve|@cc_on|\bMIT\b|\bMPL\b|\bGPL\b|\bBSD\b|\bISCL\b|\(c\)|License|Copyright/mi:

    • Preservation directives: @preserve, @cc_on
    • License type keywords: MIT, MPL, GPL, BSD, ISCL
    • Copyright indicators: (c), Copyright, License
  2. Special Comment Formats:

    • Block comments starting with ! (e.g., /*! ... */)
  3. Position-Based Detection:

    • Comments on the first line of a file
    • Comments immediately following another preserved license comment (consecutive license blocks)

Note on Stateful Behavior: The function maintains internal state to track the line number of the last preserved comment (prevCommentLine) and the current file being processed (prevFile). This allows it to identify consecutive license comment blocks that should be preserved together, even if only the first comment in the block matches the license patterns.

Usage Examples:

const UglifyJS = require('uglify-js');
const saveLicense = require('uglify-save-license');

// CLI tool example
const minified = UglifyJS.minify(process.argv[2], {
  output: {
    comments: saveLicense
  }
}).code;

console.log(minified);

Detection Examples:

Given this input file:

// First line comment - preserved (position-based: line 1)
// (c) 2024 Company Name - preserved (pattern match: contains "(c)")
// This line is also preserved (consecutive: follows preserved comment)

// This comment won't be preserved (no match, not consecutive)
function myFunction() {
  /*! Important license notice */ // preserved (special format: starts with !)
  return 'Hello World';
}

The function will preserve the first three comments and the /*! comment while removing the regular comment. The consecutive behavior ensures that multi-line license headers stay together even if only the first line contains recognizable license patterns.