Parsing Stylus with gulp-usemin - gulp

I'm migrating some code from Less to Stylus. In my code below, gulp-usemin compiles the Less files correctly, but I don't have it working with the Stylus files.
Source Files
gulpfile.js
var gulp = require('gulp'),
less = require('gulp-less'),
stylus = require('gulp-stylus'),
nib = require('nib'),
usemin = require('gulp-usemin');
gulp.task('usemin', function() {
return gulp.src('src/index.html')
.pipe(usemin({
less: [less()],
stylus: [stylus({use: nib(), compress: false})]
}))
.pipe(gulp.dest('dist/'));
});
index.html
<!-- build:less css/less.css -->
<link rel="stylesheet" type="text/css" href="foo.less">
<link rel="stylesheet" type="text/css" href="bar.less">
<!-- endbuild -->
<!-- build:stylus css/stylus.css -->
<link rel="stylesheet" type="text/css" href="foo.styl">
<link rel="stylesheet" type="text/css" href="bar.styl">
<!-- endbuild -->
foo.less
// This comment should disappear
html {
margin: 0;
}
bar.less
body {
background: #eee;
}
foo.styl
// This comment should disappear
html
margin: 0
bar.styl
body
background: #eee
Compiled Files
index.html
<link rel="stylesheet" href="css/less.css"/>
<link rel="stylesheet" href="css/stylus.css"/>
less.css
html {
margin: 0;
}
body {
background: #eee;
}
stylus.css
// This comment should disappear
html
margin: 0
body
background: #eee
As you can see, the Stylus files are concatenated, but not parsed at all. Am I using gulp-usemin correctly? Should I be using a different plugin?

There has not been much activity on this post, so I'll go ahead and answer myself.
Rather than continue down this path, I discovered the wonderful world of gulp-inject. The Stylus files are now compiling properly with the following code, but the great side effect is how everything gets injected cleanly into the html.
Source Files
index.html
<!DOCTYPE html>
<html>
<head>
<title>My index</title>
<!-- components:css -->
<!-- bower installed css files will go here... -->
<!-- endinject -->
<!-- app:css -->
<!-- built css files will go here... -->
<!-- endinject -->
</head>
<body>
<!-- components:js -->
<!-- bower installed scripts will go here... -->
<!-- endinject -->
<!-- app:js -->
<!-- app scripts will go here... -->
<!-- endinject -->
</body>
</html>
gulpfile.js
var gulp = require('gulp'),
inject = require('gulp-inject'),
bower = require('main-bower-files'),
filter = require('gulp-filter'),
es = require('event-stream'),
stylus = require('gulp-stylus'),
concat = require('gulp-concat'),
cssFilter = filter('**/*.css'),
compileBower = function () {
return gulp.src(bower())
.pipe(cssFilter)
.pipe(gulp.dest('./app/components/css'))
.pipe(cssFilter.restore());
},
compileStylus = function () {
return gulp.src('./src/css/app.styl')
.pipe(stylus())
.pipe(concat('app.css'))
.pipe(gulp.dest('./app'));
},
compileJS = function () {
return gulp.src('./src/app/**/*.js')
.pipe(gulp.dest('./app'));
},
injectIndex = function () {
return gulp.src('./src/index.html')
.pipe(inject(compileBower(), {name: 'components'}))
.pipe(inject(es.merge(compileStylus(), compileJS()), {name: 'app'}))
.pipe(gulp.dest('./app'));
};
gulp.task('build', injectIndex);
Sample Compiled File
index.html
<!DOCTYPE html>
<html>
<head>
<title>MyApp</title>
<link rel="stylesheet" href="/app/components/css/font-awesome.css"
<link rel="stylesheet" href="/app/components/css/bootstrap.css">
<link rel="stylesheet" href="/app/app.css">
</head>
<body>
<script src="/app/components/js/jquery.js"></script>
<script src="/app/components/js/bootstrap.js"></script>
<script src="/app/module/module.js"></script>
<script src="/app/app.js"></script>
</body>
</html>

Related

Read html files and find js/css and minify that and replace js/css name with old name - Gulp

