Had to rewrite my gulpfile to gulp 4 but I'm facing problems of gulp-inject injecting nothing.
var gulp = require('gulp');
var svgstore = require('gulp-svgstore');
var svgmin = require('gulp-svgmin');
var rename = require('gulp-rename');
var cheerio = require('gulp-cheerio');
var inject = require('gulp-inject');
var path = require('path');
gulp.task('svgstore', function () {
var svgs = gulp
.src('static/svg/icons/src/*.svg')
.pipe(svgmin(function (file) {
var prefix = path.basename(file.relative, path.extname(file.relative));
return {
plugins: [{
convertPathData: false
}, {
cleanupIDs: {
prefix: prefix + '-',
minify: true
}
}]
}
}))
.pipe(cheerio(function ($, file) {
$('[fill]').attr('fill', 'currentColor');
}))
.pipe(svgstore({ inlineSvg: true }))
.pipe(gulp.dest('dest'));
function fileContents(filePath, file) {
return file.contents.toString();
}
return gulp
.src('layouts/partials/src/inline-svg.html')
.pipe(inject(svgs, { transform: fileContents }))
.pipe(gulp.dest('layouts/partials'));
});
// Watch asset folder for changes
gulp.task("watch", function () {
var watcher = gulp.watch("static/svg/icons/src/**/*")
watcher.on('all', gulp.series('svgstore'))
})
// Set watch as default task
gulp.task("default", gulp.series("watch"))
I can't figure out why. I tried logging fileContents and it just says [Function: fileContents].
I faced the same issue. When I debugged the gulp-inject package, I figured out that the gulp-inject plugin look up for the startTag and the endTag in the source file/s (in your case, the source file/s is gulp.src('layouts/partials/src/inline-svg.html')) to inject the content, and when I printed out the tags to the console, the result is:
startTag: /<!\-\-\s*inject\b:svg\b\s*\-\->/gi
endTag: /<!\-\-\s*endinject\s*\-\->/gi
Conclusion:
In the src file(i.e., inline-svg.html), insert the comments like below:
<div class="sr-only">
<!-- inject:svg --><!-- endinject -->
</div>
Then, try to run the gulp task and it should work.
Reference: https://github.com/w0rm/gulp-svgstore#inlining-svgstore-result-into-html-body
Gulp Version Used: ^5.0.4
Related
I have the start and deploy tasks working the way I want them to but I am trying to figure out how to update public/js/bundle.js when I make a change in app.js so that it can be watched.
Here's what I got so far:
var gulp = require('gulp');
var streamify = require('gulp-streamify');
var uglify = require('gulp-uglify');
var transform = require('vinyl-source-stream');
var browserify = require('browserify');
var rename = require('gulp-rename');
var nodemon = require('gulp-nodemon');
var ios = browserify({
entries:['app.js']
});
const bundle = () => {
process.env.NODE_ENV = 'production';
ios.require('./app-ios.js', {expose:'appalias'})
.bundle()
.pipe(transform('bundle-ios.js'))
.pipe(gulp.dest('./public/js'))
.pipe(streamify(uglify()))
.pipe(rename('bundle-ios.min.js'))
.pipe(gulp.dest('./public/js'));
return ios;
}
const start = () => {
return nodemon({
script: 'server.js',
watch: ['server.js', 'public/js/*', 'public/index.html', 'public/css/*'],
ext: 'js html css',
env: { 'NODE_ENV': 'development' },
});
}
// Start local server and watch bundles.
gulp.task('start', start);
// Build minified versions for prod.
gulp.task('deploy', bundle);
The fix was to watch all the individual javascript component and model files and add a compile task to the start task.
// Bundle and minify for development, use development version of libraries.
const compile = () => {
process.env.NODE_ENV = 'development';
const bundleAndroidDev = ios.require('./app-ios.js', {expose:'appalias'})
.bundle()
.pipe(transform('bundle-ios.js'))
.pipe(gulp.dest('./public/js'));
return bundleIosDev;
}
// Start local server and watch for changes in compiled bundles.
const start = () => {
return nodemon({
script: 'server.js',
watch: ['server.js', 'apps/appName/components/*', 'apps/appName/models/*', 'public/index.html', 'public/css/*'],
ext: 'js html css',
tasks: ['compile'],
env: { 'NODE_ENV': 'development' }
});
}
// Compile bundle's on save.
gulp.task('compile', compile);
I'm simply trying to compile hbs templates via Browserify and Gulp, but the compilation process fails as soon as any HTML markup is encountered from my hbs file.
I've confirmed this by removing the HTML code within the hbs file, at which point Browserify runs as expected.
Here is a simplified version of my Gulp task:
const _gulp = require('gulp');
const _browserify = require('browserify');
const _remapify = require('remapify');
const _hbsfy = require('hbsfy');
const _vinylSourceStream = require('vinyl-source-stream');
const _vinylBuffer = require('vinyl-buffer');
_gulp.task('js:dev', () => {
return _browserify({entries: './src/js/app.js', debug: true})
.plugin(_remapify, [
{
src: '**/*.hbs', // glob for the files to remap
cwd: './src/markup/components',
expose: 'components' // this will expose './src/markup/components' as 'components'
}
])
.transform(_hbsfy)
.bundle()
.pipe(_vinylSourceStream('app.js'))
.pipe(_vinylBuffer())
.pipe(_gulp.dest('dist'))
});
The hbs template:
<div class="menu"> </div>
The main JS file:
(function (){
const _handlebars = require('hbsfy/runtime');
function init () {
_handlebars.registerPartial('menu', require('components/menu.hbs'));
}
document.addEventListener('DOMContentLoaded', init);
})();
What could be going wrong? It's as if the hbsfy transform isn't running properly...
It seems this issue is actually caused by the remapify plugin. Compilation works as expected using pathmodify instead.
Here is my updated Gulp file:
const _gulp = require('gulp');
const _browserify = require('browserify');
const _pathmodify = require('pathmodify');
const _hbsfy = require('hbsfy');
const _vinylSourceStream = require('vinyl-source-stream');
const _vinylBuffer = require('vinyl-buffer');
_gulp.task('js:dev', () => {
return _browserify({entries: './src/js/app.js', debug: true})
.plugin(_pathmodify, {
mods: [
_pathmodify.mod.dir('components', process.cwd() + '/src/markup/partials/components')
]
})
.transform(_hbsfy)
.bundle()
.pipe(_vinylSourceStream('app.js'))
.pipe(_vinylBuffer())
.pipe(_gulp.dest('dist'))
});
I have a project in which there are about 30 css themes. It means I have the next css files structure:
src/
themes/
default/
a.scss
b.scss
rockStar/
a.scss
b.scss
oneMoreTheme/
a.scss
b.scss
dist/
themes/
default/
styles.css
rockStar/
styles.css
oneMoreTheme/
styles.css
Here is just example of gulpfile:
var gulp = require('gulp'),
glob = require('glob'),
path = require('path'),
_ = require('underscore'),
$ = require('gulp-load-plugins')(),
options = {};
options.themes = [
'default',
'rockStar',
'oneMoreTheme'
];
gulp.task('styles', function () {
_.each(options.themes, function(themeName, themeKey) {
gulp.src('src/themes/' + themeName + '/**/*.scss')
.pipe($.concat('styles.scss'))
.pipe($.sass())
.pipe(gulp.dest('dist/themes/' + themeName + '/'));
});
});
gulp.task('watch', function () {
gulp.watch('src/**/*.*', ['styles']);
});
In my gulp file I have a task "styles", which compiles scss files from each theme and puts compiled files to dist folder.
And I have task "watch" which run "styles" task when any scss file form any source theme changes. It works, but it takes much time because of lots of themes!
How can my task "watch" detect from which theme files changes and run task "styles" only for this changed theme?
That is indeed a tough one, but here is a solution. Please refer to the comments in the code for an explanation.
version 1
var gulp = require('gulp');
var merge = require('merge2');
var $ = require('gulp-load-plugins')();
var path = require('path');
var options = {};
options.themes = [
'default',
'rockStar',
'oneMoreTheme'
];
// we extract the task itself to a new function
// this allows us to reuse it
var styleTask = function(themeName) {
return gulp.src('src/themes/' + themeName + '/**/*.scss')
.pipe($.concat('styles.scss'))
.pipe($.sass())
.pipe(gulp.dest('dist/themes/' + themeName + '/'));
}
// we adapt the style task to use that function
// please note that I switched _.each for merge
// this allows you to work with streams!
gulp.task('styles', function() {
var tasks = themes.map(styleTask);
return merge(tasks);
});
// here we set up a new watcher. Instead of running 'styles'
// we filter the theme directory from the file that has changed
// and run the styleTask function
gulp.task('default', function() {
var watcher = gulp.watch('src/themes/**/*.scss', function(e) {
var theme = path
.relative(__dirname, e.path)
.substr('src/themes/'.length)
.split('/')[0];
console.log('rebuilding ' + theme);
return styleTask('theme');
});
});
version 2
// same as above except the default task. we save the theme
// we want to build in a file
var singleTheme;
// and call the styleTask function should it be set
gulp.task('single-style', function(done) {
if(singleTheme) {
return styleTask(singleTheme);
} else {
done();
}
});
// here we have a watcher that calls single-style, but before calling
// it gets the right themename.
gulp.task('default', function() {
var watcher = gulp.watch('src/themes/**/*.scss', 'single-style');
watcher.on('change', function(e) {
singleTheme = path
.relative(__dirname, e.path)
.substr('src/themes/'.length)
.split('/')[0];
console.log('rebuilding ' + theme);
})
})
I hope this helped.
Update If you want to run more tasks and have a status call on if they ended, please go for version 2. Than you can add all the tasks you want to run in
gulp.task('default', function() {
var watcher = gulp.watch('src/themes/**/*.scss', ['single-style', 'another-task']);
watcher.on('change', function(e) {
singleTheme = path
.relative(__dirname, e.path)
.substr('src/themes/'.length)
.split('/')[0];
console.log('rebuilding ' + theme);
})
})
Instead of gulp.run you can use gulp.start.
I am trying to work to replicate a problem I am having adding React to an existing application. Unfortunately, at the moment I am running into a completely different problem simply trying to reproduce the original problem.
The basic structure is a new base module compiled by browserify that is then concatenated with the existing module which bootsraps the application for now.
var gulp = require('gulp');
var browserify = require('browserify');
var reactify = require('reactify');
var source = require('vinyl-source-stream');
var concat = require('gulp-concat');
gulp.task('default', ['browserify', 'concat']);
gulp.task('browserify', function(){
return browserify({
entries: ['./src/app.js'],
transform: [["reactify", {"es6": true}]],
extensions: ['.jsx'],
debug: true,
standalone: 'App'
}).bundle()
.pipe(source('browserifyPackage.js'))
.pipe(gulp.dest('./oldSrc'));
})
gulp.task('concat', ['browserify'], function(){
return gulp.src(['./oldSrc/browserifyPackage.js', './oldSrc/app.js'])
.pipe(concat('app.js'))
.pipe(gulp.dest('./'));
})
the new module is pretty simple
window.React = require('react');
module.exports = {
TodoSection: require('./todoSection')
}
And then the old app looks like this
_.extend(App, (function(){
return { init: function(){
React.render(new App.TodoSection(), document.getElementById('body'));
}}
}))
window.addEventListener('load', function() { App.init(); }, false).
When I try to use this file though I get an "Unexpected end of line" from within prelude.js in browserify. I don't see an obvious problem, but I am obviously missing something.
The complete example project can be found on Github
The issue is probably the period at the end of this line:
window.addEventListener('load', function() { App.init(); }, false).
I have the follwing gulp task to compile my client code:
var browserify = require('browserify');
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var reactify = require('reactify');
gulp.task('compile', function() {
return browserify('./public/js/app.js', {transform: reactify, debug: true})
.bundle()
.pipe(source('app.js'))
.pipe(gulp.dest('./public/dist'));
});
The problem is that only the root ./public/js/app.js file is shown up in the source tab in chrome. All files that are required in app.js are missing.
After decompiling the source map data, it seems that only ./public/js/app.js is listed with the relative url, all other files have the absolute url on my machine.
{
"version": 3,
"sources": [
"/Users/andreaskoberle/projects/private/webshell/node_modules/browserify/node_modules/browser-pack/_prelude.js",
"./public/js/app.js",
"/Users/andreaskoberle/projects/private/webshell/public/js/cockpits/index.js",
"/Users/andreaskoberle/projects/private/webshell/public/js/cockpits/links.js",
"/Users/andreaskoberle/projects/private/webshell/public/js/common/Box.js",
"/Users/andreaskoberle/projects/private/webshell/public/js/common/Grid.js",
"/Users/andreaskoberle/projects/private/webshell/public/js/sidebar.js",
"/Users/andreaskoberle/projects/private/webshell/public/js/webShell/ScriptSelector.js",
"/Users/andreaskoberle/projects/private/webshell/public/js/webShell/ShellOutput.js",
"/Users/andreaskoberle/projects/private/webshell/public/js/webShell/index.js"
],
The problem are the absolute paths in the source map. Using mold-source-map in my gulp task to convert to the absolute paths to relative ones, fix the issue:
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var reactify = require('reactify');
var mold = require('mold-source-map')
gulp.task('compile', function() {
return browserify('./public/js/app.js', {transform: reactify, debug: true})
.bundle()
.pipe(mold.transformSourcesRelativeTo('./'))
.pipe(source('app.js'))
.pipe(gulp.dest('./public/dist'));
});
I have a similar problem except in my case the sourcemap does not even contain absolute paths; it has only one entry for the root file.
My sources from the .map:
"sources":["theSrc/internal_www/js/renderContentPage.js"]
And my gulp task:
gulp.task('compileRenderContentPage', function () {
var b = browserify({
entries: 'theSrc/internal_www/js/renderContentPage.js',
debug: true
});
return b.transform(babelify, { presets: ['es2015'] })
.bundle()
.pipe(source('renderContentPage.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.on('error', gutil.log)
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./browser/js/'));
});
haven't figures out the issue yet