Keep source maps when saving files in a different folder with Gulp - gulp

I'm trying to make a Gulp task that takes JS files, runs uglify on them, adds a .min suffix to the filename and then saves them in a destination folder that is different than the source folder. The tricky part is to keep source maps working...
gulp.task('uglify-js', function () {
// Fetch CSS files
return gulp.src(['assets/js/*.js', '!assets/js/*.min.js'])
// Start source map
.pipe(sourcemaps.init({loadMaps: true}))
// Uglify JS
.pipe(uglify())
// Add file suffix
.pipe(rename({suffix: '.min'}))
// Save source map
.pipe(sourcemaps.write())
// Save output to destination folder
.pipe(gulp.dest('public/js/'));
});
I tried many different options, but the source maps don't seem to work...
Does anyone know the right way to do this?
My packages:
"devDependencies": {
"gulp": "^3.8.10",
"gulp-rename": "^1.2.0",
"gulp-sourcemaps": "^1.3.0",
"gulp-uglify": "^1.0.2"
}
Thanks a bunch! :)

The problem is gulp-rename doesn't currently support gulp-sourcemaps, as mentioned in their latest issue.
One alternative is to use a different lib that supports sourcemaps, for example gulp-concat, which supports renaming the files. If you don't want to concat your files, however, you could always open a pull request against gulp-rename to add sourcemaps support, as documented here.
Update: As of 2015-03-14 gulp-rename now supports sourcemaps

Related

Gulp - globs - how to run sass function on all files in the folder EXCLUDING ONE?

I am a newcomer to Gulp. I have a gulp file and I am running one task in it -
gulp.task('sass', function () {
return gulp.src('app/scss/**/.scss') // Get source files with gulp.src
.pipe(sass()) // Sends it through a gulp plugin
.pipe(gulp.dest('app/css')) // Outputs the file in the destination folder
});
in the above code what i want to do is:
I have four scss files in app/scss folder:
site1.scss
site2.scss
site3.scss
copy.scss
Now i want to run the sass task and have all the files in scss folder excuding one particular file 'copy.scss'. I don't want the 'copy.scss' file to be converted into css file.
How do I do it?
Any help would be apprecisted
Try
return gulp.src(['app/scss/**/*.scss', '!app/scss/**/copy.scss'])
Note the ! It allows you to negate or remove from the stream a file or files. Also note I added a * to your *.scss

Gulp task to create source maps affects all files, not just the ones that have changed

I'm trying to come up with a gulp task that generates new source maps whenever its corresponding .js file has changed, this is what I have so far:
gulp.task('maps', [ 'compile:ts' ], function () {
return gulp.src([
'app/**/*.js'
])
.pipe(newer({ dest: 'app', ext: '.js.map' }))
.pipe(print(function (filepath) {
return 'Creating source map for ' + filepath + '...';
}))
.pipe(sourcemaps.init())
.pipe(sourcemaps.write('./'))
.pipe(print(function (filepath) {
return 'Writing source map for ' + filepath + '...';
}))
.pipe(checkout())
.pipe(gulp.dest('app'))
;
});
Now two weird things happen:
gulp-newer returns all .js files, it doesn't matter if they were changed or not (regarding the timestamps of the .map.js files).
gulp-sourcemaps emits both, the .js and the .js.map file.
Can anyone provide a hint what I'm missing here?
gulp-sourcemaps emits both, the .js and the .js.map file.
That's to be expected, because that's how source maps work. Each .js file contains a sourceMappingURL comment that points to the .js.map file so your browser knows where to find it.
You can leave this out by using the addComment option:
.pipe(sourcemaps.write('./'), {addComment:false})
Of course, that means your HTTP server has to send a X-SourceMap header for each .js file.
gulp-newer returns all .js files, it doesn't matter if they were changed or not (regarding the timestamps of the .map.js files).
This might be caused by gulp-sourcemaps emitting both a .js and a .js.map file, effectively overwriting your existing .js file. Using the same source and destination directories is generally a bad idea, so using a different dest directory would solve this problem.
(It might also be caused by the checkout() pipe, but you didn't describe what that does. I'd try removing this and see if it works.)
However I don't think any of the above really matters, since your general approach and the way you're using gulp-sourcemaps is likely to be completely wrong. I assume you want sourcemaps from your original .ts files to your compiled .js files. In that case you need to use it in your compile:ts task. The way you're using it now will just produce an empty source map file.

Gulp process all files in directory

