Skip to content
This repository has been archived by the owner on Jan 30, 2024. It is now read-only.

Commit

Permalink
Merge pull request #22 from pirxpilot/source_maps
Browse files Browse the repository at this point in the history
Implement support for source maps
  • Loading branch information
mjonuschat committed Jul 25, 2014
2 parents b37a5e4 + 3263486 commit 4c77a93
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 14 deletions.
25 changes: 25 additions & 0 deletions Gruntfile.js
Expand Up @@ -43,6 +43,16 @@ module.exports = function(grunt) {
dest: 'tmp/extended.js',
}]
},
sourcemap: {
options: {
include: ['test/fixtures', 'test/fixtures/lib'],
enable: ['source_maps']
},
files: [{
src: 'test/fixtures/main.css.less',
dest: 'tmp/main.css'
}]
},
manifest: {
options: {
manifestPath: 'tmp/manifest/manifest.json',
Expand All @@ -53,6 +63,21 @@ module.exports = function(grunt) {
dest: 'tmp/mainfest.js'
}]
},
manifestmap: {
options: {
manifestPath: 'tmp/manifest/manifest.json',
manifestOptions: {
compress: false,
sourceMaps: true,
embedMappingComments: true
},
include: ['test/fixtures', 'test/fixtures/lib'],
},
files: [{
src: 'test/fixtures/main.css.less',
dest: 'tmp/main.css'
}]
},
helpers: {
options: {
include: 'test/fixtures',
Expand Down
19 changes: 17 additions & 2 deletions README.md
Expand Up @@ -69,6 +69,10 @@ JavaScript compression function or predefined `mincer` js compressor identifier

CSS compression function or predefined `mincer` css compressor identifier `"csso"`. If predefined identifier is used - `csso` package needs to be installed. Check out [mincer cssCompressor documentation](http://nodeca.github.io/mincer/#Compressing.prototype.cssCompressor) for more details.

#### sourceMappingBaseURL ```string```

The base url to use when referencing source-maps in compiled assets. Defaults to `""` if not explicitly set.

### Files

The files on which the task operates can be defined using all the powerful options provided by Grunt.
Expand Down Expand Up @@ -148,7 +152,12 @@ mince: {
main: {
options: {
include: ["src", "module/src"],
manifestPath: "build/manifest.json"
manifestPath: "build/manifest.json",
manifestOptions: {
compress: false,
sourceMaps: false,
embedMappingComments: false
}
},
files: [
{
Expand All @@ -160,8 +169,14 @@ mince: {
}
```

You can use a different format for each target.
By setting the `manifestPath` you enable compiling and writing the assets to the given directory. The
assets will be written to fingerprinted files. Optionally you can specify `manifestOptions`. This object
will be passed through to mincer unmodified. See the [mincer documentation][manifest_options] for supported options.
The defaults are to disable compression and source maps.

[manifest_options]: http://nodeca.github.io/mincer/#Manifest.prototype.compile

You can use a different format for each target.

You can configure Mincer engines: this configures `CoffeeEngine` to use `bare` compilation option,
and instructs `StylusEngine` to use `nib`.
Expand Down
16 changes: 10 additions & 6 deletions package.json
Expand Up @@ -14,10 +14,12 @@
"bugs": {
"url": "https://github.com/pirxpilot/grunt-mincer/issues"
},
"licenses": [{
"type": "MIT",
"url": "https://github.com/pirxpilot/grunt-mincer/blob/master/LICENSE-MIT"
}],
"licenses": [
{
"type": "MIT",
"url": "https://github.com/pirxpilot/grunt-mincer/blob/master/LICENSE-MIT"
}
],
"main": "grunt.js",
"bin": "bin/grunt-mincer",
"engines": {
Expand All @@ -27,15 +29,17 @@
"test": "grunt test"
},
"dependencies": {
"mincer": "~1.0"
"mincer": "~1.0",
"source-map": "~0.1.37"
},
"devDependencies": {
"grunt": "~0.4",
"grunt-contrib-clean": "~0",
"grunt-contrib-jshint": "~0",
"grunt-contrib-nodeunit": "~0",
"grunt-contrib-watch": "~0",
"ejs": "~0"
"ejs": "~0",
"less": "~1.7.0"
},
"peerDependencies": {
"grunt": "~0.4"
Expand Down
49 changes: 44 additions & 5 deletions tasks/lib/helpers.js
Expand Up @@ -7,7 +7,9 @@
*/

var Mincer = require('mincer'),
path = require('path');
path = require('path'),
SourceMapConsumer = require('source-map').SourceMapConsumer,
SourceNode = require('source-map').SourceNode;

exports.init = function (grunt) {
'use strict';
Expand Down Expand Up @@ -90,15 +92,20 @@ exports.init = function (grunt) {
var resolvedAssets = src.map(function(filepath) {
return logicalAssetName(environment, filepath);
});

if ((options.manifestOptions.sourceMaps !== null) && options.manifestOptions.sourceMaps) {
environment.enable('source_maps');
}

var manifest = new Mincer.Manifest(environment, options.manifestPath);
return manifest.compile(resolvedAssets);
return manifest.compile(resolvedAssets, options.manifestOptions);
}

asset = environment.findAsset(path.basename(src));
if (!asset) {
grunt.fail.warn('Cannot find logical path ' + src.cyan);
}
return asset.toString();
return asset;
};

exports.compileManifest = function(files, options) {
Expand Down Expand Up @@ -131,6 +138,7 @@ exports.init = function (grunt) {
exports.compileAssets = function(files, options) {
files.forEach(function (file) {
var output = [];
var sourceNode = new SourceNode();
var valid = file.src.filter(function(filepath) {
// Warn on and remove invalid source files (if nonull was set).
if (!grunt.file.exists(filepath)) {
Expand All @@ -151,11 +159,42 @@ exports.init = function (grunt) {
}

if (options.banner) {
output.unshift(options.banner + grunt.util.linefeed);
sourceNode.add(options.banner);
sourceNode.add(grunt.util.linefeed);
}

grunt.file.write(file.dest, output.join(''));
output.forEach(function(asset) {
if(asset.sourceMap && asset.sourceMap.mappings !== '') {
sourceNode.add(SourceNode.fromStringWithSourceMap(asset.toString(), new SourceMapConsumer(asset.sourceMap)));
} else {
asset.toString().split('\n').forEach(function(line, j){
sourceNode.add(new SourceNode(j + 1, 0, asset.relativePath, line + '\n'));
});
sourceNode.add('\n');
}
});

if([].concat(options.enable).indexOf('source_maps') > -1) {
if (/\.css$/.test(file.dest)) {
sourceNode.add('/*# sourceMappingURL=' + options.sourceMappingBaseURL + file.dest + '.map' + ' */');
} else {
sourceNode.add('//# sourceMappingURL=' + options.sourceMappingBaseURL + file.dest + '.map');
}
}

var mappedOutput = sourceNode.toStringWithSourceMap({
file: file.dest,
sourceRoot: ''
});

grunt.file.write(file.dest, mappedOutput.code.toString());
grunt.log.writeln('File ' + file.dest.cyan + ' created...');

if([].concat(options.enable).indexOf('source_maps') > -1) {
var mapFile = file.dest + '.map';
grunt.file.write(mapFile, mappedOutput.map.toString());
grunt.log.writeln('File ' + mapFile.cyan + ' created...');
}
});
};

Expand Down
6 changes: 6 additions & 0 deletions tasks/mincer.js
Expand Up @@ -17,6 +17,12 @@ module.exports = function (grunt) {
include: [],
enable: [],
manifestPath: '',
manifestOptions: {
compress: true,
sourceMaps: true,
embedMappingComments: true
},
sourceMappingBaseURL: '',
helpers: {},
engines: {},
jsCompressor: null,
Expand Down
5 changes: 5 additions & 0 deletions test/expected/main.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions test/expected/main.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions test/expected/main.js
Expand Up @@ -7,3 +7,5 @@ function local() {}

function main() {}
;


2 changes: 2 additions & 0 deletions test/fixtures/main.css.less
@@ -0,0 +1,2 @@
@baseColor: #333;
body { color: @baseColor; }
17 changes: 16 additions & 1 deletion test/mincer_test.js
Expand Up @@ -30,11 +30,26 @@ exports.mince = {
test.done();
},

'mince manifestmap': function(test) {
test.expect(4);

var manifest = grunt.file.readJSON('tmp/manifest/manifest.json');
test.ok(manifest.assets, 'manifest is valid');
test.ok(manifest.files, 'manifest is valid');
test.equal(manifest.assets['main.css'].indexOf('main-'), 0, 'generated asset name starts with original asset name');

var expected = grunt.file.read('test/expected/main.css.map');
var actual = grunt.file.read('tmp/manifest/' + manifest.assets['main.css'] + '.map');
test.equal(expected, actual, 'should generate source map');

test.done();
},

'mince helpers': function(test) {
test.expect(1);

var expected = 'console.log("Version: 3.2.1");';
var actual = grunt.file.read('tmp/version.js');
var actual = grunt.file.read('tmp/version.js').trim();
test.equal(expected, actual, 'should use mince helpers in EJS');

test.done();
Expand Down

0 comments on commit 4c77a93

Please sign in to comment.