Suruh Grunt menghasilkan index.html untuk berbagai pengaturan


208

Saya mencoba menggunakan Grunt sebagai alat bantu membangun untuk aplikasi web saya.

Saya ingin memiliki setidaknya dua pengaturan:

I. Pengaturan pengembangan - memuat skrip dari file yang terpisah, tanpa gabungan,

jadi index.html saya akan terlihat seperti:

<!DOCTYPE html>
<html>
    <head>
        <script src="js/module1.js" />
        <script src="js/module2.js" />
        <script src="js/module3.js" />
        ...
    </head>
    <body></body>
</html>

II Setup produksi - muat skrip saya yang diperkecil & disatukan dalam satu file,

dengan index.html sesuai:

<!DOCTYPE html>
<html>
    <head>
        <script src="js/MyApp-all.min.js" />
    </head>
    <body></body>
</html>

Pertanyaannya adalah, bagaimana saya bisa membuat grunt membuat index.html ini tergantung pada konfigurasi ketika saya menjalankan grunt devatau grunt prod?

Atau mungkin saya menggali ke arah yang salah dan akan lebih mudah untuk selalu menghasilkan MyApp-all.min.jstetapi memasukkan semua skrip saya (concatenated) atau skrip loader yang secara sinkron memuat skrip-skrip tersebut dari file yang terpisah?

Bagaimana kamu melakukannya, kawan?


3
Cobalah alat Yeoman, yang mencakup tugas 'usemin' yang melakukan apa yang Anda inginkan. Selain itu, generator Yeamon mencakup banyak "praktik bagus" yang mudah dipelajari yang sulit dipelajari saat menggunakan alat baru.
EricSonaron

Jawaban:


161

Baru-baru ini saya menemukan v0.4.0tugas yang kompatibel dengan Grunt ini :

Berikut cuplikan dari saya Gruntfile.js.

Pengaturan ENV:

env : {

    options : {

        /* Shared Options Hash */
        //globalOption : 'foo'

    },

    dev: {

        NODE_ENV : 'DEVELOPMENT'

    },

    prod : {

        NODE_ENV : 'PRODUCTION'

    }

},

Praproses:

preprocess : {

    dev : {

        src : './src/tmpl/index.html',
        dest : './dev/index.html'

    },

    prod : {

        src : './src/tmpl/index.html',
        dest : '../<%= pkg.version %>/<%= now %>/<%= ver %>/index.html',
        options : {

            context : {
                name : '<%= pkg.name %>',
                version : '<%= pkg.version %>',
                now : '<%= now %>',
                ver : '<%= ver %>'
            }

        }

    }

}

Tugas:

grunt.registerTask('default', ['jshint']);

grunt.registerTask('dev', ['jshint', 'env:dev', 'clean:dev', 'preprocess:dev']);

grunt.registerTask('prod', ['jshint', 'env:prod', 'clean:prod', 'uglify:prod', 'cssmin:prod', 'copy:prod', 'preprocess:prod']);

Dan dalam /src/tmpl/index.htmlfile template (misalnya):

<!-- @if NODE_ENV == 'DEVELOPMENT' -->

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
    <script src="../src/js/foo1.js"></script>
    <script src="../src/js/foo2.js"></script>
    <script src="../src/js/jquery.blah.js"></script>
    <script src="../src/js/jquery.billy.js"></script>
    <script src="../src/js/jquery.jenkins.js"></script>

<!-- @endif -->

<!-- @if NODE_ENV == 'PRODUCTION' -->

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script src="http://cdn.foo.com/<!-- @echo name -->/<!-- @echo version -->/<!-- @echo now -->/<!-- @echo ver -->/js/<!-- @echo name -->.min.js"></script>

<!-- @endif -->

Saya yakin pengaturan saya berbeda dari kebanyakan orang, dan kegunaan di atas akan tergantung pada situasi Anda. Bagi saya, meskipun sedikit kode yang luar biasa, Yeoman grunt-usemin lebih kuat dari yang saya butuhkan secara pribadi.