I have css and js files in a directory (and subdirectories). I'm looking into different tools to compress the assets in all the directories. I'm trying to find a way to get gulp to compress all the files in those directories and save the compressed file in the same directory and name it with the following convention: [name].min.css or [name].min.js. So example.js would become example.min.js.
Is there a way to achieve this?
I've read the following on this:
http://gulpjs.com/plugins/
https://github.com/gulpjs/gulp/blob/master/docs/getting-started.md
https://github.com/gulpjs/gulp/blob/master/docs/API.md
You usually don't want to generate the minified files in the same directory as the original files. You write all files that are generated by your build script to a single output directory. Some advantages of this approach are:
Makes it easier to clean the build and recreate everything from scratch: you just delete that one output folder.
You don't have to worry about generated files accidentally getting picked up by your build and getting processed again.
But since you asked, here's a solution that creates the minified files in the same directory as the original files. This creates a .min.css and .min.js file for every .css and .js file. All CSS files are assumed to be in a directory called css (or its subdirectories) and all JS files are assumed to be in a directory called js (or its subdirectories):
var gulp = require('gulp');
var rename = require('gulp-rename');
var cssnano = require('gulp-cssnano');
var uglify = require('gulp-uglify');
gulp.task('css', function () {
return gulp.src([
'css/**/*.css',
'!css/**/*.min.css',
])
.pipe(cssnano())
.pipe(rename(function(path) {
path.extname = ".min.css";
}))
.pipe(gulp.dest('css'));
});
gulp.task('js', function () {
return gulp.src([
'js/**/*.js',
'!js/**/*.min.js',
])
.pipe(uglify())
.pipe(rename(function(path) {
path.extname = ".min.js";
}))
.pipe(gulp.dest('js'));
});
gulp.task('default', ['css', 'js']);
Notice the negation pattern !css/**/*.min.css that is used to prevent the already minified CSS from getting minified again on the next build. Same for the JavaScript.
I used gulp-cssnano and gulp-uglify to minify the CSS and JS, but there's plenty of other options out there that can act as drop-in replacements.

Why dependency files still included after using Browserify

All:
I am pretty to new to Gulp and Browserify, what I did is transpile some jsx code and browserify them into a bundle.js file.
var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var reactify = require("reactify");
gulp.task("default", function(){
browserify({
entries: ["js/app.js"],
debug: true
})
.transform(reactify)
.bundle()
.pipe(source("bundle.js"))
.pipe(gulp.dest("dist/js/"));
});
In app.js, I specify a few require dependencies(each one may require some other file), and I thought browserify will parse them and compile into a single bundle.js file, but when I run it, even I only include bundle.js in index.html page, it still includes all those dependency files when I check in Chrome source tab, I wonder if this is just Chrome's feature to parse bundle file which gives me a list of dependency file list or it actually download those dependency files as well( My confuse is I actually can click and open those dependency files, so I guess Chrome download them all with bundle.js, but I am not sure about that)?
Thanks
If I understand you correctly, you are describing what debug: true in browserify gives you, aka source maps.
--debug -d Enable source maps that allow you to debug your files separately.
and
When opts.debug is true, add a source map inline to the end of the
bundle. This makes debugging easier because you can see all the
original files if you are in a modern enough browser.

Gulp + source maps (multiple output files)

I just started playing with gulp, and it's very fast and easy to use but it seems to have a critical flaw: what do you do when a task needs to output more than one type of file?
For example, gulp-less says it doesn't even support the sourceMapFilename option. I don't want my source map embedded in my CSS file. Am I hooped? Should I just go back to using Grunt, or is there a way to deal with this?
This task will take multiple files, do stuff to them, and output them along with source maps.
It will include the source code within the maps files by default, so you don't have to distribute the source code files too. This can be turned off by setting the includeContent option to false. See the gulp-sourcemaps NPM page for more source map options.
gulpfile.js:
var gulp = require("gulp");
var plugins = require("gulp-load-plugins")();
gulp.task("test-multiple", function() {
return gulp.src("src/*.scss")
.pipe(plugins.sourcemaps.init())
.pipe(plugins.sass())
.pipe(plugins.autoprefixer())
.pipe(plugins.sourcemaps.write("./"))
.pipe(gulp.dest("result"));
});
package.json
"gulp": "~3.8.6",
"gulp-load-plugins": "~0.5.3",
"gulp-sass": "~0.7.2",
"gulp-autoprefixer": "~0.0.8",
"gulp-sourcemaps": "~1.1.0"
The src directory:
first.scss
second.scss
The result directory after running the test-multiple task:
first.css
first.css.map // includes first.scss
second.css
second.css.map // includes second.scss
Gulp supports multiple output files fine. Please read the docs.
Example:
gulp.task('scripts', function () {
return gulp.src('app/*js')
.pipe(uglify())
.pipe(gulp.dest('dist'));
});
This will read in a bunch of JS files, minify them and output them to the dist folder.
As for the gulp-less issue. You could comment on the relevant ticket.
In the docs it shows you how to have multiple output files:
gulp.src('./client/templates/*.jade')
.pipe(jade())
.pipe(gulp.dest('./build/templates'))
.pipe(minify())`
.pipe(gulp.dest('./build/minified_templates'));