In my gulp file to inject bower components I have this bad style code duplication. But I do not have any ideas how to get rid of it.
Generally speaking we cannot say just bower_components/**/*.js because we don't want to import all files, plus for production we want to import just .min files. Again. I cannot guaranty that every package I use have .js and .min.js files. So just *.js and *.min.js may not work.
gulp.task('inject', () => {
let sources = gulp.src([
// jquery
'public/bower_components/jquery/dist/jquery.js',
// bootstrap
'public/bower_components/bootstrap/dist/js/bootstrap.js',
'public/bower_components/bootstrap/dist/css/bootstrap.css',
// angular
'public/bower_components/angular/angular.js',
'public/bower_components/angular/angular-csp.css',
// angular route
'public/bower_components/angular-route/angular-route.js',
],{read: false});
let min_sources = gulp.src([
// jquery
'public/bower_components/jquery/dist/jquery.min.js',
// bootstrap
'public/bower_components/bootstrap/dist/js/bootstrap.min.js',
'public/bower_components/bootstrap/dist/css/bootstrap.min.css',
// angular
'public/bower_components/angular/angular.min.js',
'public/bower_components/angular/angular-csp.css',
// angular route
'public/bower_components/angular-route/angular-route.min.js',
],{read: false});
return gulp.src('public/build/index.html')
.pipe(gulpif(!argv.production, inject(sources, {relative: true})))
.pipe(gulpif(argv.production, inject(min_sources, {relative: true})))
.pipe(gulp.dest('public/build/'));
});
But this code duplication isn't solution. I think. How can I improve this part, besides to move this two array in bower.js file ?
Maybe you can use config.js. Use var config = require('../config'); to read the variables in config.js so you can separate file paths and task.
If you want to separate .js and .min.js , you can use
'src' : [
'src/**/*.js',
'!src/**/*.min.js',
]
For example below I concat .min.js / .js files and uglify it, and also concate .css files and use cssnano() to compress it. In the end vendor task will output vendor.bundle.js and vendor.bundle.css
config.js:
'use strict';
module.exports = {
'vendor': {
'scripts': {
'src': [
'bower_components/jquery/dist/jquery.min.js',
'bower_components/lodash/dist/lodash.min.js',
// Moment
'bower_components/moment/min/moment.min.js',
'bower_components/moment/locale/zh-tw.js',
// Ionic & Angular
'bower_components/ionic/js/ionic.bundle.min.js',
'bower_components/ngCordova/dist/ng-cordova.min.js'
// ...
],
'dest': 'www/js',
'output': 'vendor.bundle.js'
},
'styles': {
'src': [
// Mobiscroll
'bower_external/mobiscroll/css/mobiscroll.custom-2.17.0.min.css',
],
'dest': 'www/css',
'output': 'vendor.bundle.css'
}
}
}
}
vendor.js
'use strict';
var config = require('../config');
var gulp = require('gulp');
var gulpif = require('gulp-if');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var postcss = require('gulp-postcss');
var cssnano = require('cssnano');
var handleErrors = require('../util/handleErrors');
var browserSync = require('browser-sync');
var pkg = require('../../package.json');
gulp.task('vendorScripts', function () {
return gulp.src(config.vendor.scripts.src)
.pipe(concat(config.vendor.scripts.output))
.pipe(uglify())
.pipe(gulp.dest(config.vendor.scripts.dest));
});
gulp.task('vendorStyles', function () {
return gulp.src(config.vendor.styles.src)
.pipe(concat(config.vendor.styles.output))
.pipe(postcss([ cssnano() ]))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(config.vendor.styles.dest));
});
gulp.task('vendor', ['vendorScripts', 'vendorStyles']);
Related
Below is a copy of my gulpfile.js. For some reason /util.js, /alert.js & push.js are not being compiled into my scripts.js file when I run "gulp scripts" from the terminal in VSCode. I would appreciate an advice to help me sort out this problem. I'm new to gulpfile format, so I wouldn't be surprised if I've
made a mistake somewhere
const gulp = require('gulp');
const sass = require('gulp-sass');
const browserSync = require('browser-sync').create();
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const uglify = require('gulp-uglify');
function scripts() {
return gulp.src(
'node_modules/jquery/dist/jquery.js',
'node_modules/bootstrap/js/dist/util.js',
'node_modules/bootstrap/js/dist/alert.js',
'node_modules/var/push.js',
'js/main.js',
'js/other.js'
)
.pipe(concat('scripts.js'))
.pipe(gulp.dest('js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('./js'));
}
// compile scss into css
function style() {
// 1 where is scss file
return gulp.src('scss/**/*.scss')
// 2 pass that file through sass compiler
.pipe(sass().on('error', sass.logError))
// 3 where do iI have the compiled css?
.pipe(gulp.dest('./css'))
// 4 stream changes to all browsers
.pipe(browserSync.stream());
}
function watch() {
browserSync.init({
server: {
baseDir: './'
}
});
gulp.watch('scss/**/*.scss', style);
gulp.watch('*.html').on('change', browserSync.reload);
gulp.watch('js/**/*.js').on('change', browserSync.reload);
}
exports.style = style;
exports.watch = watch;
exports.scripts = scripts;
When passing several globs or paths to gulp.src, you should wrap them in an array:
return gulp.src([
'node_modules/jquery/dist/jquery.js',
'node_modules/bootstrap/js/dist/util.js',
'node_modules/bootstrap/js/dist/alert.js',
'node_modules/var/push.js',
'js/main.js',
'js/other.js'
])
I have the following two tasks:
gulp.task('compress', () => {
return gulp.src('app/static/angular/**/*.js')
.pipe(concat('build.js'))
.pipe(gulp.dest('./app/static'));
});
gulp.task('templates', () => {
return gulp.src('app/static/angular/**/*.html')
.pipe(htmlmin())
.pipe(angularTemplateCache('templates.js', {
module: 'myApp',
root: '/static/angular'
}))
.pipe(gulp.dest('./app/static'))
});
And it works fine, but I want them both concatenated into build.js -- how can I combine these two?
In the end I used merge-stream to merge the two streams into one output file:
var gulp = require('gulp');
var concat = require('gulp-concat');
var htmlmin = require('gulp-htmlmin');
var angularTemplateCache = require('gulp-angular-templatecache');
var merge = require('merge-stream');
gulp.task('build', () => {
var code = gulp.src('app/static/angular/**/*.js');
var templates = gulp.src('app/static/angular/**/*.html')
.pipe(htmlmin())
.pipe(angularTemplateCache({
module: 'myApp',
root: '/static/angular'
}));
return merge(code, templates)
.pipe(concat('build.js'))
.pipe(gulp.dest('./app/static'));
});
gulp.task('default', ['build']);
I assume the above task mentioned is in separate file say compress.js inside tasks folder
In gulpfile.js you can use below code :
//Include require-dir to include files available in tasks directory
var requireDir = require('require-dir');
// And Take the tasks directory
requireDir('./tasks');
Then you can create a build task as below in gulpfile.js:
gulp.task('build', ['compress', 'templates']);
I am trying to set the Gulp tasks for styles with postcss, CSS modules etc., but for now only the watch task for the main HTML file is working, and it is not even creating the main CSS file nor the temp folder so I get the error in the console that it can not find the styles.css. It's driving me crazy for days but just cannot get to the bottom of it. Here is my file structure, pretty basic:
application -> views -> index.html
public -> gulp -> tasks -> styles.js, watch.js
-> styles (styles.css inside, base and modules for CSS subfolders)
And here are the styles and watch tasks:
var gulp = require('gulp'),
watch = require('gulp-watch'),
browserSync = require('browser-sync').create();
gulp.task('watch', function() {
browserSync.init({
notify: false,
server: {
baseDir: "../application/views"
}
});
watch('../application/views/index.html', function(){
browserSync.reload();
});
watch('../application/public/styles/**/*.css', function(){
gulp.start('cssInject');
});
});
gulp.task('cssInject', ['styles'], function(){
return gulp.src('../application/temp/styles')
.pipe(browserSync.stream());
});
Styles:
var gulp = require('gulp'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer'),
cssvars = require('postcss-simple-vars'),
nested = require('postcss-nested'),
cssImport = require('postcss-import'),
mixins = require('postcss-mixins'),
hexrgba = require('postcss-hexrgba');
gulp.task('styles', function(){
return gulp.src('../application/public/styles/styles.css')
.pipe(postcss([cssImport, mixins, cssvars, nested, hexrgba, autoprefixer]))
.on('error', function(errorInfo){
console.log(errorInfo.toString());
this.emit('end');
})
.pipe(gulp.dest('../application/temp/styles'));
});
If someone can give a piece of advice I would be really grateful.
That's a weird thing for me, i have a task to concat my .js files and then uglify them with a watcher, but the concat task just twice the content in every call...
Here is my gulpfile:
'use strict';
let gulp = require('gulp');
let stylus = require('gulp-stylus');
let sourcemaps = require('gulp-sourcemaps');
let concat = require('gulp-concat');
let uglify = require('gulp-uglify');
let plumber = require('gulp-plumber');
let bootstrap = require('bootstrap-styl');
let rupture = require('rupture');
let copy = require('gulp-copy2');
/*
Prepare the paths
*/
let base = './theme';
let themeName = 'own-theme';
let paths = {
stylus : `${base}/${themeName}/css`,
js : `${base}/${themeName}/js`,
vendor : `${base}/${themeName}/js/vendor`
}
/*
Stylus compile
*/
gulp.task('stylus-compile', () => {
return gulp.src([`${paths.stylus}/dev/*.styl`, `${paths.stylus}/!**/_*.styl`])
.pipe(plumber())
.pipe(stylus({
use: [bootstrap(), rupture()],
compress: true
}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(`${paths.stylus}`));
});
/*
Get the bootstrap-styl js files and concat/uglify them
*/
gulp.task('bootstrap-build', () => {
return gulp.src([
'node_modules/bootstrap-styl/js/transition.js',
'node_modules/bootstrap-styl/js/alert.js',
'node_modules/bootstrap-styl/js/button.js',
'node_modules/bootstrap-styl/js/carousel.js',
'node_modules/bootstrap-styl/js/collapse.js',
'node_modules/bootstrap-styl/js/dropdown.js',
'node_modules/bootstrap-styl/js/modal.js',
'node_modules/bootstrap-styl/js/tooltip.js',
'node_modules/bootstrap-styl/js/popover.js',
'node_modules/bootstrap-styl/js/scrollspy.js',
'node_modules/bootstrap-styl/js/tab.js',
'node_modules/bootstrap-styl/js/affix.js'
])
.pipe(sourcemaps.init())
.pipe(concat('bootstrap.min.js'))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(`${paths.vendor}`));
});
/*
Get the js assets from NPM
*/
gulp.task('js-copy', () => {
let dirs = [
{ src: 'node_modules/jquery/dist/jquery.min.js', dest: `${paths.vendor}/jquery.min.js` },
{ src: 'node_modules/sweet-scroll/sweet-scroll.min.js', dest: `${paths.vendor}/sweet-scroll.min.js` }
]
return copy(dirs);
});
/*
Concat/Uglify the JS files
*/
gulp.task('js-build', () => {
return gulp.src(`${paths.js}/*.js`)
.pipe(sourcemaps.init())
.pipe(concat('site.min.js'))
// .pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(`${paths.js}`));
})
/*
Watch
*/
gulp.task('watch', () => {
gulp.watch(`${paths.js}/*.js`, ['js-build']);
gulp.watch(`${paths.stylus}/dev/*.styl`, ['stylus-compile']);
});
gulp.task('default', ['bootstrap-build', 'js-copy', 'watch']);
The bootstrap-build task don't twice the content no matter how many times you call the task, but the js-build does.
Here are the test separated scripts to concat and the results:
File 1:
(function() {
console.log("oh!")
console.log("uh!")
}).call(this);
File 2:
(function() {
console.log("hey")
}).call(this);
Concated file(uh, oh file re-saved after the watcher was fired):
(function() {
console.log("oh!")
console.log("uh!")
}).call(this);
(function() {
console.log("oh!")
console.log("uh!")
}).call(this);
(function() {
console.log("hey")
}).call(this);
//# sourceMappingURL=site.min.js.map
(function() {
console.log("hey")
}).call(this);
//# sourceMappingURL=site.min.js.map
In every re-save, the concat twice the content... i really don't get the problem. Any idea?
Thanks in adnvance.
The reason your bootstrap-build works is because it places the resulting bootstrap.min.js in a different folder than the source files.
Your js-build task however concatenates all .js files in your path.js folder and places the resulting site.min.js in that same folder.
That means when first running js-build the files file1.js and file2.js are concatenated into site.min.js. On a second run the files file1.js, file2.js and site.min.js are concatenated into site.min.js. Every time you run your js-build task your site.min.js grows.
What you need to do is exclude site.min.js from being concatenated with the other files:
gulp.task('js-build', () => {
return gulp.src([
`${paths.js}/*.js`,
`!${paths.js}/site.min.js`
])
.pipe(sourcemaps.init())
.pipe(concat('site.min.js'))
// .pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(`${paths.js}`));
})
My browserify workflow (from coffee to js, with browserify-shim and coffeeify) is like this:
I have 2 main files, app.coffee and _app.coffee, respectively for frontend and backend. Both files located in resources/coffee/front and resources/coffee/back (respectively). I'm trying to include browserify task in laravel elixir so the result file will be on public/js/app.js and public/js/_app.js and can be revision to the build folder later.
So far, I have tried to extend the elixir by creating a browserify.js file in elixir's node_modules ingredients folder. The content is:
var gulp = require('gulp');
var browserify = require('browserify');
var watchify = require('watchify');
var source = require('vinyl-source-stream');
var logger = require('../../../gulp/util/bundleLogger');
var errors = require('../../../gulp/util/handleErrors');
var config = require('../../../gulp/config').browserify;
elixir.extend('browserify', function(callback) {
var bundleQueue = config.bundleConfigs.length;
var browserifyThis = function(bundleConfig) {
var bundler = browserify({
cache: {},
packageCache: {},
fullPaths: true,
entries: bundleConfig.entries,
extensions: config.extensions,
debug: config.debug
});
var bundle = function() {
logger.start(bundleConfig.outputName);
return bundler
.bundle()
.on('error', errors)
.pipe(source(bundleConfig.outputName))
.pipe(gulp.dest(bundleConfig.dest))
.on('end', finished);
}
if (global.isWatching) {
bundler = watchify(bundler);
bundler.on('update', bundle);
}
var finished = function() {
logger.end(bundleConfig.outputName);
if (bundleQueue) {
bundleQueue--;
if (bundleQueue === 0) {
callback();
}
}
}
return bundle();
};
config.bundleConfigs.forEach(browserifyThis);
});
Config for browserify is:
browserify: {
debug: true,
extensions: ['.coffee'],
watch: './resources/assets/coffee/{front,back}/**/*.coffee',
bundleConfigs: [
{
entries: './resources/assets/coffee/front/app.coffee',
dest: './public/js',
outputName: 'app.js'
},
{
entries: './resources/assets/coffee/back/app.coffee',
dest: './public/js',
outputName: '_app.js'
}]
}
Then in my gulp elixir task, I do this:
var gulp = require('gulp');
var elixir = require('laravel-elixir');
gulp.task('elixir', function() {
return elixir(function(mix) {
mix.sass('app.scss').browserify().version(['.public/css/app.css', './public/js/app.js', '.public/js/_app.js']);
});
});
This does not work because the callback function is not included in elixir (originally it is gulp's). Even if it is, the elixir watch will not listen to my original .coffee files (I'm trying to watch the entire coffee file located in resources/coffee/**/*.coffee).
So what I have thought as a solution is to re-run the entire elixir procedure if the file changed, like:
gulp.task('default', function() {
runSequence('coffeelint', 'browserify', 'elixir', 'images', 'watch');
});
and my watch task:
gulp.task('watch', function() {
gulp.watch(config.browserify.watch, ['coffeelint', 'default']);
gulp.watch(config.images.src, ['images']);
});
But the error is that, it says that sass() function in elixir cannot be linked to browserify(). Any idea how to do this?
Laravel elixir comes bundle with browserify so no need to do a require of browserify what you can do is
elixir(function(mix) {
mix.browserify(['main.js'],
'output directory',
'base-directory-if-different-from-public-folder');
});
You can't combine them, but you can run both.
//gulp.js in the root folder
var elixir = require('laravel-elixir');
var browserify = require('browserify');
elixir(function(mix) {
mix.sass(['app.scss'], 'public/css');
});
elixir(function(mix) {
mix.browserify(['app.js'], 'public/js');
});