CATATAN: Saya baru saja menemukan tugas-tugas yang tercantum di atas hari ini, jadi saya mungkin kehilangan fitur dan / atau proses saya mungkin berubah di jalan. Untuk saat ini, saya menyukai kesederhanaan dan fitur yang ditawarkan oleh grunt-preprocess dan grunt-env . :)


Pembaruan Jan 2014:

Termotivasi oleh suara turun ...

Ketika saya memposting jawaban ini, tidak ada banyak pilihan untuk Grunt 0.4.xyang menawarkan solusi yang sesuai dengan kebutuhan saya. Sekarang, berbulan-bulan kemudian, saya kira ada lebih banyak pilihan di luar sana yang bisa lebih baik daripada yang saya posting di sini. Sementara saya secara pribadi masih menggunakan, dan menikmati menggunakan, teknik ini untuk membangun saya , saya meminta pembaca masa depan meluangkan waktu untuk membaca jawaban lain yang diberikan dan untuk meneliti semua opsi. Jika Anda menemukan solusi yang lebih baik, silakan kirim jawaban Anda di sini.

Pembaruan Februari 2014:

Saya tidak yakin apakah ini akan membantu siapa pun, tetapi saya telah membuat repositori demo ini di GitHub yang memperlihatkan lengkap (dan lebih rumit penyiapan) menggunakan teknik yang telah saya uraikan di atas.


Terima kasih, saya akan memeriksanya!
Dmitry Pashkevich

3
Solusi Anda menyelamatkan saya berjam-jam dengan menabrak kepala di dinding. Terima kasih.
sthomps

1
@sthomps Senang itu membantu! Sejak saya menemukan tugas-tugas itu, saya sudah menyukai alur kerjanya. FYI, saya telah membuat sedikit perubahan pada proses ... Alih-alih mengirimkan beberapa variabel konteks ke templat html saya, saya memilih untuk melewatkan satu var path : '/<%= pkg.name %>/dist/<%= pkg.version %>/<%= now %>/<%= ver %>'yang menggabungkan semua var (itulah jalur build saya). Template saya akan memiliki: <script src="http://cdn.foo.com<!-- @echo path -->/js/bulldog.min.js"></script>. Ngomong-ngomong, aku senang bisa menghemat waktu! : D
mhulse

4
Anda dapat melakukan hal yang sama hanya menggunakan grunt-template , hanya dengan mengirimkan dataobjek yang berbeda untuk dev / prod.
Mathias Bynens

2
Saya suka solusi ini .. Bersih, mudah dibaca dan tidak direkayasa.
Gaurang Patel

34

Saya sudah menemukan solusi saya sendiri. Belum dipoles tapi saya pikir saya akan bergerak ke arah itu.

Pada dasarnya, saya menggunakan grunt.template.process () untuk menghasilkan saya index.htmldari template yang menganalisis konfigurasi saat ini dan menghasilkan daftar file sumber asli saya atau tautan ke file tunggal dengan kode minified. Contoh di bawah ini adalah untuk file js tetapi pendekatan yang sama dapat diperluas ke css dan file teks lainnya yang mungkin.

grunt.js:

