วิธีเชื่อมต่อและลดขนาดไฟล์ CSS และ JavaScript หลายไฟล์ด้วย Grunt.js (0.3.x)


99

หมายเหตุ: คำถามนี้เกี่ยวข้องกับ Grunt 0.3.x เท่านั้นและถูกทิ้งไว้ให้อ้างอิง สำหรับความช่วยเหลือเกี่ยวกับ Grunt 1.x รุ่นล่าสุดโปรดดูความคิดเห็นของฉันด้านล่างคำถามนี้

ฉันกำลังพยายามใช้ Grunt.js เพื่อตั้งค่ากระบวนการสร้างอัตโนมัติสำหรับการเชื่อมต่อครั้งแรกจากนั้นจึงลดขนาดไฟล์ CSS และ JavaScript

ฉันสามารถเชื่อมต่อและย่อขนาดไฟล์ JavaScript ของฉันได้สำเร็จแม้ว่าทุกครั้งที่ฉันเรียกใช้คำรามดูเหมือนว่าจะต่อท้ายไฟล์แทนที่จะเขียนทับ

สำหรับการย่อขนาดหรือแม้แต่การเชื่อมต่อ CSS ฉันยังไม่สามารถดำเนินการได้ในตอนนี้!

ในแง่ของโมดูล CSS แสมผมได้ลองใช้consolidate-css, grunt-cssและcssminแต่จะไม่มีประโยชน์ ไม่สามารถเข้าใจวิธีการใช้งานได้!

โครงสร้างไดเร็กทอรีของฉันเป็นดังนี้ (เป็นแอ็พพลิเคชัน node.js ทั่วไป):

  • app.js
  • คำราม js
  • /public/index.html
  • / public / css / [ไฟล์ css ต่างๆ]
  • / public / js / [ไฟล์ javascript ต่างๆ]

นี่คือลักษณะของไฟล์ grunt.js ของฉันในโฟลเดอร์รูทของแอปพลิเคชันของฉัน:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: '<json:package.json>',
    concat: {
      dist: {
        src: 'public/js/*.js',
        dest: 'public/js/concat.js'
      }
    },
    min: {
      dist: {
        src: 'public/js/concat.js',
        dest: 'public/js/concat.min.js'
      }
    },
    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        node: true
      },
      globals: {
        exports: true,
        module: false
      }
    },
    uglify: {}
  });

  // Default task.
  grunt.registerTask('default', 'concat min');

};

เพื่อสรุปว่าฉันต้องการความช่วยเหลือด้วยคำถามสองข้อ:

  1. วิธีการต่อและย่อขนาดไฟล์ css ทั้งหมดของฉันภายใต้โฟลเดอร์/public/css/ให้เป็นไฟล์เดียวพูดmain.min.css
  2. เหตุใด grunt.js จึงยังคงต่อท้ายกับไฟล์จาวาสคริปต์ที่ต่อและย่อขนาดconcat.jsและconcat.min.jsอยู่ภายใต้/public/js/แทนที่จะเขียนทับไฟล์เหล่านี้ทุกครั้งที่gruntเรียกใช้คำสั่ง

อัปเดตเมื่อวันที่ 5 กรกฎาคม 2016 - การอัปเกรดจาก Grunt 0.3.x เป็น Grunt 0.4.x หรือ 1.x

Grunt.jsได้ย้ายไปยังโครงสร้างใหม่ในGrunt 0.4.x(เรียกไฟล์นี้แล้วGruntfile.js) โปรดดูโครงการที่มาของฉันเปิดGrunt.js โครงกระดูกGrunt 1.xความช่วยเหลือเกี่ยวกับการตั้งค่าการสร้างกระบวนการสำหรับ

การย้ายจากGrunt 0.4.xไปยังGrunt 1.x ไม่ควรทำให้เกิดการเปลี่ยนแปลงที่สำคัญมากมาย

คำตอบ:


108

