I use browserify and 6to5ify to compile ES6 to JS and assemble project.
The problem is that I can't find any solution, how to minify compiled javascript, and generate source-maps for minified js.
My build task code is:
'use strict';
var gulp = require('gulp'),
source = require('vinyl-source-stream'),
plumber = require('gulp-plumber'),
browserify = require('browserify'),
buffer = require('vinyl-buffer'),
uglify = require('gulp-uglify'),
buildErrorHandler = require('./../utilities/build-error-handler').handleBuildError
;
gulp.task('js:build-scripts', function() {
var commandLineParameters = process.argv.slice(2);
var releaseModeRequired = commandLineParameters.indexOf('--release') > -1;
var bundler = browserify({
debug: true,
entries: ['./src/js/entry-point.js']
})
;
var pipeLine = bundler
.transform('6to5ify')
.bundle()
.on('error', buildErrorHandler)
.pipe(plumber({
errorHandler: buildErrorHandler
}))
.pipe(source('application.js'));
if(releaseModeRequired){
pipeLine = pipeLine.pipe(buffer())
.pipe(uglify());
}
pipeLine =pipeLine.pipe(gulp.dest('build/js'))
;
return pipeLine;
});
If I don't minify code, sourcemaps are working fine, but if I uglify it, sourcemaps disappear.
I tried several solutions like this or this but none of them works.
EDITED:
"browserify": "^8.1.3",
"gulp": "^3.8.10",
This has been an issue with Browserify + Uglify.js for a long time. It got fixed in this commit, but has not been released yet and was release with v2.4.21.
Related
With LibSass deprecated, I see that I should replace the node-sass library with sass. In an express app, previously, you would use the node-sass-middleware and node-sass like so:
const express = require('express');
const sassMiddleware = require('node-sass-middleware');
const path = require('path');
const app = express();
app.use(sassMiddleware({
/* Options */
src: __dirname,
dest: path.join(__dirname, 'public'),
debug: true,
outputStyle: 'compressed',
prefix: '/prefix' href="prefix/style.css"/>
}));
app.use('/public', express.static(path.join(__dirname, 'public')));
The only indication I found about how to use the sass module with express is this article. This method does not use a middleware but instead runs the sass module via a script (configured inside the packages.json file). Here is the relevant part of the article:
"scripts": {
"start": "node .",
"dev": "nodemon . & npm run scss",
"scss": "sass --watch src/scss/main.scss public/styles/main.css"
},
But my confidence in this article is low. For starters, it seems to be compiling sass only in development (the "start" script does not use the "scss" script). Also, this method does not use a middleware.
So, I guess I have 2 questions:
is there a way to use a middleware (like the old node-sass-middleware) to use the sass module with express? (It would be easier to update my code and I'm lazy...)
If not, is the example in the article the correct way to use sass with express?
I didn't want to rely on remembering to run a script manually (I would definitely forget to do it) and combining scripts with "&" (or even "&&") like in the article was not working so well for me.
I wanted to use code to launch the script, so what I did is just compile my CSS synchronously when the server starts.
Here is my code:
app.js
const express = require('express');
const path = require('path');
const { compileCss } = require('./compileCss');
const app = express();
const sassOptions = {
src: path.join(__dirname, 'public'),
dest: path.join(__dirname, 'public')
};
compileCss(sassOptions);
app.use('/public', express.static(path.join(__dirname, 'public')));
# ... rest of app.js code
compileCss.js
const sass = require('sass');
const { readdirSync , writeFileSync} = require('fs');
const path = require('path');
const compileCss = ({src, dest, ext=[".sass", ".scss"]}) => {
const srcFiles = readdirSync(src, {withFileTypes: true}).filter(dirent => dirent.isFile() && ext.includes(path.extname(dirent.name)));
for(const file of srcFiles) {
const srcFilePath = path.join(src, file.name);
const baseName = path.basename(file.name, path.extname(file.name));
const cssName = baseName + '.css';
const destFilePath = path.join(dest, cssName);
const result = sass.compile(srcFilePath);
writeFileSync(destFilePath, result.css, 'utf-8');
}
}
module.exports = { compileCss }
I haven't tested it yet, but I think if you download dart-sass-middleware and require it instead of node-sass-middleware then it should work.
This is what I ran to install it:
npm install dart-sass-middleware
More details on dart-sass-middleware can be found at https://www.npmjs.com/package/dart-sass-middleware
Let me know if it works!
Instead of node-sass-middleware you can use express-dart-sass.
Here is their repo.
I'm working on a legacy site that has some pre-set-up Gulp commands.
I want to compile some .less files into .css. The existing script is as such:
gulp.task('less', function(){
return gulp.src('./src/css/less/app.less')
.pipe(less({
paths: [ path.join(__dirname, 'less', 'includes') ]
}))
.pipe(gulp.dest('./src/css/'))
});
However, when I run this I get an error:
Error: File not found with singular glob: /src/css/less/app.less (if this was purposeful, use `allowEmpty` option)
I've checked all paths, all #import and directories and they're all ok.
I am using Gulp Local: 4.0.0, CLI: 2.3.0.
Would anyone know could be causing this?
Maybe later, but Gulp 4 has a new syntax for writing tasks.
Also, you have to fix the wrong path to the source file:
// gulpfile.js
const SRC = 'src';
const DIST = 'src';
function lessTask(cb) {
return src(SRC + '/less/app.less')
.pipe(less())
.pipe(dest(DIST + '/style.css'));
}
exports.default = series(lessTask);
# On terminal:
gulp
I configured this Gulp task for my local project. It is perfectly watching my folders, compiling the SCSS files to CSS.
Only problem is that -
On an average my Gulp Task runs 'sass' task around 6 times in a second, whether I make any change in code or not. It keeps on running like this redundantly even after closing the IDE (SublimeText). I feel like it might not be a good practice and also compromising my machine's performance.
Here's my Gulp code:
var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('sass', function(){
return gulp.src('compile/style.scss')
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sass())
.pipe(sass({outputStyle: 'expanded',sourceComments: false}))
.pipe(sourcemaps.write('../../../compile'))
.pipe(gulp.dest('public/assets/css'));
});
gulp.task('watch', function(){
gulp.watch('compile/**/*', gulp.series('sass'));
});
gulp.task('default', gulp.series('sass','watch'));
You are creating a loop because of these two lines:
.pipe(sourcemaps.write('../../../compile')) // saving to compile
gulp.task('watch', function(){
gulp.watch('compile/**/*', gulp.series('sass')); // watching compile
});
So your sass task runs , writes to the compile folder which the watch sees has changed and it fires the sass task again, over and over.
Save your sourcemaps somewhere that isn't including in your watch folders.
gulp.task('sass', function(){
return gulp.src('compile/style.scss')
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sass()) // delete this, no need for two sass pipes
.pipe(sass({outputStyle: 'expanded',sourceComments: false}))
.pipe(sourcemaps.write('../../../compile'))
.pipe(gulp.dest('public/assets/css'));
});
My file structure is:
sass
-main.sass
-variables.sass
-containers.sass
-buttons.sass
-helpers.sass
css
-main.css
In my main.sass file, I'm importing all the other sass files:
#import "variables";
#import "containers";
#import "buttons";
//etc...
In gulp I want to watch any changed scss file and compile only main.sass into main.css.
This is what I have:
var gulp = require('gulp');
var sass = require('gulp-sass');
function styles() {
return gulp.src('sass/main.sass', {
sourcemaps: true
})
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('css/'));
}
function watch() {
gulp.watch('sass/**/*.sass', styles);
}
var build = gulp.parallel(styles, watch);
gulp.task(build);
gulp.task('default', build);
The files are being watched but when I update one, the main.css file is not updated.
I believe one of your problems could be that you define a watching task via gulp.watch(...) but its reference is lost and so it never gets called. However, I don't really understand what you try to achieve with the call to parallel(). I'm currently working on a similar use case with a build script like the following:
var gulp = require('gulp');
function styles() {
return gulp.src('...')
.pipe(...)
.pipe(gulp.dest('...'));
}
exports.build = gulp.watch('...', styles);
This should be a minimal working example, just call gulp build.
Having used Gulp all the time for 2 last years, I've suddenly got a problem with the less file imports and just can not resolve it.
I've tried more then 5 combinations, such as from SmashingMagazine, from gulp-less homepage, etc... none worked for me.
The problem is (error log in console output):
C:\wamp\www\lumenframe>gulp less
[10:23:25] Using gulpfile C:\wamp\www\lumenframe\Gulpfile.js
[10:23:25] Starting 'less'...
Potentially unhandled rejection [2] '/bower_components/animate.css/animate.css' wasn't found. Tried - /bower_components/animate.css/animate.c
ss,bower_components\bootstrap\less\bower_components\animate.css\animate.css,bower_components\animate.css\bower_components\animate.css\animate
.css,bower_components\font-awesome\less\bower_components\animate.css\animate.css in file C:\wamp\www\lumenframe\bower_components\assets\l
ess\appstrap.less line no. 43
Gulpfile.js looks like this:
// Init Gulp
var gulp = require('gulp');
// Dependencies
var less = require('gulp-less'),
concat = require('gulp-concat'),
rename = require('gulp-rename'),
uglify = require('gulp-uglify'),
autoprefixer = require('gulp-uglify');
// Folder paths
var jsdir = './bower_components/assets/js/',
jspub = './public/assets/js/',
lessdir = './bower_components/assets/less/',
lesspub = './public/assets/css/';
// LESS compiler
gulp.task('less', function () {
return gulp.src(lessdir + 'frontend.less')
.pipe(less({
compress: true,
paths: [
'./bower_components/bootstrap/less/',
'./bower_components/animate.css/',
'./bower_components/font-awesome/less/'
]
}))
.pipe(autoprefixer('last 10 versions', 'ie 9'))
.pipe(gulp.dest(lesspub));
});
// Concatenate and Minify JS
gulp.task('scripts', function () {
return gulp.src(jsdir + '*.js')
.pipe(concat('appstrap.js'))
.pipe(gulp.dest(jspub))
.pipe(rename('appstrap.min.js'))
.pipe(uglify())
.pipe(gulp.dest(jspub));
});
// Filewatcher for changes
gulp.task('watch', function () {
gulp.watch(jsdir + '*.js', ['scripts']);
gulp.watch(lessdir + '*.less', ['less']);
});
// Default Task combination
gulp.task('default', ['less', 'scripts', 'watch']);
All files are in their proper place, so they exists. And once I do #import appstrap.less, it comes out with the error **Potentially unhandled rejection [2].
frontend.less looks like this:
// Core source files of the whole frontend plugins
#import (once) "appstrap.less";
.btn{
color: #ff0000;
display: block;
}
Any visible errors ?