/*global module:false*/
module.exports = function(grunt) {
    var   // js files
        jsFiles = [
              'src/module1.js',
              'src/module2.js',
              'src/module3.js',
              'src/awesome.js'
            ];

    // Import custom tasks (see index task below)
    grunt.loadTasks( "build/tasks" );

    // Project configuration.
    grunt.initConfig({
      pkg: '<json:package.json>',
      meta: {
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
          '<%= grunt.template.today("yyyy-mm-dd") %> */'
      },

      jsFiles: jsFiles,

      // file name for concatenated js
      concatJsFile: '<%= pkg.name %>-all.js',

      // file name for concatenated & minified js
      concatJsMinFile: '<%= pkg.name %>-all.min.js',

      concat: {
        dist: {
            src: ['<banner:meta.banner>'].concat(jsFiles),
            dest: 'dist/<%= concatJsFile %>'
        }
      },
      min: {
        dist: {
        src: ['<banner:meta.banner>', '<config:concat.dist.dest>'],
        dest: 'dist/<%= concatJsMinFile %>'
        }
      },
      lint: {
        files: ['grunt.js'].concat(jsFiles)
      },
      // options for index.html builder task
      index: {
        src: 'index.tmpl',  // source template file
        dest: 'index.html'  // destination file (usually index.html)
      }
    });


    // Development setup
    grunt.registerTask('dev', 'Development build', function() {
        // set some global flags that all tasks can access
        grunt.config('isDebug', true);
        grunt.config('isConcat', false);
        grunt.config('isMin', false);

        // run tasks
        grunt.task.run('lint index');
    });

    // Production setup
    grunt.registerTask('prod', 'Production build', function() {
        // set some global flags that all tasks can access
        grunt.config('isDebug', false);
        grunt.config('isConcat', true);
        grunt.config('isMin', true);

        // run tasks
        grunt.task.run('lint concat min index');
    });

    // Default task
    grunt.registerTask('default', 'dev');
};

index.js (the index task):

module.exports = function( grunt ) {
    grunt.registerTask( "index", "Generate index.html depending on configuration", function() {
        var conf = grunt.config('index'),
            tmpl = grunt.file.read(conf.src);

        grunt.file.write(conf.dest, grunt.template.process(tmpl));

        grunt.log.writeln('Generated \'' + conf.dest + '\' from \'' + conf.src + '\'');
    });
}

Akhirnya, index.tmpldengan logika generasi yang dipanggang:

<doctype html>
<head>
<%
    var jsFiles = grunt.config('jsFiles'),
        isConcat = grunt.config('isConcat');

    if(isConcat) {
        print('<script type="text/javascript" src="' + grunt.config('concat.dist.dest') + '"></script>\n');
    } else {
        for(var i = 0, len = jsFiles.length; i < len; i++) {
            print('<script type="text/javascript" src="' + jsFiles[i] + '"></script>\n');
        }
    }
%>
</head>
<html>
</html>

UPD. Menemukan bahwa Yeoman , yang didasarkan pada mendengus, memiliki tugas usemin bawaan yang terintegrasi dengan sistem pembangunan Yeoman. Ini menghasilkan versi produksi index.html dari informasi dalam versi pengembangan index.html serta pengaturan lingkungan lainnya. Agak canggih tapi menarik untuk dilihat.


5
grunt-template adalah pembungkus yang sangat ringangrunt.template.process()(yang Anda gunakan di sini) yang akan membuat ini lebih mudah. Anda dapat melakukan hal yang sama menggunakan grunt-template hanya dengan mengirimkandataobjek yangberbedauntuk dev / prod.
Mathias Bynens

15

Saya tidak suka solusi di sini (termasuk yang saya berikan sebelumnya ) dan inilah alasannya:

  • Masalah dengan jawaban pilihan tertinggi adalah Anda harus menyinkronkan daftar tag skrip secara manual saat Anda menambah / mengganti nama / menghapus file JS.
  • Masalah dengan jawaban yang diterima adalah bahwa daftar file JS Anda tidak dapat memiliki pencocokan pola. Ini artinya Anda harus memperbaruinya dengan tangan di Gruntfile.

Saya telah menemukan cara untuk menyelesaikan kedua masalah ini. Saya telah mengatur tugas kasar saya sehingga setiap kali file ditambahkan atau dihapus, tag skrip otomatis dihasilkan untuk mencerminkan hal itu. Dengan cara ini, Anda tidak perlu memodifikasi file html atau file mendengus Anda saat Anda menambah / menghapus / mengganti nama file JS Anda.

