2013-05-28 31 views
38

Tôi mới đến Grunt, và cho đến nay tôi rất thích nó. Tôi muốn Grunt chỉ biên dịch các tệp đã thay đổi khi chạy grunt watchGrunt: Xem nhiều tập tin, biên dịch chỉ thay đổi

Trong Grunfile.coffee tôi hiện có (các phần liên quan).
Lưu ý: tài sản/javascript/app.coffee và tài sản/javascript/app.js là thư mục

coffee: 
     default: 
      expand: true 
      cwd: "assets/javascript/app.coffee" 
      src: ["*.coffee"] 
      dest: "assets/javascript/app.js" 
      ext: ".js" 

    uglify: 
     dev: 
      options: 
       beautify: true 
       compress: false 
       mangle: false 
       preserveComments: 'all' 

      files: 
       "js/app.js": "assets/javascript/app.js/*.js" 
       "js/libs.js": "assets/javascript/libs/*.js" 

    watch: 
     coffeescript: 
      files: 'assets/javascript/**/*.coffee' 
      tasks: ["coffee"] 

     javascript: 
      files: "assets/**/*.js" 
      tasks: ["uglify:dev"] 
     livereload: 
      files: ["Gruntfile.coffee", "js/*.js", "*.php", "css/*.css", "images/**/*.{png,jpg,jpeg,gif,webp,svg}", "js/*.js", ] 
      options: 
       livereload: true 

Có lẽ là một cách ngắn hơn xung quanh, nhưng tôi đang biên soạn app.coffee để app.js đầu tiên, để sau khi tôi phân phối tác phẩm của mình, những người không thoải mái với Coffeescript có thể duyệt mã theo cách hơi hợp lý.

Vấn đề với tất cả điều này là bây giờ mà tôi lưu một tập tin Coffeescript, tôi nhận được quá nhiều bước (tôi nghĩ):

>> File "assets/javascript/app.coffee/browse.coffee" changed. 

Running "coffee:default" (coffee) task 
File assets/javascript/app.js/browse.js created. 
File assets/javascript/app.js/filters.js created. 

Done, without errors. 
Completed in 0.837s at Tue May 28 2013 12:30:18 GMT+0300 (EEST) - Waiting... 
OK 
>> File "assets/javascript/app.js/browse.js" changed. 
>> File "assets/javascript/app.js/filters.js" changed. 

Running "uglify:dev" (uglify) task 
File "js/app.js" created. 
File "js/libs.js" created. 

Done, without errors. 
Completed in 0.831s at Tue May 28 2013 12:30:19 GMT+0300 (EEST) - Waiting... 
OK 
>> File "js/app.js" changed. 
>> File "js/libs.js" changed. 

Completed in 0.000s at Tue May 28 2013 12:30:19 GMT+0300 (EEST) - Waiting... 

Hiện nay tôi chỉ lập dự án của tôi, nhưng tôi sẽ có nhiều tệp Coffeescript hơn và tôi không muốn Coffeescript biên dịch lại tất cả các tệp, trên mỗi tệp thay đổi.

Hơn nữa, libs.js không có phần nào trong tất cả điều này, nhưng tôi đoán nó vẫn được biên dịch, vì nó cũng khớp với mẫu "assets/* / .js".

Có cách nào để biến Grunt chỉ biên dịch các tệp đã thay đổi không?

+1

bản sao có thể có của [Làm thế nào để bạn xem nhiều tệp, nhưng chỉ chạy tác vụ trên tệp đã thay đổi, trong Grunt.js?] (Http://stackoverflow.com/questions/12063266/how-do-you-watch- nhiều tập tin-nhưng-chỉ-chạy-tác vụ-trên-thay-tập-trong-grunt-js) –

Trả lời

69

cuối cùng tôi đã tìm thấy một giải pháp thực tế! Và nó cũng siêu đơn giản!

npm install grunt-newer --save-dev

Sau đó, trong Gruntfile của bạn (sau khi tải nhiệm vụ trong grunt):

watch: 
    coffeescript: 
     files: 'assets/javascript/**/*.coffee' 
     tasks: ["newer:coffee"] 

Và đó là nó! The Awesome grunt-newer is awesome!

+1

Đẹp - đó chính xác là những gì tôi cần! Tôi thậm chí không cần đọc bất kỳ tài liệu hoặc hướng dẫn nào - nó chỉ hoạt động. –

+0

Yay! hoàn hảo! cảm ơn vì viên ngọc này :) – flks

+0

Thật tuyệt vời^_^ –

2

Nếu bạn concat tất cả các nguồn .coffee thành một tệp .js, thì bạn sẽ phải biên dịch lại mỗi khi có bất kỳ nguồn nào của bạn thay đổi. Chia nhỏ nó thành nhiều tệp .js và tạo một tác vụ phát hành nơi bạn chỉ concat các tệp .js này. Bằng cách này bạn vẫn chỉ cần bao gồm một tệp .js.

Xem Using gruntjs, how do watch for changes in .coffee files?

+0

