From e62c7a999ace9946af4c78666984b68d6ccb95d3 Mon Sep 17 00:00:00 2001 From: Mihai Ionut Vilcu Date: Sat, 30 Mar 2019 16:21:52 +0200 Subject: [PATCH 1/2] Adds support for the --input-source-map flag. --- README.md | 1 + index.js | 43 +++++++++++++++++----- package.json | 2 +- test/binary-test.js | 45 ++++++++++++++++++++++++ test/fixtures/source-maps/map/input.map | 1 + test/fixtures/source-maps/map/styles.css | 3 ++ 6 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/source-maps/map/input.map create mode 100644 test/fixtures/source-maps/map/styles.css diff --git a/README.md b/README.md index 747143c..a08f6c1 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ clean-css-cli 4.1 introduces the following changes / features: --skip-rebase Disable URLs rebasing --source-map Enables building input's source map --source-map-inline-sources Enables inlining sources inside source maps +--input-source-map [file] Specifies the path of the input source map file ``` ## Compatibility modes diff --git a/index.js b/index.js index ef646c9..3d853a3 100644 --- a/index.js +++ b/index.js @@ -34,7 +34,8 @@ function cli(process, beforeMinifyCallback) { .option('--remove-inlined-files', 'Remove files inlined in or via `@import` statements') .option('--skip-rebase', 'Disable URLs rebasing') .option('--source-map', 'Enables building input\'s source map') - .option('--source-map-inline-sources', 'Enables inlining sources inside source maps'); + .option('--source-map-inline-sources', 'Enables inlining sources inside source maps') + .option('--input-source-map [file]', 'Specifies the path of the input source map file'); commands.on('--help', function () { console.log(' Examples:\n'); @@ -156,14 +157,25 @@ function cli(process, beforeMinifyCallback) { sourceMapInlineSources: commands.sourceMapInlineSources }; + if (commands.inputSourceMap && !options.sourceMap) { + options.sourceMap = true; + } + if (options.sourceMap && !options.output) { outputFeedback(['Source maps will not be built because you have not specified an output file.'], true); options.sourceMap = false; } + var configurations = { + beforeMinifyCallback: beforeMinifyCallback, + debugMode: debugMode, + removeInlinedFiles: removeInlinedFiles, + inputSourceMap: commands.inputSourceMap + }; + // ... and do the magic! if (commands.args.length > 0) { - minify(process, beforeMinifyCallback, options, debugMode, removeInlinedFiles, expandGlobs(commands.args)); + minify(process, options, configurations, expandGlobs(commands.args)); } else { stdin = process.openStdin(); stdin.setEncoding('utf-8'); @@ -172,7 +184,7 @@ function cli(process, beforeMinifyCallback) { data += chunk; }); stdin.on('end', function () { - minify(process, beforeMinifyCallback, options, debugMode, removeInlinedFiles, data); + minify(process, options, configurations, data); }); } } @@ -211,15 +223,15 @@ function expandGlobs(paths) { }, []); } -function minify(process, beforeMinifyCallback, options, debugMode, removeInlinedFiles, data) { +function minify(process, options, configurations, data) { var cleanCss = new CleanCSS(options); applyNonBooleanCompatibilityFlags(cleanCss, options.compatibility); - beforeMinifyCallback(cleanCss); - cleanCss.minify(data, function (errors, minified) { + configurations.beforeMinifyCallback(cleanCss); + cleanCss.minify(data, getSourceMapContent(configurations.inputSourceMap), function (errors, minified) { var mapFilename; - if (debugMode) { + if (configurations.debugMode) { console.error('Original: %d bytes', minified.stats.originalSize); console.error('Minified: %d bytes', minified.stats.minifiedSize); console.error('Efficiency: %d%', ~~(minified.stats.efficiency * 10000) / 100.0); @@ -240,7 +252,7 @@ function minify(process, beforeMinifyCallback, options, debugMode, removeInlined process.exit(1); } - if (removeInlinedFiles) { + if (configurations.removeInlinedFiles) { minified.inlinedStylesheets.forEach(fs.unlinkSync); } @@ -289,6 +301,21 @@ function outputFeedback(messages, isError) { }); } +function getSourceMapContent(sourceMapPath) { + if (!sourceMapPath || !fs.existsSync(sourceMapPath)) { + return null; + } + var content = null; + + try { + content = fs.readFileSync(sourceMapPath).toString(); + } catch (e) { + console.error('Failed to read the input source map file.'); + } + + return content; +} + function output(process, options, minified) { if (options.output) { fs.writeFileSync(options.output, minified, 'utf8'); diff --git a/package.json b/package.json index 52ed360..cc465ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clean-css-cli", - "version": "4.2.0", + "version": "4.3.0", "description": "A command-line interface to clean-css CSS optimization library", "scripts": { "check": "jshint ./bin/cleancss .", diff --git a/test/binary-test.js b/test/binary-test.js index 816e725..bdcf10e 100644 --- a/test/binary-test.js +++ b/test/binary-test.js @@ -694,4 +694,49 @@ vows.describe('cleancss') } } }) + .addBatch({ + 'process an input-source-map': pipedContext(fs.readFileSync('./test/fixtures/source-maps/map/styles.css'), '-o ./test/styles.min.css --input-source-map ./test/fixtures/source-maps/map/input.map', { + 'enables the source map flag': function() { + assert.isTrue(fs.existsSync('test/styles.min.css')); + assert.isTrue(fs.existsSync('test/styles.min.css.map')); + }, + 'teardown': function () { + deleteFile('test/styles.min.css'); + deleteFile('test/styles.min.css.map'); + } + }) + }) + .addBatch({ + 'missing an input-source-map': pipedContext(fs.readFileSync('./test/fixtures/source-maps/map/styles.css'), '-o ./test/styles.min.css', { + 'does not generate a source map if the parameter is missing': function() { + assert.isTrue(fs.existsSync('test/styles.min.css')); + assert.isFalse(fs.existsSync('test/styles.min.css.map')); + }, + 'teardown': function () { + deleteFile('test/styles.min.css'); + } + }) + }) + .addBatch({ + 'content of input-source-map': pipedContext(fs.readFileSync('./test/fixtures/source-maps/map/styles.css'), '-o ./test/styles.min.css --input-source-map ./test/fixtures/source-maps/map/input.map', { + 'includes the right content of the source map': function() { + assert.isTrue(fs.existsSync('test/styles.min.css.map')); + var sourceMap = new SourceMapConsumer(fs.readFileSync('./test/styles.min.css.map', 'utf-8')); + + assert.deepEqual( + sourceMap.originalPositionFor({ line: 1, column: 1 }), + { + source: 'styles.less', + line: 1, + column: 4, + name: null + } + ); + }, + 'teardown': function () { + deleteFile('test/styles.min.css'); + deleteFile('test/styles.min.css.map'); + } + }) + }) .export(module); diff --git a/test/fixtures/source-maps/map/input.map b/test/fixtures/source-maps/map/input.map new file mode 100644 index 0000000..ae44ee0 --- /dev/null +++ b/test/fixtures/source-maps/map/input.map @@ -0,0 +1 @@ +{"version":3,"sources":["styles.less"],"names":[],"mappings":"AAAA,GAAI;EACF,WAAA","file":"styles.css"} diff --git a/test/fixtures/source-maps/map/styles.css b/test/fixtures/source-maps/map/styles.css new file mode 100644 index 0000000..5a22897 --- /dev/null +++ b/test/fixtures/source-maps/map/styles.css @@ -0,0 +1,3 @@ +div > a { + color: blue; +} From 89deb398eaf587842d6630bc6ba852f96ca7ce54 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Wed, 3 Apr 2019 09:19:31 +0300 Subject: [PATCH 2/2] Update package.json Co-Authored-By: ionutvmi --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc465ce..2bcf5dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clean-css-cli", - "version": "4.3.0", + "version": "4.3.0-pre", "description": "A command-line interface to clean-css CSS optimization library", "scripts": { "check": "jshint ./bin/cleancss .",