Untuk meringkas cara kerjanya, saya memiliki template html dengan variabel untuk tag skrip. Saya menggunakan https://github.com/alanshaw/grunt-include-replace untuk mengisi variabel itu. Dalam mode dev, variabel itu berasal dari pola globbing semua file JS saya. Tugas arloji menghitung ulang nilai ini ketika file JS ditambahkan atau dihapus.

Sekarang, untuk mendapatkan hasil berbeda dalam mode dev atau prod, Anda cukup mengisi variabel itu dengan nilai yang berbeda. Ini beberapa kode:

var jsSrcFileArray = [
    'src/main/scripts/app/js/Constants.js',
    'src/main/scripts/app/js/Random.js',
    'src/main/scripts/app/js/Vector.js',
    'src/main/scripts/app/js/scripts.js',
    'src/main/scripts/app/js/StatsData.js',
    'src/main/scripts/app/js/Dialog.js',
    'src/main/scripts/app/**/*.js',
    '!src/main/scripts/app/js/AuditingReport.js'
];

var jsScriptTags = function (srcPattern, destPath) {
    if (srcPattern === undefined) {
        throw new Error("srcPattern undefined");
    }
    if (destPath === undefined) {
        throw new Error("destPath undefined");
    }
    return grunt.util._.reduce(
        grunt.file.expandMapping(srcPattern, destPath, {
            filter: 'isFile',
            flatten: true,
            expand: true,
            cwd: '.'
        }),
        function (sum, file) {
            return sum + '\n<script src="' + file.dest + '" type="text/javascript"></script>';
        },
        ''
    );
};

...