I have a html file like this:
<html class="h-100">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Login</title>
<!-- main css -->
<link rel="stylesheet" href="../src/vendors/clarity-ui/css/clarity-ui.min.css">
<link rel="stylesheet" href="../src/scss/main.css">
</head>
I want to read html file for do that:
Extract name and path css or js file
Minify css or js
Copy to dist directory
Rename css or js path/name to new location and name
How to do that with Gulp and Gulp plugins?
Look at gulp-useref. It has a good example:
var gulp = require('gulp'),
useref = require('gulp-useref'),
gulpif = require('gulp-if'),
uglify = require('gulp-uglify'),
minifyCss = require('gulp-clean-css');
gulp.task('html', function () {
// I made a small change to gulp.src below
return gulp.src('./app/*.html')
.pipe(useref())
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css', minifyCss()))
.pipe(gulp.dest('dist'));
});
[EDIT : Added your html]
<html class="h-100">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Login</title>
<link rel="stylesheet" href="../src/vendors/clarity-ui/css/clarity-ui.min.css">
<!-- build:css dist/css/main.css -->
<link rel="stylesheet" href="../src/scss/main.css">
<!-- endbuild -->
<!-- build:js ../dist/js/myJS.js -->
<script src="../src/js/myJS.js"></script>
<!-- endbuild -->
</head>
I assume you do not want to change the already minified vendor css. So there is no need to put a directive around it.
And useref will not concatenate the vendor css because it will not grab that asset since their is no build directive around it.
You can do something similar for your js files.
[EDIT : added folder structure.]
-[your working directory]
---[app]
-----test.html
---[src]
------[scss]
--------main.css
------[js]
--------myJS.js
-gulpfile.js
So the gulpfile.js is in your base working directory above the app and src folders.
Running gulp html from your working directory will create a 'dist' folder with your minified css and uglified js in it and your modified main.html.
I have run this on a test system with this folder structure and it works perfectly. Let me know if you still have problems.

What does the second argument of a gulp task mean:

