Anton W
Anton W

Reputation: 36

Jade include produces error when trying to include a file in parent folder sibling

So I have this piece of Jade code in the top of my layout.jade file:

doctype html
  html
    head
      include ./../jade/includes/head

This produces the error

ENOENT, no such file or directory '[project root]/jade/jade/includes/head.jade'

Notice the double instance of 'jade'.

The folder structure is like this:

[project home]
  app/
    jade/
      layouts/
        layout.jade
      includes/
        head.jade

BTW, this produces the same error:

include ../jade/includes/head

This is a fairly standard WSK project (which uses Gulp), compiling the Jade using gulp-accord. See snippet from gulp file below:

// Compile Jade files.
gulp.task('jade', function () {

  return gulp.src('app/jade/**/*.jade')
    .pipe($.accord('jade', { pretty: true }))
    .pipe(gulp.dest('.tmp'))
    .pipe(gulp.dest('dist'));

});

I got around the problem by specifying a 'basedir' ("app/") as an option for gulp-accord in the gulpfile and using this instead:

include /jade/includes/head

Perhaps that is simply better practice, but I would still like to know why the error occurred.

EDIT:

Having banged my head against this for a while I missed including a very important part, which is this:

include ./../includes/head

And that it throws the error:

ENOENT, no such file or directory '[project home]/app/includes/head.jade

So it's damned if you do, damned if you don't...

Upvotes: 0

Views: 1193

Answers (2)

Anton W
Anton W

Reputation: 36

By way of further testing, the problem lies in that the layout was rendered both on its own and when used by way of extends in other files. The proof is in that the errors are thrown for the different files depending on the path: One for the jade/jade/, the other for when backing out one step to far as brought up in the edit.

The paths to other files in the structure needs to survive both these contexts, i.e. by using absolute paths (like include /jade/includes/head) with a basedir option set in the gulpfile (value of "app", in my particular WSK case). Or you need to make sure that partials and layouts do not get compiled by excluding them from the gulp.src(). In the case of my folder structure that would be this:

gulp.task('jade', function () {
  return gulp.src(['app/jade/**/*.jade', 
                   '!app/jade/layouts{,/**}', 
                   '!app/jade/includes{,/**}'])
    .pipe($.accord('jade', { pretty: true, basedir: "app" }))
    .pipe(gulp.dest('.tmp'))
    .pipe(gulp.dest('dist'));
});

Using a basedir and absolute path you do not have to worry about adding further folders in the future. But you probably do not want to compile layouts and partials to HTML anyway, so why not do both?

A good walkthrough on excluding is here.

Upvotes: 1

ezpn
ezpn

Reputation: 1748

Your included path will be relative to the directory /app/jade/layouts of current file - layout.jade. That is why you need to traverse up the directory tree (../) only once to end up in /app/jade directory. From here you were trying to get into jade directory again (jade/), which was not present (/app/jade/jade does not exist). Instead go straight to includes/head.

The include code below should work properly:

include ./../includes/head

Upvotes: 0

Related Questions