grunt.initConfig({

    includereplace: {
        dev: {
            options: {
                globals: {
                    scriptsTags: '<%= jsScriptTags(jsSrcFileArray, "../../main/scripts/app/js")%>'
                }
            },
            src: [
                'src/**/html-template.html'
            ],
            dest: 'src/main/generated/',
            flatten: true,
            cwd: '.',
            expand: true
        },
        prod: {
            options: {
                globals: {
                    scriptsTags: '<script src="app.min.js" type="text/javascript"></script>'
                }
            },
            src: [
                'src/**/html-template.html'
            ],
            dest: 'src/main/generatedprod/',
            flatten: true,
            cwd: '.',
            expand: true
        }

...

    jsScriptTags: jsScriptTags

jsSrcFileArrayadalah pola menggumpal file grunt khas Anda. jsScriptTagsmengambil jsSrcFileArraydan menyatukannya dengan scripttag di kedua sisi. destPathadalah awalan yang saya inginkan pada setiap file.

Dan inilah tampilannya HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Example</title>

</head>

<body>    
@@scriptsTags
</body>
</html>

Sekarang, seperti yang Anda lihat di konfigurasi, saya menghasilkan nilai variabel itu sebagai scripttag berkode keras ketika dijalankan dalam prodmode. Dalam mode dev, variabel ini akan diperluas ke nilai seperti ini:

<script src="../../main/scripts/app/js/Constants.js" type="text/javascript"></script>
<script src="../../main/scripts/app/js/Random.js" type="text/javascript"></script>
<script src="../../main/scripts/app/js/Vector.js" type="text/javascript"></script>
<script src="../../main/scripts/app/js/StatsData.js" type="text/javascript"></script>
<script src="../../main/scripts/app/js/Dialog.js" type="text/javascript"></script>

Beri tahu saya jika Anda memiliki pertanyaan.

PS: Ini adalah jumlah kode gila untuk sesuatu yang ingin saya lakukan di setiap aplikasi JS sisi klien. Saya harap seseorang dapat mengubah ini menjadi plugin yang dapat digunakan kembali. Mungkin suatu hari nanti.


1
Kedengarannya menjanjikan. Apakah ada peluang Anda dapat berbagi cuplikan?
Adam Marshall

I've set up my grunt task so that every time a file is added or deleted, the script tags automatically get generated to reflect thatBagaimana Anda melakukannya?
CodyBugstein

2
Pertanyaan lain: Apakah Anda tahu cara menghapus blok-blok <script>tag HTML ?
CodyBugstein

@Marray tidak keluar dari kepala saya. Maksud Anda tanpa bentuk templating (misalnya, grunt-include-replace)? Pikiran pertama yang muncul di kepalaku adalah xslt. Mungkin bukan solusi yang baik.
Daniel Kaplan

1
Jawaban ini tepat, meskipun saya pribadi dihapus destPathdari jsScriptTagsdan bertukar grunt.file.expandMappingdengan grunt.file.expandkarena file yang saya inginkan sudah di tempat yang benar. Ini banyak hal yang disederhanakan. Terima kasih @DanielKaplan, Anda telah menyelamatkan saya untuk waktu yang sangat lama :)
DanielM

13

Saya telah bertanya pada diri sendiri pertanyaan yang sama untuk sementara waktu, dan saya pikir plugin kasar ini dapat dikonfigurasi untuk melakukan apa yang Anda inginkan: https://npmjs.org/package/grunt-targethtml . Ini menerapkan tag html bersyarat, yang tergantung pada target kasar.


2
Saya telah melihat plugin ini tetapi saya tidak suka gagasan untuk secara manual menentukan semua file (dan sebenarnya memiliki logika) di index.html saya karena saya sudah memiliki daftar file sumber js / css dalam konfigurasi kasar saya dan jangan Saya tidak ingin mengulangi lagi. Intinya adalah - itu bukan di index.html di mana Anda harus memutuskan file apa yang akan dimasukkan
Dmitry Pashkevich

+1 untuk grunt-targethtml. Meskipun agak jelek untuk menambahkan jika pernyataan untuk "memutuskan" di index.html aset Anda untuk memuat. Tetap saja, itu masuk akal. Ini adalah tempat Anda biasanya akan melihat untuk memasukkan sumber daya dalam proyek Anda. Juga, menindaklanjuti hal ini membuat saya memeriksa contreng. Ada beberapa hal hebat di dalamnya.
carbontax

8

Saya mencari solusi yang lebih sederhana dan lurus sehingga saya menggabungkan jawaban dari pertanyaan ini:

Cara menempatkan if lagi memblokir di gruntfile.js

dan datang dengan langkah-langkah sederhana berikut:

  1. Simpan dua versi file indeks Anda saat Anda terdaftar dan beri nama mereka index-development.html dan index-prodoction.html.
  2. Gunakan logika berikut di blok concat / copy Gruntfile.js Anda untuk file index.html Anda:

    concat: {
        index: {
            src : [ (function() {
                if (grunt.option('Release')) {
                  return 'views/index-production.html';
                } else {
                  return 'views/index-development.html';
                }
              }()) ],
           dest: '<%= distdir %>/index.html',
           ...
        },
        ...
    },
  3. jalankan 'grunt --Release' untuk memilih file index-production.html dan tinggalkan flag untuk memiliki versi pengembangan.

Tidak ada plugin baru untuk ditambahkan atau dikonfigurasi dan tidak ada tugas kasar baru.


3
Satu-satunya downside di sini adalah ada dua file index.html untuk dipelihara.
Adam Marshall

5

Tugas kasar ini bernama scriptlinker ini terlihat seperti cara mudah untuk menambahkan skrip dalam mode dev. Anda mungkin dapat menjalankan tugas concat terlebih dahulu dan kemudian arahkan ke file concatenated Anda dalam mode prod.


+1. Dokumentasinya membingungkan dan beberapa hal (appRoot, relatif) tidak selalu berfungsi sebagaimana dimaksud, tetapi tetap: alat yang membantu.
hashchange

1
@hashchange Saya tidak menggunakan alat ini. Saya akhirnya menggunakan github.com/alanshaw/grunt-include-replace sebagai gantinya. Saya memiliki variabel dalam file html saya yang mewakili tag skrip. Lalu saya mengisi variabel itu dengan String html yang saya inginkan. Dalam mode dev, variabel ini adalah daftar skrip. Dalam mode prod, variabel ini adalah versi gabungan, yang diperkecil.
Daniel Kaplan

Terima kasih atas pointer untuk menggerutu-termasuk-ganti. (Saya benar-benar membutuhkan alat untuk menambahkan semua file spesifikasi dalam direktori ke file index.html Mocha. Scriptlinker baik-baik saja untuk itu.)
hashchange

@hashchange Anda benar tentang isian dokumentasi. Bagaimana Anda memberi tahu tempat meletakkan ubin skrip ke file html Anda?
Daniel Kaplan

1
Anda mendefinisikan komentar HTML. Lihatlah file ini . Insersi terjadi pada <!--SINON COMPONENT SCRIPTS-->dan <!--SPEC SCRIPTS-->. Dan di sini adalah tugas Grunt yang melakukannya (yang berfungsi, yang bertentangan dengan hal-hal dalam dokumen). Semoga ini bisa membantu;)
hashchange

5

grunt-dom-hijauer membaca dan memanipulasi HTML dengan pemilih CSS. Ex. baca tag dari html Anda. Hapus node, tambahkan node, dan banyak lagi.

Anda dapat menggunakan grunt-dom-hijauer untuk membaca semua file JS Anda yang ditautkan oleh index.html Anda, uglify mereka dan kemudian gunakan grunt-dom-hijauer lagi untuk memodifikasi indeks Anda.html untuk hanya menghubungkan JS yang diperkecil


5

Saya menemukan plugin kasar yang disebut grunt-dev-prod-switch. Yang perlu dilakukan adalah mengomentari blok tertentu yang dicari berdasarkan opsi --env yang Anda berikan untuk mendengus (meskipun membatasi Anda untuk dev, prod, dan test).

Setelah Anda mengaturnya seperti yang dijelaskan di sini , Anda dapat menjalankan misalnya:

grunt serve --env=dev, dan yang dilakukannya hanyalah mengomentari blok yang dibungkus oleh

    <!-- env:test/prod -->
    your code here
    <!-- env:test/prod:end -->

dan itu akan menghilangkan tanda blok yang dibungkus oleh

    <!-- env:dev -->
    your code here
    <!-- env:dev:end -->

Ini juga berfungsi pada javascript, saya menggunakannya untuk mengatur alamat IP yang tepat untuk terhubung ke API backend saya. Blok hanya berubah menjadi

    /* env:dev */
    your code here
    /* env:dev:end */

Dalam kasus Anda, sesederhana ini:

<!DOCTYPE html>
<html>
    <head>
        <!-- env:dev -->
        <script src="js/module1.js" />
        <script src="js/module2.js" />
        <script src="js/module3.js" />
        ...
        <!-- env:dev:end -->
        <!-- env:prod -->
        <script src="js/MyApp-all.min.js" />
        ...
        <!-- env:prod:end -->
    </head>
    <body></body>
</html>

4

grunt-bake adalah skrip grunt yang fantastis yang akan bekerja sangat baik di sini. Saya menggunakannya dalam skrip build JQM otomatis saya.

https://github.com/imaginethepoet/autojqmphonegap

Lihatlah file grunt.coffee saya:

bake:
    resources: 
      files: "index.html":"resources/custom/components/base.html"

Ini terlihat pada semua file di base.html dan menghisapnya untuk membuat index.html berfungsi luar biasa untuk aplikasi multi halaman (phonegap). Ini memungkinkan pengembangan yang lebih mudah karena semua pengembang tidak bekerja pada satu aplikasi halaman tunggal yang panjang (mencegah banyak checkin konflik). Sebagai gantinya Anda dapat memecah halaman dan bekerja pada potongan kode yang lebih kecil dan kompilasi ke halaman penuh menggunakan perintah arloji.

Bake membaca templat dari base.html dan menyuntikkan halaman html komponen pada jam tangan.

<!DOCTYPE html>

jQuery Mobile Demo

app.initialize ();

<body>
    <!--(bake /resources/custom/components/page1.html)-->
    <!--(bake /resources/custom/components/page2.html)-->
    <!--(bake /resources/custom/components/page3.html)-->
</body>

Anda dapat mengambil langkah ini lebih jauh dan menambahkan suntikan di halaman Anda untuk "menu" "popup" dll sehingga Anda benar-benar dapat memecah halaman menjadi komponen yang lebih kecil yang dapat dikelola.


Mungkin Anda dapat meningkatkan jawaban Anda dengan demo kode yang menggunakan grunt-bake?
Dmitry Pashkevich

4

Gunakan kombinasi wiredep https://github.com/taptapship/wiredep dan usemin https://github.com/yeoman/grunt-usemin untuk meminta bantuan tugas-tugas ini. Wiredep akan menambahkan dependensi Anda satu file skrip pada satu waktu, dan usemin akan menggabungkan semuanya menjadi satu file untuk produksi. Ini kemudian dapat dicapai hanya dengan beberapa komentar html. Misalnya, paket bower saya secara otomatis disertakan dan ditambahkan ke html ketika saya menjalankan bower install && grunt bowerInstall:

<!-- build:js /scripts/vendor.js -->
<!-- bower:js -->
<!-- endbower -->
<!-- endbuild -->

2

Jawaban ini bukan untuk noobs!

Gunakan Jade templating ... meneruskan variabel ke templat Jade adalah case use standar rawa

Saya menggunakan grunt (grunt-contrib-jade) tetapi Anda tidak harus menggunakan grunt. Cukup gunakan modul giok npm standar.

Jika menggunakan grunt maka gruntfile Anda akan menyukai sesuatu seperti ...

jade: {
    options: {
      // TODO - Define options here
    },
    dev: {
      options: {
        data: {
          pageTitle: '<%= grunt.file.name %>',
          homePage: '/app',
          liveReloadServer: liveReloadServer,
          cssGruntClassesForHtmlHead: 'grunt-' + '<%= grunt.task.current.target %>'
        },
        pretty: true
      },
      files: [
        {
          expand: true,
          cwd: "src/app",
          src: ["index.jade", "404.jade"],
          dest: "lib/app",
          ext: ".html"
        },
        {
          expand: true,
          flatten: true,
          cwd: "src/app",
          src: ["directives/partials/*.jade"],
          dest: "lib/app/directives/partials",
          ext: ".html"
        }
      ]
    }
  },

Kita sekarang dapat dengan mudah mengakses data yang dilewati oleh gerutuan di template Jade.

Sama seperti pendekatan yang digunakan oleh Modernizr, saya menetapkan kelas CSS pada tag HTML sesuai dengan nilai variabel yang diteruskan dan dapat menggunakan logika JavaScript dari sana berdasarkan pada apakah kelas CSS ada atau tidak.

Ini bagus jika menggunakan Angular karena Anda dapat melakukan ng-jika untuk memasukkan elemen dalam halaman berdasarkan pada apakah kelas ada.

Sebagai contoh, saya dapat menyertakan skrip jika kelas hadir ...

(Misalnya, saya dapat memasukkan skrip isi ulang langsung di dev tetapi tidak dalam produksi)

<script ng-if="controller.isClassPresent()" src="//localhost:35729/livereload.js"></script> 

2

Pertimbangkan processhtml . Ini memungkinkan definisi beberapa "target" untuk bangunan. Komentar digunakan untuk memasukkan atau mengecualikan materi dari HTML:

<!-- build:js:production js/app.js -->
...
<!-- /build -->

menjadi

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

Ia bahkan bermaksud melakukan hal-hal bagus seperti ini (lihat README ):

<!-- build:[class]:dist production -->
<html class="debug_mode">
<!-- /build -->

<!-- class is changed to 'production' only when the 'dist' build is executed -->
<html class="production">
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.