I'm looking for an answer to this, doesn't have to be in depth or great detail. Just want to know exactly what happening with the sequence of the task.
gulp.task('name',['*this right here*'], function() {
// content
});
Does it mean do this task in consecutively namely with this definition task? Why this came up for me is because in my gulpfile.js I'm using gulp-inject for app files and wiredep for vendor dependencies. If this is wrong or either one will do then great, Im under the impression not though. What I have so far is below.
//originally i didn't have bower here in the array in 2nd param.
gulp.task('index', ['bower'], function() {
var target = gulp.src(files.app_files.target);
var sources = gulp.src(files.app_files.sources, {
read: false
});
return target.pipe(inject(sources))
.pipe(gulp.dest('./dist'));
});
gulp.task('bower', function() {
return gulp
.src(files.app_files.target)
.pipe(wiredep())
.pipe(gulp.dest('dist/'));
});
<head>
<meta charset="UTF-8">
<title>Example Page</title>
<!-- Vendor Files -->
<!-- bower:css -->
<!-- endbower -->
<!-- App Files -->
<!-- inject:css -->
<!-- endinject -->
</head>
<body>
<navigation></navigation>
<div ui-view></div>
<footer-area></footer-area>
<!-- Vendor Files -->
<!-- bower:js -->
<!-- endbower -->
<!-- App Files -->
<!-- inject:js -->
<!-- endinject -->
</body>
Update
gulp.task('index', function() {
var target = gulp.src(files.app_files.target);
// It's not necessary to read the files (will speed up things), we're only after their paths:
var sources = gulp.src(files.app_files.sources, {
read: false
});
return target
//here instead of breaking into new task i piped inject and wiredep, works great
.pipe(inject(sources))
.pipe(wiredep())
.pipe(gulp.dest('./dist'));
});
That's an array of tasks to run before your task.
Also, note those tasks (all the ones in the array, in you case there's only bower) run in parallel.
If you need some in sequence. Consider gulp-sequence

Is it possible to ignore some lines in html on building html with Gulp?

I have a html setup in my app folder and this is copied in the dist folder by gulp.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../dist/css/style.css">
</head>
<body ng-app="myApp">
<div ui-view></div>
<!-- build:jsLib js/libs.js -->
<script src="../libs/angular-ui-router/release/angular-ui-router.js"></script>
<!-- endbuild -->
<!-- build:jsApp js/app.js -->
<script src="app.js"></script>
<!-- endbuild -->
<script src="../libs/angular-mocks/angular-mocks.js"></script>
<script type="text/javascript">
angular.module('testApp', ['mockService', 'productServicesApp', 'ngMockE2E']);
</script>
</body>
</html>
That part is used to make fake service calls and I don't want it in deployment files:
//something like *ignore this*
<script type="text/javascript">
angular.module('testApp', ['mockService', 'productServicesApp', 'ngMockE2E']);
</script>
Is is possible to ignore this line with gulp?
Yes this is possible. A nice plugin to do this would be the gulp-remove-code plugin.
Below is an example of how you would use it
HTML:
<div>
<!--removeIf(production)-->
<div class="sandbox-banner">Running in sandbox environment</div>
<!--endRemoveIf(production)-->
<span>Removing code is ready.</span>
</div>
GULP:
var gulp = require('gulp');
var removeCode = require('gulp-remove-code');
HTML_FILES = '/path/to/html/**/*.html';
gulp.task('clean-html', function() {
return gulp.src(HTML_FILES)
.pipe(removeCode({ production: true }))
.pipe(gulp.dest('dist/'));
});
And then you just call it by saying
gulp clean-html
Anything inside of those comment tags will be removed. Also, the object passed to removeCode is not namespace specific. So you can change the naming to whatever.

Gulp-Inject Positions

If I want to inject Js Files in diff. locations e.g. <head> here and here </body>. I need to set names like described here for the injections:
https://github.com/klei/gulp-inject#method-2-use-gulp-injects-name-option
<!-- head:js -->
<!-- only importantFile.js will be injected here -->
<!-- endinject -->
How can I modify this selector, that I don't have to name each file. E.g. take all files which contain *_important.js
.pipe(inject(gulp.src('./src/importantFile.js', {read: false}), {name: 'head'}))
And is there a better way. E.g. like adding s.th. inside the javascript file or name it like this orderModule.above.js, googleAnalytics.below.js
From the gulp documentation:
gulp.src(globs[, options]) - Emits files matching provided glob or an array of globs.
You therefore have tremendous freedom to define how you want to differentiate between "important" files and others.
.pipe(inject(gulp.src('*_important.js')))
.pipe(inject(gulp.src('*.head.js')))
etc. Then just provide the negation of this pattern in the second gulp.src call
.pipe(inject(gulp.src(['*.js', '!*_important.js'])))
.pipe(inject(gulp.src(['*.js', '!*.head.js'])))
gulp.task('dev', function () {
var target = gulp.src('./index.html');
return target
.pipe(inject(gulp.src('_MAIN_CSS_FILES_', {read: false})))
.pipe(inject(gulp.src('_BOWER_CSS_FILES_', {read: false}), {name: 'bower'}))
.pipe(inject(gulp.src('_MAIN_JS_FILES_', {read: false})))
.pipe(inject(gulp.src('_BOWER_JS_FILES_', {read: false}), {name: 'bower'}))
.pipe(gulp.dest("./dest/"));
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
<!-- inject:css -->
<!-- built css files will go here... -->
<!-- endinject -->
<!-- bower:css -->
<!-- bower installed css files will go here... -->
<!-- endinject -->
</head>
<body>
<!-- bower:js -->
<!-- bower installed js files will go here... -->
<!-- endinject -->
<!-- inject:js -->
<!-- built js files will go here... -->
<!-- endinject -->
</body>
</html>

How to copy and inject the main-bower-files in one step using gulp?

When deploying my app I want to copy the bower dependency to the deploy directory and inject the links to these files into the index.html that is also in the deploy directory.
Each step alone works perfectly by I'm not able to combine them.
Copy the files:
return gulp.src(mainBowerFiles(), { read: false })
.pipe(gulp.dest('./deploy/lib/'));
Injecting the files:
return gulp.src('./deploy/index.html')
.pipe(plugins.inject(
gulp.src(mainBowerFiles(), { read: false }), { relative: true }))
.pipe(gulp.dest('./deploy/'));
I think that I should do this in one step to keep the correct order of the dependent files.
I tried this combination but it did not work out.
return gulp.src('./deploy/index.html')
.pipe(plugins.inject(
gulp.src(mainBowerFiles(), { read: false })
.pipe(gulp.dest('./deploy/lib/'), { relative: true })))
.pipe(gulp.dest('./deploy/'));
I recommend wiredep:
You add a block to your html:
<html>
<head>
</head>
<body>
<!-- bower:js -->
<!-- endbower -->
</body>
</html>
and your wiredep task looks like:
// inject bower components
gulp.task('wiredep', function () {
var wiredep = require('wiredep').stream;
gulp.src('app/*.html')
.pipe(wiredep())
.pipe(gulp.dest('app'));
});
Which will add the deps to your html as such:
<html>
<head>
</head>
<body>
<!-- bower:js -->
<script src="bower_components/foo/bar.js"></script>
<!-- endbower -->
</body>
</html>
You can then combine this with useref to order all your project's javascript dependencies
html block
<!-- build:js scripts/app.js -->
<!-- bower:js -->
<script src="bower_components/foo/bar.js"></script>
<!-- endbower -->
<script src="js/yourcustomscript.js"></script>
<!-- endbuild -->
gulp task
gulp.task('html', ['styles'], function () {
var assets = $.useref.assets({searchPath: '{.tmp,app}'});
return gulp.src('app/*.html')
.pipe(assets)
.pipe(assets.restore())
.pipe($.useref())
.pipe(gulp.dest('dist'));
});
Take a look at how generator-gulp-webapp does things: https://github.com/yeoman/generator-gulp-webapp
Note: the $.plugin syntax assumes var $ = require('gulp-load-plugins')();