klei / gulp-inject Goto Github PK
View Code? Open in Web Editor NEWA javascript, stylesheet and webcomponent injection plugin for Gulp
License: MIT License
A javascript, stylesheet and webcomponent injection plugin for Gulp
License: MIT License
I already have my templated file in memory because I've been doing other things with it. In fact, it's a clone of my original src file. Would it be possible to have an option that can operate directly on a buffer (file.contents) or a string (file.contents.toString('utf8'))?
I would otherwise need to save my file in a temporary location in order to get gulp-inject to do its work (something that feels pretty un-gulpy).
Options {relative: true}, {ignorePath: '/folder/'} do NOT work in combination with {name: 'bower'} (or any other name) If no name property is specified, these options work as expected.
Using the project structure described below, gulp-inject
injects absolute paths rather than regular paths. When the gulpfile is in the project root, the relative paths are injected.
Can the file paths be injected relative to the html file that they are being injected into?
Project Directory (only relevant paths)
minesweeper-angular
|
|- index.html
|
|- dev.html
|
|- Resources
| |
| |- scripts
| |
| |- js
|
|- Tasks
|
|- gulpfile.js
gulp-inject task in gulpfile.js
var gulp = require('gulp')
var rename = require('gulp-rename')
var inject = require('gulp-inject')
path.html = {
dev : '../dev.html',
index : '../index.html'
}
gulp.task(
'html',
function() {
return gulp
.src(path.html.index)
.pipe(
inject(
// path.js.compile is an array of file paths
gulp.src(path.js.compile, {read:false})
)
)
.pipe(rename(path.html.dev))
.pipe(gulp.dest('./'))
}
)
gulp-inject delimiters in index.html (source)
<!-- inject:js -->
<!-- endinject -->
dev.html (outcome)
<!-- inject:js -->
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/lib/angular.min.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/lib/jquery.min.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/lib/angular-route.min.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/lib/angular-sanitize.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/lib/angular-cookies.min.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/lib/angularLocalStorage.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/lib/ng-slider.min.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/js/collections/tiles/collection.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/js/models/sliders/model.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/js/models/modals/model.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/js/models/tile/model.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/js/models/tile/modelMethods.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/js/controllers/board.js"></script>
<script src="/Users/walterroman/Sites/minesweeper-angular/Resources/scripts/js/app.js"></script>
<!-- endinject -->
Expectation
For each js file to be injected with relative paths, rather than absolute. In this specific case, without '/Users/walterroman/Sites/minesweeper-angular' prefixed onto the file path.
Using these comments:
<!-- inject:vendors:js -->
<!-- endinject -->
<!-- inject:vendors:css -->
<!-- endinject -->
And these options on gulp-inject
:
{ relative: true,
addRootSlash: false,
starttag: '<!-- inject:vendors:{{ext}} -->'
}
Nothing gets injected in either comment blocks
If I change the comment block to:
<!-- inject:js -->
<!-- endinject -->
<!-- inject:css -->
<!-- endinject -->
The tags are injected, EVEN if I leave the starttag
option to '<!-- inject:vendors:{{ext}} -->'
I also tried using camel-cased option name startTag
to no avail
For clarification, here's how I call the plugin:
return sourceStreams.phoenixIndex()
.pipe(g.inject(sourceStreams.build.vendorsScripts()), options.injections.vendors);
sourceStreams.phoenixIndex()
and sourceStreams.build.vendorsScripts()
: A lazypipe that returns a stream of files (the 1st one being the index.html, the second one being the list of bower-dependencies)
options.injections.vendors
: this object:
{ relative: true,
addRootSlash: false,
starttag: '<!-- inject:vendors:{{ext}} -->'
}
I need to inject my files in a specific order. I was wondering if I could create multiple comment blocks and have different files injected into them. Example: etc
Similar to the inject head example.
I'm using gulp-inject and the first time i fire gulp it doesn't add the injects in the html, only the second time or if watch fires.
This is because I think it takes time to write the files in /dist, which is the folder I use to inject files
.pipe(inject(
gulp.src([dest + 'js/**/*.js', dest + 'css/**/*.css'], {read: false}),
{ignorePath: 'public', addRootSlash: false}
))
This is not a big problem but it is a big problem when using git-rev or other revision modules where you have to inject the last files generated.
Also, is there an options to ignore files with have a .min? Usually in the /css and /js folder i have normal files and .min files
I'd like to have the <!-- inject:js -->
(etc) comments removed from the output file.
Suggested enhancement: use the destination path (automatically detected if possible, or an option otherwise) to generate relative file URLs.
Hello!
I need to inject svg sprite combined with gulp-svgstore into html. It didn't work out of box, so I had to define custom transform function:
transform: function (filePath, file) { return file.contents.toString('utf8') }
Is this a correct way of using gulp-inject? Has it been designed with this usage in mind?
I have a simple app structure:
bower_components/
scripts/
index.html
bower.json
gulpfile.js
I'd have these in index.html:
<!-- bower:css -->
<!-- endinject -->
<!-- bower:js -->
<!-- endinject -->
and my gulpfile.js looks like so:
var gulp = require('gulp'),
bowerFiles = require('main-bower-files'),
inject = require("gulp-inject");
gulp.task('index', function(){
gulp.src('./index.html')
.pipe(inject(gulp.src(bowerFiles(), { read: false }, { name: 'bower' })))
})
When I run $ gulp index
it looks successful but the files don't inject
[gulp] Using gulpfile ~/Projects/ng-morris/gulpfile.js
[gulp] Starting 'index'...
[gulp] Finished 'index' after 21 ms
[11:25:18] gulp-inject 6 files into index.html.
Hi. I'm using this with connect in development. Right now what I'm doing is copying my entire app to ./build. I then run gulp-inject on ./build/index.html and start a connect start server on ./build. The problem I'm getting now is that all the injected scripts are prefixed with /build/. Am I just missing something or just going about it the wrong way or is this something that would be better fixed internally to gulp-inject?
Jade files with remove trailing whitespace enabled will produce invalid html inject comments with your current regex. If for some reason you want to inject files after compiling jade to html, you end up with this:
<!-- inject:js-->
(missing the final space, breaking your regex). So you may want to make this space optional. Got it working by injecting before compiling.
I have the following lines of code:
gulp.src('build/js/**/*.js', {read: false})
.pipe(inject("app/views/includes/foot.handlebars"))
.pipe(gulp.dest('./build/serverViews/includes'));
so the injected files look like this:
<script src="/build/js/app.js"></script>
my problem is that my files are reachable on /js/app.js
and not on /build/js/app.js
is there a way to a achieve this?
I haven't figured out why, but if you attempt to gulp-inject a stream which is wrapped by gulp-watch (not gulp.watch) the stream files disappear after the inject:
var watch = require('gulp-watch'),
inject = require('gulp-inject'),
sass = require('gulp-sass');
css = gulp.src(path.sass)
.pipe(watch(function(files) {
return files
.pipe(sass())
.pipe(gulp.dest(path.build));
}));
gulp.src('index.html')
.pipe(inject(css));
Adding a .pipe(print())
with gulp-print after the .pipe(inject(css))
results in no files in the stream. So attempting to gulp.dest
the file does nothing (since the stream is empty). This is a silent failure, there are no errors.
If using a starttag
without "{ext}"
the files injected is overwritten for each extension.
The files should be grouped by starttag
instead of extension to fix this. (see #51)
It's a bit annoying using jade with gulp inject since there is no way (AFAIK) to add whitespace at the end of a comment.
// inject:css -> <!-- inject:css-->
Due to the missing space on the end both the start and end tag need to be specified in the inject config.
Is it worth having the defaults not whitespace sensitive?
I haven't been able to find a way to use gulp inject
to inject paths relative to the html file.
I'm using the gulp-angular yeoman generator which uses gulp-inject in the build
task (actually, the html
task) like this:
gulp.src('app/*.html')
.pipe($.inject(gulp.src('.tmp/partials/**/*.js'), {
read: false,
starttag: '<!-- inject:partials -->',
addRootSlash: false,
addPrefix: '../'
}))
There are just 2 html files with inject templates and only one js file and it takes more than 7 seconds to execute this part of the task. Any hints?
I'm trying to have gulp-inject, inject a bunch of JS files in my app.
My folder structure looks like this
gulpfile.js
app/
scripts/
index.html
The file comments that get injected look like this.
<script src="/app/scripts/app.js"></script>
However I need to remove the /app/ so the index.html file loads the .js files properly.
I've tried adding this {ignorePath: 'app'}
but it doesn't seem to remove it from the inject comments.
Any ideas?
I've tried using gulp.watch
and the gulp-watch
plugin, but anytime a change is detected, my index.html
file does not inject the <!-- inject:js -->
and <!-- inject:css -->
tags. index.html
is inject correctly when I first run my gulp task, but when I change index.html, it doesn't re-inject.
gulp.task('copy', function() {
gulp.src('./public/index.html')
.pipe($.inject(vendorStream, {
ignorePath: '/dist/',
addRootSlash: false
}))
.pipe(gulp.dest('./dist'))
.pipe(connect.reload());
});
gulp.task('watch', function() {
gulp.watch([paths.html], ['copy']);
...
});
gulp.task('copy', function() {
gulp.src('./public/index.html')
.pipe($.watch(function(files) {
files.pipe($.inject(vendorStream, {
ignorePath: '/dist/',
addRootSlash: false
}))
.pipe(gulp.dest('./dist'))
.pipe(connect.reload());
}));
});
Here is my code
gulp.task('dev', function() {
gulp.src('./src/index.html')
.pipe(inject(gulp.src(mainBowerFiles(), {read: true}), {name: 'bower'}))
.pipe(inject(gulp.src('./src/app/**/*.js').pipe(angularFilesort())))
.pipe(gulp.dest('./src'));
})
I get:
localhost:yo mozilla$ gulp dev
[13:22:14] Using gulpfile ~/Proj/yo/gulpfile.js
[13:22:14] Starting 'dev'...
[13:22:14] Finished 'dev' after 9.38 ms
[13:22:14] gulp-inject 1 files into index.html.
[13:22:14] gulp-inject 2 files into index.html.
And only the two files in src/app
appear, the other ones don't. If I switch the pip, I get the same, the other way around.
For example, the bootstrap css file from a CDN has the url of http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css
How do I inject this with gulp-inject?
I cannot seem to inject js into the body
. It only works if I inject into the head
, even when using starttag
instead of defaults.
Lets say I have a sign-up.html file and I created a sign-up.scss file that I want to compile and pipe into the injector to inject into my html file. But I only want it to inject the sign-up.css file into the sign-up.html file and no other .hmtl files that have the injector block. Is there a way to do this?
It is not immediately clear how one would inject a url for a CDN?
E.g. how might one inject the following:
["http://cdnjs.cloudflare.com/ajax/libs/jasmine/1.3.1/jasmine.js", "./spec/test"]
It would appear that gulp.src()
ignores the URL, and I did not see any unit tests corresponding with this functionality.
Many thanks for any thoughts. Cheers.
Hi, i'm using gulp-inject this works well, but i need a "gulp-reject", have you thought about that?
why wont this work?
return gulp.src('./*.hbs')
.pipe(inject(gulp.src('http://localhost:35729/livereload.js', {read: false})))
.pipe(gulp.dest('.'));
I got this task
gulp.task('dev-admin-index',function(){
var target = gulp.src('target');
var sources = gulp.src([
'public/js/controller/*.js',
],{
read:false
},{
transform: function (filepath) {
return 'hello-world';
}
});
return target
.pipe(inject(sources))
.pipe(gulp.dest('views/admin'));
});
no matter what I return on transform function on target file the file will be "public/js/controller/file.js"
If I try to addPrefix //myassets.s3.amazonaws.com
, I get /myassets.s3.amazonaws.com/myJS.js
. If I set addRootSlash to false, I get myassets.s3.amazonaws.com/myJS.js
. If I set addPrefix to http://myassets.s3.amazonaws.com"
it outputs correctly. I'm guessing it's one of the regexes that's clobbering the URL, but can't identify which one specifically.
Suggested enhancement: an option to remove the inject
/ endinject
comment pair after injection of the source tags. The endinject
comment could be optional if this option is set.
Basically a clone of ladjs/gulp-jade-usemin#3 but with support for img
tags as well in Jade (and HTML ofc).
Right now you don't support custom attributes in the returned HTML/jade output.
Unless injecting into a non-html file (i.e the JSON example) I don't see any need to specify <!-- endinject -->
in the html file.
So this pattern:
<!-- inject:js -->
<!-- any *.js files among your sources will go here as: <script src="FILE"></script> -->
<!-- endinject -->
Is the same as this one:
<!-- inject:js -->
But just shorter, more concise and less messy. The endtags IMO are a remnant of the usemin
patterns where you actually specify all files beforehand unlike gulp-inject
where files just come from a stream.
What do you think?
Getting issue #39 if I inject from two different gulp tasks. The same task it does not override. But separate tasks it causes the most recent task with inject to override the inject of a previous task.
First of all, congrats for the awesome plugin.
I'm using it in my gulpfile to inject Bower components but it seems it does not recognize the correct order of dependencie's order, causing issues with the bower components not working properly.
Is there a way to let it work like "wiredep" and let it understand in what order to inject dependencies' references?
Thanks in advance.
var sources = gulp.src(['app/pages/*/.scss']);
var target = gulp.src('app/styles/main.scss');
return target.pipe(inject(sources, {starttag: '// '}))
.pipe(gulp.dest('./app'));
main.scss
//
//
What if I have a very large project where at build time all of my javascript files are moved into a build folder /build/js
.
Each of their paths may be dramatically different and using ignorePath
would get out of hand.
Is there a way to completely remove the path from every file so I can specify my own like:
options:{
ignorePath:['*'],
addPrefix:'/js/'
}
I hate to ask questions in an issue, but here goes. It seems "un-gulpy" to pass in a file path and to use fs
to read that file. Isn't the gulp way to read it from the passed in stream? Is there a reason for this?
I'm having an issue where no matter how I configure gulp-inject it fails to inject anything into my index.html file. I've read the documentation and various articles many times.
Based on this stackoverflow post it seems that I'm not the only one having this issue.
http://stackoverflow.com/questions/23642809/gulp-inject-not-working?noredirect=1#comment36400651_23642809
I'm using the latest build of gulp-inject on node 0.10.28
When using this plugin with the following config:
return gulp.src("index.html")
.pipe(g.inject(gulp.src(["scripts/**/*.js",
"!scripts/**/*.test.js"],
{read: false}), {relative: true}))
.pipe(gulp.dest("dist"));
I get a different order of files each time I run it, even if the filesystem hasn't changed, which makes it hard to use the gulp-rev
plugin efficiently, because you get a different hash each time.
Is there a way to keep the recursive file search consistent?
Thanks!
var bower = require('main-bower-files');
var inject = require('gulp-inject');
gulp.task('test', function(){
return gulp.src('app/index.html')
.pipe(inject(gulp.src(bower()), {starttag: '<!-- inject:bower -->'}))
.pipe(gulp.dest('app'));
});
results in a few thousand new lines in my app/index.html inject tag. I've debugged the output for bower() and sure enough it grabs all the bower files. Thoughts?
Hi,
I tired this but its not working.
gulp.src('src/*.html')
.pipe($.inject(gulp.src('dist/assets/js/*.js')), {
read: false,
starttag: '<!-- inject:partials -->',
addRootSlash: false,
addPrefix: '../'
}))'
.pipe($.inject(gulp.src('dist/assets/css/*.css'),{
read:false,
starttag: '<!-- inject:css -->'
}))`
I am unable to see these tags into my index.html
Maybe we need an middleware?
Hi, thanks for this plugin, it's exactly what I was looking for. I have a problem though, it's not working for me :(
Here's my gulpfile:
var gulp = require('gulp');
var inject = require('gulp-inject');
// dynamically inject app assets to the HTML
gulp.task('build', function () {
return gulp.src(['./src/app/**/*.js', './src/app/**/*.css'], { read: false })
.pipe(inject('./src/index.html'))
.pipe(gulp.dest('./dist'));
});
gulp.task('default',function () {
gulp.run('build');
});
But when I run gulp, I don't get any dist directory. If I create it manually, after running gulp the directory remains empty.
I'm new to gulp, so... am I missing something here?
Thank you!
Hi,
I'm using gulp-inject to inject some files ./app/scripts/**/*.js
into my index.html. When gulp finds files, the plugin works as expected and injects all files. But when I remove all files from the filesystem the files aren't removed in the index.html. I experimented a little bit and found out that when at least one file is in the stream the plugin correctly removes all others. When I remove the last file, the index.html remains untouched resulting in 404's.
I reduced the problem to this simple task to reproduce it:
gulp.task('inject', function () {
var jsFiles = gulp.src(['./app/scripts/**/*.js']);
return gulp.src('./app/index.html')
.pipe($.inject(jsFiles, {relative: true}))
.pipe(gulp.dest('./app'));
});
Am I doing something wrong or is this the intended behavior?
I'm trying to drop the rootSlash from the output (needed to run on mobile devices).
Tried:
var src = {
cwd: 'app',
scripts: '{,modules/*/}scripts/**/*.js'
};
// [...]
.pipe(inject(gulp.src(src.scripts, {cwd: src.cwd, base: src.cwd}, {addRootSlash: false}).pipe(angularFilesort())))
But I end up with a rootSlash anyway, on an index.jade
file.
Tried addPrefix: '.',
as a workaround, but it's not working.
If I have 2 script groups in my html file, such as scripts
and vendors
, I would want to inject different files to different inject scripts holders. This would require that I can add namespacing to the inject target scripts (or html/css). Such as:
<!-- inject:js (vendors) -->
<!-- endinject -->
<!-- inject:js (scripts) -->
<!-- endinject -->
And then when piping the src stream I could namespace my injects:
var inject = require("gulp-inject");
gulp.src('./src/index.html')
.pipe(inject(gulp.src(["./src/*.js"], {read: false}), {namespace:'scripts'}))
.pipe(inject(gulp.src(["./src/vendors/*.js"], {read:false}), {namespace:'vendors'}))
.pipe(gulp.dest("./dist"));
This will allow for separate uglify & concat tasks based on namespacing. I for example want to uglify & concat scripts but only concat vendor scripts.
No matter what I do, when I use this plugin, it overwrites the original file.
I'm using this code:
return gulp.src(['.build/**/*.*', '!./build/index.html'], {read:false})
.pipe(inject('src/index.html'))
.pipe(gulp.dest('./build'));
I would expect the file to be output as './build/index.html'
, but it is definitely overwriting the source.
I think the issue might be that base
is being set as the basename of the file (ie: index.html
), rather than the base path (ie: src/
). When you simply call gulp.src()
on the file, that's what gulp sets it to:
Output of gulp.src('src/index.html').debug()
File
cwd: ~/myApp
base: ~/myApp/src/
path: ~/myApp/src/index.html
stat: [object Object]
contents: <!DOCTYPE html>
<html ng-app="djpack" ng...
Output of gulp.src([...]).pipe(inject('src/index.html')).debug()
File
cwd: ~/myApp
base: index.html
path: ~/myApp/src/index.html
contents: <!DOCTYPE html>
<html ng-app="djpack" ng...
Anyway, I think this is broken. base
is used by gulp.dest()
to determine the correct subfolders to save under.
As a suggestion, would it be possible to instead take a pipe as the source for the injected file? ie:
gulp.src([...]).pipe(inject(gulp.src('src/index.html'))).dest(...');
(see discussion in #8 )
Improving gulpyness
To make gulp-inject
more "gulpy" it should take a Vinyl File Stream as a parameter, instead of path to template.
If a Vinyl File Stream is given as parameter gulp-inject
will assume it contains the files to inject, and not the files to inject into.
Usage example
gulp.src('./src/index.html')
.pipe(inject(gulp.src(['./src/*.js', './src/*.css'])))
.pipe(gulp.dest('./build'));
Backwards compatibility
If a string
or object
is given as first parameter to gulp-inject
, it will use the old behavior.
Suggested enhancement: an option to set the base URL path (e.g. public_html/
), so absolute URLs point to the correct path.
Afaict the only solution right now is to the transform
option and manipulate the filepath
.
I got a problem with paths to injected files, my app structure looks like below
gulpfile.js
doc/
build/
src/
components/
grid.html
forms.html
styles/
base.css
index.html
I want to inject css file to every html file with keeping properly path, but it only works with index.html. How can I keep properly path in each level?
what i have:
index.html
<link rel="stylesheet" href="styles/css/base.css">
grid.html
<link rel="stylesheet" href="styles/css/base.css">
etc.
what i need:
index.html
<link rel="stylesheet" href="styles/css/base.css>
grid.html
<link rel="stylesheet" href="../styles/css/base.css">
etc
my gulpfile.js
var paths = {
html: './doc/src/**/*.html',
styles: './doc/build/styles/css/*.css',
out: './doc/build'
};
gulp.task('inject', function () {
gulp.src(paths.html)
.pipe(inject(gulp.src([paths.styles], {read: false}), {
ignorePath: 'doc/build',
addRootSlash: false
}
))
.pipe(gulp.dest(paths.out));
});
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.