concat.js จะถูกรวมอยู่ในงานของไฟล์ที่มาconcat public/js/*.jsคุณสามารถมีงานที่ลบconcat.js(ถ้ามีไฟล์อยู่) ก่อนที่จะเชื่อมต่ออีกครั้งส่งอาร์เรย์เพื่อกำหนดไฟล์ที่คุณต้องการเชื่อมต่อและลำดับของไฟล์อย่างชัดเจนหรือเปลี่ยนโครงสร้างของโปรเจ็กต์ของคุณ

หากทำอย่างหลังคุณสามารถใส่แหล่งที่มาทั้งหมดไว้ข้างใต้./srcและไฟล์ที่สร้างไว้ข้างใต้./dest

src
├── css
│   ├── 1.css
│   ├── 2.css
│   └── 3.css
└── js
    ├── 1.js
    ├── 2.js
    └── 3.js

จากนั้นตั้งค่างานconcatของคุณ

concat: {
  js: {
    src: 'src/js/*.js',
    dest: 'dest/js/concat.js'
  },
  css: {
    src: 'src/css/*.css',
    dest: 'dest/css/concat.css'
  }
},

งานขั้นต่ำของคุณ

min: {
  js: {
    src: 'dest/js/concat.js',
    dest: 'dest/js/concat.min.js'
  }
},

งานขั้นต่ำในตัวใช้ UglifyJS ดังนั้นคุณต้องมีการเปลี่ยน ฉันพบว่าgrunt-cssนั้นค่อนข้างดี หลังจากติดตั้งแล้วให้โหลดลงในไฟล์ฮึดฮัดของคุณ

grunt.loadNpmTasks('grunt-css');

แล้วตั้งค่า

cssmin: {
  css:{
    src: 'dest/css/concat.css',
    dest: 'dest/css/concat.min.css'
  }
}

สังเกตว่าการใช้งานจะคล้ายกับ min ในตัว

เปลี่ยนdefaultงานของคุณเป็น

grunt.registerTask('default', 'concat min cssmin');

ตอนนี้การวิ่งgruntจะให้ผลลัพธ์ที่คุณต้องการ

dest
├── css
│   ├── concat.css
│   └── concat.min.css
└── js
    ├── concat.js
    └── concat.min.js

1
คุณคืออัจฉริยะ! มันไม่เคยเกิดขึ้นกับฉันแน่นอนถ้าฉันรวมไว้concatในjsโฟลเดอร์เดียวกันกับที่มันจะตักขึ้นมาและต่อท้าย! ฉันได้เริ่มใช้ cssmin และใช้งานได้ดีมาก! ขอบคุณอีกครั้ง.
Jasdeep Khalsa

1
เยี่ยมมากเยี่ยมจริงๆ! แต่ชื่อไฟล์จะอยู่เสมอconcat.min.cssและconcat.min.js. ถ้าฉันแก้ไขบางอย่างรีรันและปรับใช้คนอื่นจะไม่ได้รับเวอร์ชันล่าสุดเนื่องจากเบราว์เซอร์แคชไว้แล้ว มีวิธีการสุ่มชื่อไฟล์และเชื่อมโยงพวกเขาตามที่เหมาะสมในบางส่วน<link>และ<script>แท็ก?
Tárcio Zemel

3
@ TárcioZemelคุณสามารถรวมเวอร์ชันของ package.json ไว้ในชื่อไฟล์:concat.min-<%= pkg.version %>.js
Rui Nunes

1
คุณสามารถใช้.destแบบนี้ได้cssmin: { css:{ src: '<%= concat.css.dest %>', dest: './css/all.min.css'}} `เป็นผลมาจากการดำเนินการconcat -> css
Ivan Black

12

ฉันอยากจะพูดถึงที่นี่เป็นเทคนิคที่น่าสนใจมากที่ใช้ในโครงการขนาดใหญ่เช่น jQuery และ Modernizr สำหรับสิ่งที่เชื่อมต่อกัน

ทั้งสองโครงการนี้ได้รับการพัฒนาโดยใช้โมดูล requirejs ทั้งหมด (คุณจะเห็นว่าใน github repos ของพวกเขา) จากนั้นก็ใช้เครื่องมือเพิ่มประสิทธิภาพ requirejs เป็นตัวเชื่อมต่อที่ชาญฉลาด สิ่งที่น่าสนใจคืออย่างที่คุณเห็นหรือ jQuery ก็ไม่จำเป็นต้องใช้ Modernizr ในการทำงานและสิ่งนี้เกิดขึ้นเนื่องจากพวกเขาลบพิธีกรรมทางไวยากรณ์ของ requirejs เพื่อกำจัด requirejs ในรหัสของพวกเขา ดังนั้นพวกเขาจึงลงเอยด้วยไลบรารีแบบสแตนด์อโลนที่พัฒนาด้วยโมดูล requirejs! ด้วยเหตุนี้พวกเขาจึงสามารถสร้างไลบรารีของพวกเขาในรูปแบบ cutom ท่ามกลางข้อดีอื่น ๆ

สำหรับผู้ที่สนใจในการเชื่อมต่อกับเครื่องมือเพิ่มประสิทธิภาพ requirejs โปรดดูโพสต์นี้

นอกจากนี้ยังมีเครื่องมือขนาดเล็กที่แยกองค์ประกอบต้นแบบทั้งหมดของกระบวนการ: AlbanilJS


สิ่งนี้น่าสนใจมาก แต่ไม่เกี่ยวข้องกับคำถามเนื่องจาก RequireJS เป็นตัวโหลดโมดูลจึงไม่เชื่อมต่อหรือลดขนาด AFAIK
Jasdeep Khalsa

ขอบคุณ! คุณพูดถูก RequireJS เป็นตัวโหลดโมดูลและไม่เชื่อมต่อหรือย่อขนาด แต่ r.js (เครื่องมือเพิ่มประสิทธิภาพ RequireJS -> requirejs.org/docs/optimization.html ) ทำ โดยเฉพาะอย่างยิ่งมันเชื่อมต่อโมดูลของคุณโดยเรียงลำดับตามการอ้างอิง พวกจาก Modernizr และ jQuery ใช้ประโยชน์จากอัลกอริทึมการสั่งซื้อของเครื่องมือและใช้เป็นตัวเชื่อมต่ออัจฉริยะโดยเฉพาะ คุณสามารถตรวจสอบ repos ของพวกเขาเพื่อดูว่าพวกเขากำลังทำอะไรอยู่
Augusto Altman Quaranta

การใช้ concat หรือ uglify ของ grunt ไฟล์ผลลัพธ์จะถูกสร้างขึ้นโดยใช้ลำดับจากไฟล์ต้นฉบับที่กำหนดค่าไว้ ในขณะที่ RequireJS ขึ้นอยู่กับการพึ่งพา แนวทางที่แตกต่างกัน แต่สามารถบรรลุผลลัพธ์เดียวกันได้
priyabagus

10

ฉันเห็นด้วยกับคำตอบข้างต้น แต่นี่เป็นอีกวิธีหนึ่งในการบีบอัด CSS

คุณสามารถเชื่อมต่อ CSS ของคุณโดยใช้คอมเพรสเซอร์ YUI :

module.exports = function(grunt) {
  var exec = require('child_process').exec;
   grunt.registerTask('cssmin', function() {
    var cmd = 'java -jar -Xss2048k '
      + __dirname + '/../yuicompressor-2.4.7.jar --type css '
      + grunt.template.process('/css/style.css') + ' -o '
      + grunt.template.process('/css/style.min.css')
    exec(cmd, function(err, stdout, stderr) {
      if(err) throw err;
    });
  });
}; 

ในกรณีที่คุณใช้ 'grunt-css' คุณต้องใช้โมดูล Locale Npm ดังนั้นตรวจสอบให้แน่ใจว่าเมื่อคุณกำลังติดตั้ง 'grunt-css' ในต้องอยู่ในโมดูล Locale Npm
Anshul

7
ทำไมคุณถึงต้องการสร้างความซับซ้อนทั้งหมดนี้และเรียก jvm ในกระบวนการสร้างของคุณ เพียงแค่ทำให้ทุกอย่างช้าลงโดยไม่มีเหตุผล
michael salmon

3

คุณไม่จำเป็นต้องเพิ่มแพ็คเกจ concat คุณสามารถทำได้ผ่าน cssmin ดังนี้:

cssmin : {
      options: {
            keepSpecialComments: 0
      },
      minify : {
            expand : true,
            cwd : '/library/css',
            src : ['*.css', '!*.min.css'],
            dest : '/library/css',
            ext : '.min.css'
      },
      combine : {
        files: {
            '/library/css/app.combined.min.css': ['/library/css/main.min.css', '/library/css/font-awesome.min.css']
        }
      }
    }

และสำหรับ js ให้ใช้ uglify ดังนี้:

uglify: {
      my_target: {
        files: {
            '/library/js/app.combined.min.js' : ['/app.js', '/controllers/*.js']
        }
      }
    }

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.