Xem đó là điều. Tôi biên dịch từng tệp Coffeescript thành một tệp JavaScript riêng biệt, do đó trình biên dịch không thực sự chạm vào tệp coffeescript khác. Các tệp Javascript sau đó được nối vào app.js, nhưng đó là một nhiệm vụ riêng biệt, cũng vô tình gọi nén của libs.js, cũng không cần thiết. – Norris

+0

Sau đó, chỉ cần loại trừ lib.js khỏi đồng hồ với "! Js/libs.js". Có thể bạn có thể viết [Bộ lọc tùy chỉnh] của riêng mình (http://gruntjs.com/configuring-tasks#custom-filter-function) hoặc yêu cầu [tính năng tương tự] (https://github.com/gruntjs/grunt- contrib-copy/pull/56). – Jamesgt

+0

Đây thực sự là giải pháp hợp lý nhất, gắn bó với nó cho đến khi tôi tìm thấy một cái gì đó tốt hơn ... – Norris

1

Sự kiện grunt.event.on phát hiện những thay đổi trong các tập tin, tiếp nhận một tham số actionfilepath.

Đây là một ví dụ chưa được kiểm tra dựa trên một trong các gruntfiles của tôi. Trong trường hợp này, tất cả các file coffeescript nguồn của tôi được lưu giữ trong một thư mục gọi nguồn khác nhau, và cho xem trước họ được biên soạn và lưu vào một cấu trúc thư mục giống hệt nhau dưới một thư mục gọi là dev

SOURCES_DIR = 'sources' 
DEV_DIR = 'dev' 

grunt.initConfig 
    watch : 
    all : 
     files : ["**/*.coffee"] 
    coffee : 
    dev : 
     files : 
     dest : "app.js" 
grunt.loadNpmTasks 'grunt-contrib-watch' 
grunt.loadNpmTasks 'grunt-contrib-coffee' 

grunt.registerTask 'build', ['coffee:dev'] 

grunt.event.on('watch', (action,filepath) -> 
    # Determine the full directory of the changed file 
    wdi = filepath.lastIndexOf '/' 
    wd = filepath.substring 0,wdi 

    # remove `sources` prefix from that directory 
    fpath = wd.replace(SOURCES_DIR,'') + '/' 

    # determine the filename 
    fnamei = filepath.lastIndexOf '.' 
    fname = filepath.substring wdi+1,fnamei # NOTE: this breaks the case where in same dir 

    # concatenate fpath and fname with the dir to be compiled into 
    deststr = "#{DEV_DIR}#{fpath}#{fname}.coffee" 


    # set coffee.dev.files value in the coffee task to have am entry of form {"destination":"source"} 
    obj = {} 
    obj[deststr] = filepath 
    grunt.config "coffee.dev.files", obj 

    # fire the coffee task 
    grunt.task.run "coffee" 
) 

Hy vọng rằng sẽ giúp.

EDIT: Có lẽ không chính xác những gì bạn muốn - bởi vì không nghi ngờ bạn muốn truy cập vào các biến trung gian, hành động và vv - nhưng bạn có thể sử dụng lệnh grunt để chạy lệnh shell coffee. Nhiệm vụ grunt-shell NPM thực hiện điều này, ví dụ

EDIT2: tôi đã phải đối mặt với vấn đề với tiếp tục grunt.watch.on không làm việc liên tục trong grunt 0.4.1 trên OSX 10.8 và MacVim 7,3; vì lý do gì, nó dừng xem. Tôi đã quay trở lại chỉ bằng cách sử dụng đối tượng initConfig cơ bản grunt nhưng với độ chi tiết hơn để nó chỉ xem và biên dịch các nhóm tệp tương đối nhỏ hơn là toàn bộ rất nhiều. Điều này làm chậm thời gian xây dựng đáng kể, nhưng nó mạnh mẽ hơn nhiều. Mileage của bạn có thể rất.

+0

Cảm ơn, điều này thực sự trông giống như một cái gì đó tôi đang tìm kiếm. Tôi sẽ xem xét kỹ hơn sau này. – Norris

0

Tôi cũng đã tình cờ gặp điều này và không tìm thấy bất kỳ phiên bản hoạt động nào đã làm việc với phiên bản hiện tại (0.4.1) Nhưng câu trả lời của Jof Arnolds cho thấy một cách tiếp cận tốt.

Đây là những gì tôi đã đưa ra:

# only recompile changed files 
grunt.event.on "watch", (action, filepath) -> 
    # note that we have to manually change the target file name to 
    # our desired format 
    targetName = filepath.replace(/\/(client|shared)/, "") 
    .replace(".coffee", ".js") 
    .replace("app/", "") 

    options = 
    src: filepath 
    dest: "public/javascripts/#{targetName}" 

    grunt.config ["coffee", "client"], options 

Tôi có một phần cà phê trông hơi như thế này:

coffee: 
    client: 
    options: 
     sourceMap: false 
    files: [ 
     expand: true 
     cwd: "app" 
     src: ["*/client/**/*.coffee", "helpers/{client,shared}/*.coffee"] 
     dest: "public/javascripts" 
     rename: (folder, name) -> 
     name = name.replace(/\/(client|shared)/, "") 

     [folder, name].join path.sep 
     ext: ".js" 
    ] 
Các vấn đề liên quan