Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why specify path to HTML file? #8

Closed
gabegorelick opened this issue Feb 10, 2014 · 7 comments
Closed

Why specify path to HTML file? #8

gabegorelick opened this issue Feb 10, 2014 · 7 comments

Comments

@gabegorelick
Copy link

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?

@joakimbeng
Copy link
Member

Yeah, I did think about that when making the plugin, but how do you specify which files to inject in a good way then?

@gabegorelick
Copy link
Author

Have you looked at https://github.com/zont/gulp-usemin?

@joakimbeng
Copy link
Member

Actually I think that gulp-usemin is even less "gulpy" than gulp-inject in my opinion. As a matter of fact it uses the fs module to read files manually as well.

I think it's more inline with the "gulp-way" to use gulp.src for the heavy parts, i.e. collecting a bunch of files with glob patterns, and let the plugin read just one file (in my case), instead of the reverse, which is the common case for gulp-usemin.

Although, I'm thinking of changing this plugin to accept a Vinyl File Stream as first parameter instead of a filename, which I think would be the most "gulpy" solution. Like this:

gulp.src('./src/*.js', './src/*.css')
  .pipe(inject(gulp.src('./src/index.html')))
  .pipe(gulp.dest('./build'));

That should be a minor fix. But maybe the other way around is more clear:

gulp.src('./src/index.html')
  .pipe(inject(gulp.src('./src/*.js', './src/*.css')))
  .pipe(gulp.dest('./build'));

That will break backwards compatibility though, but I think clarity is more important.

What do you think?

@gabegorelick
Copy link
Author

Actually I think that gulp-usemin is even less "gulpy" than gulp-inject in my opinion. As a matter of fact it uses the fs module to read files manually as well.

Ah. I didn't look at gulp-usemin's source. I just thought their API was a little cleaner (although it's not perfect). As a side note, it looks like they're using fs to process the JS and CSS, which I think is unnecessary.

What do you think?

This is a little better, but why do you need to read the JS and CSS files? I envision this plugin as something like a wrapper around gulp-replace: it scans your files for HTML comments and replaces the referenced resources with whatever you specify.

For example, in gulp-usemin, this:

<!-- build:js main.js -->
<script src="foo"></script>
<!-- endbuild -->

becomes

<script src="main.js"></script>

with

gulp.src('*.html')
  .pipe(usemin());

This is nice in that the plugin doesn't have to concern itself with where main.js comes from. That can be handled later, perhaps in a separate task.

@joakimbeng
Copy link
Member

This is a little better, but why do you need to read the JS and CSS files?

Actually I don't need to read the files to inject which is why I recommend you to use the {read: false} option for gulp.src as stated in the readme. I only want their paths.

But gulp-usemin on the other hand does some things it shouldn't, IMO: like 1) parsing an html-file to find sources (js and css files) 2) and their targets, 3) reading the sources, 4) concatenating them and 5) replaces the comments in the html-file with a reference to the concatenated resource. Which sounds like a lot of things already covered by other plugins.

As a side note, it looks like they're using fs to process the JS and CSS, which I think is unnecessary.

As you can see in my last statement, gulp-usemin can not manage without the fs module, and I don't think it can be rewritten in a simple way to get rid of it either.

This is nice in that the plugin doesn't have to concern itself with where main.js comes from. That can be handled later, perhaps in a separate task.

In theory yes, but because the usemin plugin reads and concatenates files this is not practical in reality.

Another downside with gulp-usemin is that you can not understand from reading the gulpfile what files will be injected/replaced/concatenated into the source html.

To accomplish something similar to gulp-usemin with gulp-inject one could do like this:

index.html:

...
<body>
<!-- inject:js -->
<!-- endinject -->
</body>

gulpfile.js (production task):

gulp.src('./src/**/*.js')
  .pipe(concat('package.js'))
  .pipe(gulp.dest('./build')) // Saving unminified source
  .pipe(uglify())
  .pipe(rename('package.min.js'))
  .pipe(gulp.dest('./build')) // Saving minified source
  .pipe(inject('./src/index.html', {ignorePath: '/build'})) // Injecting 'package.min.js'
  .pipe(gulp.dest('./build')); // Saving index.html

gulpfile.js (development task):

gulp.src('./src/**/*.js', {read: false})
  .pipe(inject('./src/index.html', {ignorePath: '/build'})) // Injecting 'package.min.js'
  .pipe(gulp.dest('./src')); // Saving index.html at its location

Which I think is much clearer than the gulp-usemin solution.

@gabegorelick
Copy link
Author

I agree with all this. gulp-usemin does too many things. They shouldn't concern themselves with concatenation and minification. However, I think they recently changed to not doing any processing by default. I know the way I ended up using it, it just replaces things between comments. This is how I think gulp-inject should behave. Just replace things between specified comments.

Another downside with gulp-usemin is that you can not understand from reading the gulpfile what files will be injected/replaced/concatenated into the source html.

I think there are pros and cons to this approach, but since gulp-usemin already does it, there's no sense in reimplementing what it does. So let's say gulp-inject gets the name of the file to inject from an option passed into it, e.g.

gulp.src('*.html')
  .pipe(inject({file: 'scripts/foo.js'})

Would that work? Remember, the name of the file doesn't actually have to point to a file. It's just a string that should be injected as <script src="scripts/foo.js">. Where the actual file comes from should be outside the scope of gulp-inject (it may not actually be a file on the filesystem after all). Multiple inject directives in a single file could be handled by running gulp-inject multiple times and using different starttags, as opposed to how usemin does it with different file names in the HTML comments. Or you could add more options to the API to make this usecase cleaner.

@joakimbeng
Copy link
Member

Your last example is no different than the current functionality, except it's reversed, i.e. you inject one javascript file into many html files, but gulp-inject is mainly built to inject many files into one template (which is the more common scenario in single page application development).

I will settle with this approach, as earlier mentioned:

gulp.src('./src/index.html')
  .pipe(inject(gulp.src('./src/*.js', './src/*.css')))
  .pipe(gulp.dest('./build'));

With that solution gulp-inject won't read files itself, and one can inject one file into many templates, many files into one template or many files into many templates, i.e. it'll support all possibilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants