Grunt编译Jade文件

22

我正在尝试配置我的Gruntfile将所有的Jade文件编译为单独的HTML文件。例如,如果我有以下源文件夹:

source
└── templates
    ├── first.jade
    ├── second.jade
    └── third.jade

那么我期望 grunt jade 输出:

build
└── templates
    ├── first.html
    ├── second.html
    └── third.html

这是我的 Gruntfile,使用了 grunt-contrib-jade 插件:

module.exports = function(grunt) {
    grunt.initConfig({

        jade: {
            compile: {
                options: {
                    client: false,
                    pretty: true
                },
                files: [ {
                  src: "*.jade",
                  dest: "build/templates/",
                  ext: "html",
                  cwd: "source/templates/"
                } ]
            }
        },
    });

    grunt.loadNpmTasks("grunt-contrib-jade");
};

然而,当我运行jade命令时,我会遇到以下错误:

Running "jade:compile" (jade) task
>> Source file "first.jade" not found.
>> Source file "second.jade" not found.
>> Source file "third.jade" not found.

我做错了什么?


尝试使用以下代码:files: {"source/templates/out.html: ['source/templates/*.jade']} - elclanrs
我想将它们编译成多个文件,而不是一个单独的文件。 - LandonSchropp
1
哦,我明白了...看文档似乎是这样添加扩展名的 ext: '.html',带点。我不知道问题出在哪里...你试过不用 cwd 来测试完整路径吗? - elclanrs
好的,我想这会有所帮助。现在我遇到了错误:警告:无法写入“build/templates/”文件(错误代码:EISDIR)。使用--force继续。 - LandonSchropp
看起来它把dest当作单个文件处理了。 - LandonSchropp
没关系,我已经想出来了。感谢你的帮助! - LandonSchropp
3个回答

50
为了完成以上回答。
    jade: {
        compile: {
            options: {
                client: false,
                pretty: true
            },
            files: [ {
              cwd: "app/views",
              src: "**/*.jade",
              dest: "build/templates",
              expand: true,
              ext: ".html"
            } ]
        }
    }

如果你的源代码结构如下:

app
└── views
    └── main.jade
    └── user
        └── signup.jade
        └── preferences.jade

grunt jade 将创建以下结构

build
└── templates
    └── main.html
    └── user
        └── signup.html
        └── preferences.html

编辑: grunt-contrib-jade已经被废弃了。你应该使用grunt-contrib-pug。它与 jade 完全相同,但是他们必须将 jade 更名为 pug!


2
“files:” 部分有点令人困惑。Grunt会扩展它吗,还是它们只是 grunt jade 插件的选项?我之所以问,是因为我想在 /views/ 目录中使用 layout.jade 文件作为 include,但我不想编译 layout.jade 文件。在 “files” 字段中有没有一种巧妙的方法来包含单个文件?而且我希望将其保留在/views/中,因为它是由 Express 渲染引擎使用的。谢谢。 - PeterT

3

以防有人需要。以上的方法都不起作用。这是我的最终解决方法。

我使用 grunt.loadNpmTasks('grunt-contrib-pug'); ,我不知道 contrib-jade 是否已被弃用,但这个解决方案对我有效。我需要第一个文件对象仅处理index.jade,第二个来处理模板。现在,如果我不将它分开,只是指向项目目录,jade编译器就会迷失在我的npm包文件夹中,所以这样运行速度更快。

pug: {
        compile: {
            options: {
                client: false,
                pretty: true,
                data: {
                    debug: false
                }
            },
            files: [
            {
                'dist/index.html': ['index.jade']
            },
            {
                src: "templates/*.jade",
                dest: "dist",
                expand: true,
                ext: ".html"
            } ]
        }
    }

1
我知道这是一个旧帖子,但在尝试解决类似问题时,我一直回到这里。我想从单个jade模板文件使用for循环输出多个html文件。所以需要更好地控制'files'对象。
我遇到的两个问题并最终解决的问题是设置输出文件名(javascript对象文字KEY)和确保内联javascript函数立即运行,以便循环变量可用。
这是我完整的源代码和注释。我希望这对任何其他偶然发现这篇文章的人有用。

Gruntfile.js:

module.exports = function(grunt) {

  // Create basic grunt config (e.g. watch files)
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    watch: {
      grunt: { files: ['Gruntfile.js'] },
      jade: {
        files: 'src/*.jade',
        tasks: ['jade']
      }
    }
  });

  // Load json to populate jade templates and build loop
  var json = grunt.file.readJSON('test.json');

  for(var i = 0; i < json.length; i++) {
      var obj = json[i];

      // For each json item create a new jade task with a custom 'target' name.
      // Because a custom target is provided don't nest options/data/file parameters 
      // in another target like 'compile' as grunt wont't be able to find them 
      // Make sure that functions are called using immediate invocation or the variables will be lost
      // https://dev59.com/sHNA5IYBdhLWcg3wfd8m      
      grunt.config(['jade', obj.filename], {
        options: {
            // Pass data to the jade template
            data: (function(dest, src) {
                return {
                  myJadeName: obj.myname,
                  from: src,
                  to: dest
                };
            }()) // <-- n.b. using() for immediate invocation
        },
        // Add files using custom function
        files: (function() {
          var files = {};
          files['build/' + obj.filename + '.html'] = 'src/index.jade';
          return files;
        }()) // <-- n.b. using () for immediate invocation
      });
  }

  grunt.loadNpmTasks('grunt-contrib-jade');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Register all the jade tasks using top level 'jade' task
  // You can also run subtasks using the target name e.g. 'jade:cats'
  grunt.registerTask('default', ['jade', 'watch']);
};

src/index.jade:

doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) {
         bar(1 + 5)
      }
  body
    h1 #{myJadeName} - node template engine    
    #container.col
      p.
        Jade is a terse and simple
        templating language with a
        strong focus on performance
        and powerful features.

test.json:

[{
    "id" : "1", 
    "filename"   : "cats",
    "tid" : "2016-01-01 23:35",
    "myname": "Cat Lady"
},
{
    "id" : "2", 
    "filename"   : "dogs",
    "tid" : "2016-01-01 23:45",
    "myname": "Dog Man"
}]

运行“grunt”后,输出应该是:
build/cats.html
build/dogs.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接