rm-cstyle-cmts
TypeScript icon, indicating that this package has built-in type declarations

3.3.13 • Public • Published

Node.js CI CircleCI codecov npm version node GitHub

FOSSA Status DeepScan grade Maintainability Test Coverage GitHub code size in bytes npm bundle size npm GitHub commit activity

remove cstyle comments (rm-cstyle-cmts)

remove c style comments from text file. (javascript source, json file etc

  • This module removes comments from source files such as typescript and javascript.
    It does not remove lines that are meaningful to typescript, such as @ts-ignore and <reference types="node"/>,
    but removes other single line comments and multi line comments.

  • For other single line comment and multi line comment, it is possible to control which comment is remove by setting scan listener.

  • This module is much faster than the popular comment removal module.

  • gulp plugin is available.

  • web version is available.

  • new property keepJsDoc (v3.3.11)

install

  • npm
$ npm install rm-cstyle-cmts --save-dev  
# shorthand  
$ npm i rm-cstyle-cmts -D
  • yarn
$ yarn add rm-cstyle-cmts -D

Features

  • remove mode
const rmc = require("rm-cstyle-cmts");
const removed = rmc("<source file content>");
  • walkthrough mode (walkthrough mode does things like statistics for source code comments by setting a scan listener.)
const rmc = require("rm-cstyle-cmts");

/** @type {Map<string, number>} */
const tagStatistics = new Map();
/**
 * Take statistics for jsDoc tag
 *
 * @param {object} context
 * @param {TScannerEventContext["event"]} context.event - currently EScannerEvent.(SingleLineComment | MultiLineComment) only
 * @param {TScannerEventContext["fragment"]} context.fragment comment body
 * @param {TScannerEventContext["offset"]} context.offset - fragment start offset from original source
 */
function handleScanEvent({ event, fragment, offset }) => {
  if (event === /*EScannerEvent.MultiLineComment*/1) {
      if (/^\/\*\*[^*]/.test(fragment)) {
          const re = /(?<=[\s\*{])@\w+(?=\s)/g;
          /** @type {RegExpExecArray} */
          let m;
          while (m = re.exec(fragment)) {
              const tag = m[0];
              let count = tagStatistics.get(tag) || 0;
              tagStatistics.set(tag, count + 1);
          }
      }
  }
  return true;
}

// At current implementation, accept one listener only
rmc.setListener(handleScanEvent);
rmc.walk("<source file content>");

API

node module.

const rmc = require("rm-cstyle-cmts");

run as remove mode

const opt = { collectRegex: true, showErrorMessage: true, preserveBlanks: true };
const removed = rmc("<source file content>", opt);
  • source {string} -- The target source content.
  • opt {object}
    • opt.collectRegex {true | undefined} -- Whether collect detected regex. Default: undefined.
    • opt.showErrorMessage {true | undefined} -- Whether to display an error message. Default: undefined.
    • opt.preserveBlanks {true | undefined} -- Whether preserve whitespace and blank lines. Default: undefined.

run as walkthrough mode

const opt = { collectRegex: true, showErrorMessage: true };
rmc.walk("<source file content>", opt);
  • source {string} -- The target source content.
  • opt {object}
    • opt.collectRegex {true | undefined} -- Whether collect detected regex. Default: undefined.
    • opt.showErrorMessage {true | undefined} -- Whether to display an error message. Default: undefined.

Playground

Performance measurement with Benchmark.js

$ npm run benchmark
  • We are comparing the process of deleting only comment from the following sample

    const json = `// see: http://json.schemastore.org/tsconfig
    {
      "compilerOptions": {
        /* Basic Options */
        "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
        "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
        // "allowJs": true,                       /* Allow javascript files to be compiled. */
        // "checkJs": true,                       /* Report errors in .js files. */
        // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
        // "sourceMap": true,                     /* Generates corresponding '.map' file. */
        // "outFile": "./",                       /* Concatenate and emit output to single file. */
        // "outDir": "./",                        /* Redirect output structure to the directory. */
    
        /* Strict Type-Checking Options */
        "strict": true,                           /* Enable all strict type-checking options. */
        // "strictNullChecks": true,              /* Enable strict null checks. */
        // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    
        /* Additional Checks */
        // "noUnusedLocals": true,                /* Report errors on unused locals. */
        // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    
        /* Module Resolution Options */
        // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
        // "typeRoots": [],                       /* List of folders to include type definitions from. */
        "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    
        /* Experimental Options */
        // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
        // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
      },
      "files": [
        "y"
      ]
    }`;

node v12.22.11

yarn run v1.22.18
$ node bench.mjs

- - - - - - - bench mark test - - - - - - - - -
Platform info:
Windows_NT 10.0.19043 x64
Node.JS: 12.22.11
V8     : 7.8.279.23-node.56
Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz x 4

strip-comments x 11,677 ops/sec ±0.32% (90 runs sampled)
strip-json-comments x 16,759 ops/sec ±0.11% (97 runs sampled)
rm-cstyle-cmts x 169,240 ops/sec ±0.09% (95 runs sampled)
rm-cstyle-cmts (webpack) x 174,768 ops/sec ±0.16% (94 runs sampled)
rm-cstyle-cmts (umd) x 172,408 ops/sec ±0.18% (94 runs sampled)
- - done - -
all results are equals? true # see NOTE:
Done in 27.79s.

node v17.9.0

yarn run v1.22.18
$ node etc/bench/bench.mjs

- - - - - - - bench mark test - - - - - - - - -
Platform info:
Windows_NT 10.0.19043 x64
Node.JS: 17.9.0
V8     : 9.6.180.15-node.16
Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz x 4

strip-comments x 11,327 ops/sec ±0.43% (87 runs sampled)
strip-json-comments x 17,281 ops/sec ±0.08% (95 runs sampled)
rm-cstyle-cmts x 163,564 ops/sec ±0.08% (94 runs sampled)
rm-cstyle-cmts (webpack) x 159,575 ops/sec ±0.08% (93 runs sampled)
rm-cstyle-cmts (umd) x 160,841 ops/sec ±0.18% (96 runs sampled)
- - done - -
all results are equals? true # see NOTE:
Done in 27.74s.
  • NOTE: strip-comments may be buggy and is excluded from comparison

The Walkthrough mode

Walkthrough mode is not modify original source.

The current implementation calls the listener on line comment and multi-line comment scan events.

import * as rmc from "rm-cstyle-cmts";

/**
 * @param {object} context
 * @param {TScannerEventContext["event"]} context.event - currently EScannerEvent.(SingleLineComment | MultiLineComment) only
 * @param {TScannerEventContext["fragment"]} context.fragment comment body
 * @param {TScannerEventContext["offset"]} context.offset - fragment start offset from original source
 */
function handleScanEvent({ event, fragment, offset }) => {
  if (event === /*EScannerEvent.MultiLineComment*/1) {
    // remove mode: preserve JSDoc comment
    // walkthrough mode: whether proceed walkthrough
    return /^\/\*\*[^*]/.test(fragment);
  }
  return false;
}
// At current implementation, accept one listener only
rmc.setListener(handleScanEvent);

const opt = { collectRegex: true, showErrorMessage: true };
rmc("<commented source>", opt);
rmc.walk("<commented source>", opt);

NOTE: Handling of listener in remove mode and walkthrough mode

  • In walkthrough mode: Returns true to continue processing. otherwise stop processing.

  • In remove mode: it returns true to preserve in the line comment and multi line comment deletion process.

rm-cstyle-cmts gulp plugin

gulp plugin sample task

  • sample task to scan javascript related files directly under node_modules
$ npm run grmc-test:cjs

API of gulp plugin

const gulp = require("gulp"); 
const grmc = require("rm-cstyle-cmts/cjs/gulp/");
const grmcOpt = {
    preserveBlanks: undefined, // remove blank lines and traling whitespace
    renderProgress: true,      // show progress
    // isWalk: true // want walk through?
};
gulp.src(["./src/**/*.{js,jsx,ts,tsx}"]).pipe(
    grmc.getTransformer(grmcOpt)
).pipe(gulp.dest("./tmp"));

gulp plugin options

  • preserveBlanks {true | undefined} -- Whether preserve whitespace and blank lines. Default: undefined.
  • renderProgress {true | undefined} -- log scan source path(relative) currently being processed. Default: undefined.
  • collectRegex {true | undefined} -- Whether collect detected regex. Default: undefined.
  • isWalk {true | undefined} -- Whether to run in walkthrough mode. Default: undefined.
  • extraExtensions {string[] | undefined} -- Add additional extensions. Default: undefined.
  • disableDefaultExtentions {true | undefined} -- use extraExtensions only, instaed of defaultExtensions. Default: undefined.
    • defaultExtensions - ".js", ".jsx", ".ts", ".tsx", ".cjs", ".mjs", ".cts", ".mts"
  • timeMeasure {true | undefined} -- Whether to record the processing time for each file (replace mode only). Default: undefined.

example with scan listener

const gulp = require("gulp"); 
const grmc = require("rm-cstyle-cmts/cjs/gulp/");

// set scan event listener
grmc.getRmcInterface().setListener(({ event, fragment, offset }) => {
    if (event === /*EScannerEvent.MultiLineComment*/1) {
        // true: Concatenate fragment to result in "remove mode", continue walkthrough in "walkthrough mode".
        // false: remove fragment in "remove mode", stop walkthrough in "walkthrough mode".
        return /^\/\*(\*|!)\s/.test(fragment);
    }
    else if (event === /*EScannerEvent.SingleLineComment*/0) {
        return /(?:\/\/\/?\s+@ts-\w+|\/\/\/\s*<reference)/.test(fragment);
    }
    // remove fragment in "remove mode", stop walkthrough in "walkthrough mode".
    return false;
});

gulp.src(["./src/**/*.{js,jsx,ts,tsx}"]).pipe(
    /**
     * preserveBlanks : keep blank line and whitespaces, default is `undefined`.
     */
    grmc.getTransformer({
        preserveBlanks: undefined, // remove blank lines and traling whitespace
        renderProgress: true,      // show progress
        // isWalk: true // want walk through?
    })
).pipe(gulp.dest("./tmp"));

rm-cstyle-cmts web version

  • You can use web version from cdn such as jsdelivr.
    • can use the API through the Rmc global variable.
<!-- or https://cdn.jsdelivr.net/npm/rm-cstyle-cmts@latest/umd/index.min.js -->
<script src="https://cdn.jsdelivr.net/npm/rm-cstyle-cmts@3/umd/index.min.js"></script>
const source = `
///  <reference types="node"/>

import React from "react";
import ReactDOM from "react-dom";

/**
 * jsdoc comment
 */
function App() {
  return (
    // TODO: can optionally include quote string in react syntax.
    // such source input does not complete successfully.
    <h1>Hello's world's</h1>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
`;

/**
 * You can use the API through the `Rmc` global variable.
 */
console.log(Rmc(source));
// print detected regex literals detail (in this case, nothing any result)
console.log(Rmc.getDetectedReContext());
// reset of related statistics
Rmc.reset();

usage

Case: single line input (js)

const rmc = require("rm-cstyle-cmts");
const input = "    /** block comment */ const a = \"this is apple! \\n\", b = 'quoted \"strings\"', \
c = `list:\\n1. \${a}\\n2. \${b}\\n\${ /* comments */ ` - len: \${a.length + b.length}`}\\n ---`;  \
/* . */  let i = 2, n = 12 / 4 * 7/i; // last coment.  !";

const result = rmc(input);
console.log(result);
//> const a = "this is apple! \n", b = 'quoted "strings"', c = `list:\n1. ${a}\n2. ${b}\n${ /* comments */ ` - len: ${a.length + b.length}`}\n ---`;    let i = 2, n = 12 / 4 * 7/i;

Case: json source

const rmc = require("rm-cstyle-cmts");
const json = `// see: http://json.schemastore.org/tsconfig
{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    // "allowJs": true,                       /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    // "outDir": "./",                        /* Redirect output structure to the directory. */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */

    /* Module Resolution Options */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
  },
  "files": [
    "y"
  ]
}`;

const result = rmc(input);
console.log(result);
//> {
//>   "compilerOptions": {
//>     "target": "es5",
//>     "module": "commonjs",
//>     "strict": true,
//>     "esModuleInterop": true
//>   },
//>   "files": [
//>     "y"
//>   ]
//> }

Package Sidebar

Install

npm i rm-cstyle-cmts

Weekly Downloads

165

Version

3.3.13

License

MIT

Unpacked Size

77.2 kB

Total Files

21

Last publish

Collaborators

  • motrohi