Grunt - Hướng dẫn nhanh
Grunt là gì?
Grunt là một Trình chạy Tác vụ JavaScript có thể được sử dụng như một công cụ dòng lệnh cho các đối tượng JavaScript. Nó là một trình quản lý tác vụ được viết trên NodeJS.
Tại sao sử dụng Grunt?
Grunt có thể thực hiện các tác vụ lặp đi lặp lại rất dễ dàng, chẳng hạn như biên dịch, kiểm tra đơn vị, thu nhỏ tệp, chạy thử nghiệm, v.v.
Grunt bao gồm các tác vụ tích hợp để mở rộng chức năng của các plugin và tập lệnh của bạn.
Hệ sinh thái của Grunt rất lớn; bạn có thể tự động hóa mọi thứ với rất ít nỗ lực.
Lịch sử
Các dòng mã nguồn đầu tiên được thêm vào GruntJS vào năm 2011. Grunt v0.4 được phát hành vào ngày 18 tháng 2 năm 2013. Grunt v0.4.5 được phát hành vào ngày 12 tháng 5 năm 2014. Phiên bản ổn định của Grunt là 1.0.0 rc1. được phát hành vào ngày 11 tháng 2 năm 2016.
Ưu điểm
Sử dụng Grunt, bạn có thể thực hiện việc thu nhỏ, biên dịch và kiểm tra tệp một cách dễ dàng.
Grunt thống nhất quy trình làm việc của các nhà phát triển web.
Bạn có thể dễ dàng làm việc với một codebase mới bằng Grunt vì nó chứa ít cơ sở hạ tầng hơn.
Nó tăng tốc quy trình phát triển và nâng cao hiệu suất của các dự án.
Nhược điểm
Bất cứ khi nào npm các gói được cập nhật, bạn cần đợi cho đến khi tác giả của Grunt cập nhật nó.
Mỗi nhiệm vụ được thiết kế để thực hiện một công việc cụ thể. Nếu bạn muốn mở rộng một nhiệm vụ cụ thể, thì bạn cần sử dụng một số thủ thuật để hoàn thành công việc.
Grunt bao gồm một số lượng lớn các thông số cấu hình cho các plugin riêng lẻ. Thông thường, các tệp cấu hình Grunt có độ dài dài hơn.
Grunt là một trình chạy tác vụ dựa trên JavaScript, có nghĩa là nó có thể tự động hóa các tác vụ lặp đi lặp lại trong quy trình làm việc và nó có thể được sử dụng như một công cụ dòng lệnh cho các đối tượng JavaScript.
Một số tính năng nổi bật nhất của GruntJS được liệt kê dưới đây:
Grunt làm cho quy trình làm việc dễ dàng như viết một tệp thiết lập.
Bạn có thể tự động hóa các công việc lặp đi lặp lại với nỗ lực tối thiểu.
Grunt là một task runner phổ biến dựa trên NodeJS. Nó linh hoạt và được áp dụng rộng rãi.
Nó có một cách tiếp cận đơn giản bao gồm các tác vụ trong JS và cấu hình trong JSON.
Grunt thu nhỏ các tệp JavaScript, CSS, tệp thử nghiệm, biên dịch tệp tiền xử lý CSS (SASS, LESS), v.v.
Grunt bao gồm các tác vụ tích hợp để mở rộng chức năng của các plugin và tập lệnh của bạn.
Nó tăng tốc quy trình phát triển và nâng cao hiệu suất của các dự án.
Bạn có thể dễ dàng làm việc với một codebase mới bằng Grunt vì nó chứa ít cơ sở hạ tầng hơn.
Hệ sinh thái của Grunt rất lớn; bạn có thể tự động hóa mọi thứ với rất ít nỗ lực.
Grunt giảm nguy cơ mắc lỗi khi thực hiện các nhiệm vụ lặp đi lặp lại.
Grunt hiện có hơn 4000 plugin.
Nó có thể được sử dụng trong các địa điểm sản xuất lớn.
Chương này cung cấp quy trình từng bước về cách cài đặt Grunt trên hệ thống của bạn.
Yêu cầu hệ thống đối với Grunt
Operating System - Đa nền tảng
Browser Support - IE (Internet Explorer 8+), Firefox, Google Chrome, Safari, Opera
Cài đặt Grunt
Step 1- Chúng tôi cần NodeJs để chạy Grunt. Để tải xuống NodeJs, hãy mở liên kếthttps://nodejs.org/en/, bạn sẽ thấy một màn hình như hình dưới đây -
Tải xuống phiên bản Tính năng mới nhất của tệp zip.
Step 2- Tiếp theo, chạy thiết lập để cài đặt NodeJs trên máy tính của bạn.
Step 3- Tiếp theo, bạn cần thiết lập các biến môi trường .
Path User Variable
- Nhấp chuột phải vào My Computer.
- Lựa chọn Properties.
- Tiếp theo, chọn Advanced tab và nhấp vào Environment Variables.
Trong cửa sổ Biến môi trường , nhấp đúp vào PATH như hiển thị trong màn hình.
Bạn sẽ nhận được một cửa sổ Chỉnh sửa biến người dùng như được hiển thị. Thêm đường dẫn thư mục NodeJs trong trường Giá trị biến dưới dạng C: \ Program Files \ nodejs \ node_modules \ npm . Nếu đường dẫn đã được đặt sẵn cho các tệp khác, thì bạn cần đặt dấu chấm phẩy (;) sau đó và thêm đường dẫn NodeJs như hình dưới đây:
Ở cuối, nhấp vào nút OK .
System Variable
Trong Biến hệ thống , nhấp đúp vào Đường dẫn như hiển thị trong màn hình sau.
Bạn sẽ nhận được một cửa sổ Chỉnh sửa Biến Hệ thống như được hiển thị. Thêm đường dẫn thư mục NodeJs trong trường Giá trị biến dưới dạng C: \ Program Files \ nodejs \ và nhấp vào OK như hình dưới đây -
Step 4 - Để cài đặt grunt trên hệ thống của bạn, bạn cần cài đặt giao diện dòng lệnh (CLI) của Grunt trên toàn cầu như hình dưới đây -
npm install -g grunt-cli
Chạy lệnh trên sẽ đặt lệnh grunt vào đường dẫn hệ thống của bạn, điều này làm cho nó chạy từ bất kỳ thư mục nào.
Cài đặt grunt-cli không cài đặt trình chạy tác vụ Grunt. Vai trò của grunt-cli là chạy phiên bản Grunt đã được cài đặt bên cạnh Gruntfile . Nó cho phép một máy cài đặt nhiều phiên bản Grunt đồng thời.
Step 5 - Bây giờ, chúng ta sẽ tạo configuration files để chạy Grunt.
package.json
Tệp package.json được đặt trong thư mục gốc của dự án, bên cạnh Gruntfile . Các package.json được sử dụng để chạy một cách chính xác từng phụ thuộc được liệt kê bất cứ khi nào bạn chạy lệnhnpm install trong cùng một thư mục với package.json.
Bạn có thể tạo package.json cơ bản bằng cách gõ lệnh sau vào dấu nhắc lệnh:
npm init
Tệp package.json cơ bản sẽ như hình dưới đây:
{
"name": "tutorialspoint",
"version": "0.1.0",
"devDependencies": {
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0"
}
}
Bạn có thể thêm Grunt và gruntplugins vào tệp pacakge.json hiện có thông qua lệnh sau:
npm install <module> --save-dev
Trong lệnh trên, <module> đại diện cho mô-đun được cài đặt cục bộ. Lệnh trên cũng sẽ tự động thêm <module> vào devDependencies .
Ví dụ: lệnh sau sẽ cài đặt phiên bản mới nhất của Grunt và thêm nó vào devDependencies của bạn -
npm install grunt --save-dev
Gruntfile.js
Tệp Gruntfile.js được sử dụng để xác định cấu hình của chúng tôi cho Grunt. Nó là nơi mà cài đặt của chúng tôi sẽ được viết. Tệp Gruntfile.js cơ bản như hình dưới đây:
// our wrapper function (required by grunt and its plugins)
// all configuration goes inside this function
module.exports = function(grunt) {
// CONFIGURE GRUNT
grunt.initConfig({
// get the configuration info from package.json file
// this way we can use things like name and version (pkg.name)
pkg: grunt.file.readJSON('package.json'),
// all of our configuration goes here
uglify: {
// uglify task configuration
options: {},
build: {}
}
});
// log something
grunt.log.write('Hello world! Welcome to Tutorialspoint!!\n');
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s).
grunt.registerTask('default', ['uglify']);
};
Để sử dụng Grunt, bạn cần cài đặt Node.js. Việc cài đặt Node.js đã được giải thích trong chương trước . Bạn có thể cài đặt các plugin Grunt và Grunt bằng cách sử dụng trình quản lý gói Node.js.
Trước khi thiết lập Grunt trên hệ thống, bạn có thể cập nhật trình quản lý gói Node bằng cách sử dụng lệnh sau:
npm update -g npm
Nếu bạn đang sử dụng Mac hoặc Linux, bạn cần sử dụng sudo word ở đầu dòng lệnh để cấp quyền truy cập quản trị viên như hình dưới đây:
sudo npm update -g npm
Cài đặt CLI
CLI là viết tắt của Command Line Interface chạy phiên bản Grunt đã được cài đặt. Để bắt đầu với Grunt, bạn cần cài đặt giao diện dòng lệnh (CLI) của Grunt trên toàn cầu như hình dưới đây:
npm install -g grunt-cli
Chạy lệnh trên sẽ đặt lệnh grunt vào đường dẫn hệ thống của bạn, điều này làm cho nó chạy từ bất kỳ thư mục nào. Bạn không thể cài đặt Grunt task runner bằng cách cài đặt grunt-cli . Nó cho phép một máy cài đặt nhiều phiên bản Grunt đồng thời.
Hoạt động của CLI
CLI tìm kiếm Grunt đã cài đặt trên hệ thống của bạn bằng cách sử dụng hệ thống request () bất cứ khi nào Grunt được chạy. Sử dụng grunt-cli , bạn có thể chạy Grunt từ bất kỳ thư mục nào trong dự án của mình. Nếu bạn đang sử dụng Grunt được cài đặt cục bộ, thì grunt-cli sử dụng thư viện Grunt được cài đặt cục bộ và áp dụng cấu hình từ tệp Grunt.
Làm việc với một dự án hiện tại và mới
Nếu bạn đang làm việc với một dự án đã được định cấu hình bao gồm package.json và Gruntfile , hãy làm theo các bước đơn giản như được chỉ định bên dưới:
- Tìm đường dẫn đến thư mục gốc của dự án.
- Bạn có thể cài đặt các phần phụ thuộc bằng lệnh npm install .
- Chạy Grunt bằng lệnh grunt .
Nếu bạn đang tạo một dự án mới, hãy đưa hai tệp package.json và Gruntfile vào dự án của bạn.
package.json- Tệp package.json được đặt trong thư mục gốc của dự án và nó được sử dụng để chạy từng phần phụ thuộc được liệt kê bất cứ khi nào bạn chạy lệnh npm install trong cùng một thư mục.
Gruntfile.js - Tập tin Gruntfile.js dùng để ghi các thiết lập cấu hình cho dự án.
package.json
Tệp package.json được đặt trong thư mục gốc của dự án, bên cạnh Gruntfile và được sử dụng để chạy từng phần phụ thuộc được liệt kê bất cứ khi nào bạn chạy lệnh npm install trong cùng một thư mục.
Bạn có thể tạo package.json theo nhiều cách khác nhau như được liệt kê bên dưới:
- Bạn có thể grunt-init để tạo tệp package.json.
- Bạn cũng có thể tạo tệp package.json bằng cách sử dụng lệnh npm-init .
Bạn có thể viết thông số kỹ thuật như hình dưới đây -
{
"name": "tutorialspoint",
"version": "0.1.0",
"devDependencies": {
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0"
}
}
Bạn có thể thêm Grunt và gruntplugins vào tệp pacakge.json hiện có bằng cách sử dụng lệnh sau:
npm install <module> --save-dev
Ở đây, <module> đại diện cho mô-đun được cài đặt cục bộ. Lệnh trên sẽ cài đặt mô-đun được chỉ định và tự động thêm nó vào phần devDependencies .
Ví dụ: lệnh sau sẽ cài đặt phiên bản mới nhất của Grunt và thêm nó vào devDependencies của bạn -
npm install grunt --save-dev
Gruntfile
Tệp Gruntfile.js là nơi mặc định để cài đặt cấu hình của bạn cho Grunt. Tệp Grunt bao gồm các phần sau:
- Hàm wrapper
- Cấu hình dự án và nhiệm vụ
- Đang tải các tác vụ và plugin Grunt
- Nhiệm vụ tùy chỉnh
Tệp Gruntfile.js cơ bản như hình dưới đây:
// our wrapper function (required by grunt and its plugins)
// all configuration goes inside this function
module.exports = function(grunt) {
// CONFIGURE GRUNT
grunt.initConfig({
// get the configuration info from package.json file
// this way we can use things like name and version (pkg.name)
pkg: grunt.file.readJSON('package.json'),
// all of our configuration goes here
});
// Load the plugin that provides the "uglify" task
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s)
grunt.registerTask('default', ['uglify']);
};
Chức năng gói
Trong đoạn mã trên, module.exports là một hàm bao bọc trong đó toàn bộ cấu hình đi vào bên trong hàm này. Đó là một cách hiển thị cấu hình cho phần còn lại của ứng dụng.
module.exports = function(grunt) {
//do grunt-related things here
}
Cấu hình Dự án và Nhiệm vụ
Bạn có thể cấu hình các tác vụ Grunt khi cấu hình Grunt của bạn đã sẵn sàng. Cấu hình dự án có thể được viết trong phần grunt.initConfig () . Bên trong hàm grunt.initConfig () , lấy thông tin cấu hình từ tệp package.json và lưu vào pkg . Bạn có thể gọi tên dự án của mình bằng pkg.name và phiên bản với pkg.version .
Đang tải Grunt Plugins và Tasks
Tải các tác vụ từ một plugin được chỉ định bằng cách sử dụng phương thức grunt.loadNpmTasks . Bạn có thể cài đặt plugin cục bộ bằng cách sử dụngnpmvà nó phải tương đối với Gruntfile. Bạn có thể tải plugin bằng một lệnh đơn giản như hình dưới đây:
grunt.task.loadNpmTasks(pluginName)
Nhiệm vụ tùy chỉnh
Khi bạn đang chạy Grunt thông qua dòng lệnh, Grunt sẽ tìm kiếm nhiệm vụ mặc định . Trong đoạn mã trên, chúng ta đang sử dụng một tác vụ có tên uglify có thể chạy bằng lệnh grunt . Điều này giống như việc chạy lệnh uglify grunt một cách rõ ràng và bạn có thể chỉ định số lượng tác vụ trong mảng.
grunt.registerTask('default', ['uglify']);
Bạn có thể xác định dữ liệu cấu hình dự án cụ thể cho Grunt trong tệp Gruntfile.js .
Cấu hình Grunt
Dữ liệu cấu hình tác vụ có thể được khởi tạo trong Gruntfile bằng cách sử dụng phương thức grunt.initConfig () . Bên trong hàm grunt.initConfig () , lấy thông tin cấu hình từ tệp package.json. Cấu hình sẽ chứa một nhiệm vụ có tênproperties và bất kỳ dữ liệu tùy ý nào.
grunt.initConfig({
jshint: {
// configuration for jshint task
},
cssmin: {
// configuration for cssmin task
},
// Arbitrary non-task-specific properties
my_files: ['dir1/*.js', 'dir2/*.js'],
});
Cấu hình nhiệm vụ và mục tiêu
Khi bạn đang chạy một tác vụ, Grunt sẽ tìm kiếm cấu hình trong thuộc tính có tên tác vụ. Chúng tôi sẽ xác định các nhiệm vụ với nhiều cấu hình và các tùy chọn mục tiêu như hình dưới đây -
grunt.initConfig({
jshint: {
myfile1: {
// configuration for "myfile1" target options
},
myfile2: {
// configuration for "myfile2" target options
},
},
cssmin: {
myfile3: {
// configuration for "myfile3" target options
},
},
});
Ở đây, jshint nhiệm vụ có myfile1 và myfile2 mục tiêu và cssmin nhiệm vụ có myfile3 mục tiêu. Khi bạn đang chạy jshint grunt , nó sẽ lặp lại cả nhiệm vụ và mục tiêu để xử lý cấu hình của mục tiêu được chỉ định.
Tùy chọn
Xác định thuộc tính tùy chọn bên trong cấu hình tác vụ ghi đè các giá trị mặc định của tác vụ. Mỗi mục tiêu bao gồm thuộc tính tùy chọn ghi đè các tùy chọn cấp nhiệm vụ. Nó sẽ có định dạng sau:
grunt.initConfig({
jshint: {
options: {
// task-level options that overrides task defaults
},
myfile: {
options: {
// "myfile" target options overrides task defaults
},
},
myfile1: {
// there is no option, target will use task-level options
},
},
});
Các tập tin
Grunt cung cấp một số ý tưởng để chỉ định các tệp mà tác vụ sẽ hoạt động và sử dụng các cách khác nhau để chỉ định ánh xạ tệp src-dest . Sau đây là một số thuộc tính bổ sung được hỗ trợ bởi ánh xạ src và đích :
filter- Đây là một hàm chỉ định đường dẫn tệp src phù hợp và trả về giá trị true hoặc false.
nonull - Nó xác định các mẫu không khớp khi nó được đặt thành true.
dot - Nó khớp với các tên tệp bắt đầu bằng dấu chấm hoặc cách khác.
matchBase - Nó khớp với các mẫu có chứa dấu gạch chéo với tên cơ sở của đường dẫn.
expand - Nó xử lý ánh xạ tệp src-dest.
Định dạng nhỏ gọn
Nó chỉ định ánh xạ tệp src-dest cho mỗi mục tiêu có thể được sử dụng cho các tác vụ chỉ đọc và chỉ yêu cầu thuộc tính src và không có thuộc tính đích .
grunt.initConfig({
jshint: {
myfile1: {
src: ['src/file1.js','src/file2.js']
},
},
cssmin: {
myfile2: {
src: ['src/file3.js','src/file4.js'],
dest: 'dest/destfile.js',
},
},
});
Định dạng đối tượng tệp
Nó chỉ định ánh xạ tệp src-dest cho mỗi mục tiêu, trong đó tên thuộc tính là tệp đích và giá trị của nó là tệp src .
grunt.initConfig({
jshint: {
myfile1: {
files: {
'dest/destfile.js':['src/file1.js','src/file2.js'],
'dest/destfile1.js':['src/file3.js','src/file4.js'],
},
},
myfile2: {
files: {
'dest/destfile2.js':['src/file22.js','src/file23.js'],
'dest/destfile21.js':['src/file24.js','src/file25.js'],
},
},
},
});
Định dạng mảng tệp
Nó chỉ định ánh xạ tệp src-đích cho mỗi mục tiêu bằng cách sử dụng các thuộc tính bổ sung cho mỗi ánh xạ.
grunt.initConfig({
jshint: {
myfile1: {
files: [
{src:['src/file1.js','src/file2.js'],dest:'dest/file3.js'},
{src:['src/file4.js','src/file4.js'],dest:'dest/file5.js'},
],
},
myfile2: {
files: [
{src:['src/file6.js','src/file7.js'],dest:'dest/file8/', nonull:true},
{src:['src/file9.js','src/file10.js'],dest:'dest/file11/', filter:'isFalse'},
],
},
},
});
Các định dạng cũ hơn
Các dest-as-mục tiêu định dạng tập tin đã có trước sự tồn tại của multitasks nơi đường dẫn tập tin đích là tên của mục tiêu. Định dạng sau không được dùng nữa và nó sẽ không được sử dụng trong mã.
grunt.initConfig({
jshint: {
'dest/destfile2.js':['src/file3.js','src/file4.js'],
'dest/destfile5.js':['src/file6.js','src/file7.js'],
},
});
Chức năng lọc tùy chỉnh
Bạn có thể giúp các tệp đích với mức độ chi tiết cao bằng cách sử dụng thuộc tính bộ lọc . Định dạng sau chỉ xóa tệp nếu nó khớp với tệp thực.
grunt.initConfig({
clean: {
myfile:{
src: ['temp/**/*'],
filter: 'isFile',
},
},
});
Các mẫu bóng
Globbing có nghĩa là mở rộng tên tệp. Grunt hỗ trợ globbing bằng cách sử dụng các thư viện nút và minimatch tích hợp sẵn . Hình cầu bao gồm các điểm sau:
- * khớp với bất kỳ số ký tự nào, nhưng không khớp với / .
- ? khớp với một ký tự, nhưng không khớp với / .
- ** khớp với một số ký tự bao gồm / .
- {} chỉ định danh sách các biểu thức "hoặc" được phân tách bằng dấu phẩy.
- ! sẽ phủ định kết quả khớp mẫu lúc đầu.
Ví dụ -
{src: 'myfile/file1.js', dest: ...} // it specifies the single file
{src: 'myfile/*.js', dest: ...} //it matches all the files ending wth .js
{src: 'myfile/{file1,file2}*.js', dest: ...} //defines the single node glob pattern
{src: ['myfile/*.js', '!myfile/file1.js'], dest: ...} // all files will display in alpha
// order except for file1.js
Xây dựng đối tượng tệp một cách động
Khi bạn đang làm việc với các tệp riêng lẻ, bạn có thể sử dụng các thuộc tính bổ sung để tạo danh sách tệp động. Khi bạn đặtexpand thuộc tính true, nó sẽ kích hoạt một số thuộc tính sau:
cwd khớp tất cả src với đường dẫn này.
src so khớp các mẫu để phù hợp, liên quan đến cwd .
thuộc tính đích chỉ định tiền tố đường dẫn đích.
ext sẽ thay thế một phần mở rộng hiện có bằng một giá trị được tạo trong các đường dẫn đích .
extDot cho biết dấu chấm cho biết phần mở rộng nằm ở đâu. Nó sử dụng khoảng thời gian đầu tiên hoặc kỳ cuối cùng ; theo mặc định, nó được đặt thành khoảng thời gian đầu tiên
flatten loại bỏ tất cả các phần đường dẫn khỏi các đường dẫn đích .
đổi tên chỉ định một chuỗi chứa đích và tên tệp mới.
Thuộc tính đổi tên
Đây là một hàm JavaScript duy nhất trả về một chuỗi và bạn không thể sử dụng giá trị chuỗi để đổi tên. Trong ví dụ sau, tác vụ sao chép sẽ tạo một bản sao lưu của README.md.
grunt.initConfig({
copy: {
backup: {
files: [{
expand: true,
src: ['docs/README.md'], // creating a backup of README.md
rename: function () { // specifies the rename function
return 'docs/BACKUP.txt'; // returns a string with the complete destination
}
}]
}
}
});
Mẫu
Bạn có thể chỉ định các mẫu bằng cách sử dụng dấu phân cách <%%> . Chúng sẽ được mở rộng tự động khi chúng được đọc từ cấu hình. Nó bao gồm hai loại thuộc tính -
<%= prop.subprop %>thuộc tính được sử dụng để mở rộng giá trị của prop.subprop trong cấu hình có thể tham chiếu đến các giá trị chuỗi, mảng và các đối tượng khác.
<% %> thuộc tính thực thi mã JavaScript nội tuyến được sử dụng cho luồng điều khiển hoặc vòng lặp.
Ví dụ -
grunt.initConfig({
concat: {
myfile: {
options: {
banner: '/* <%= val %> */\n',
},
src: ['<%= myval %>', 'file3/*.js'],
dest: 'build/<%= file3 %>.js',
},
},
// properties used in task configuration templates
file1: 'c',
file2: 'b<%= file1 %>d',
file3: 'a<%= file2 %>e',
myval: ['file1/*.js', 'file2/*.js'],
});
Nhập dữ liệu bên ngoài
Bạn có thể nhập dữ liệu bên ngoài từ tệp package.json . Plugin grunt- Contrib- uglify có thể được sử dụng để thu nhỏ tệp nguồn và nó tạo ra một nhận xét biểu ngữ bằng cách sử dụng siêu dữ liệu. Bạn có thể sử dụng grunt.file.readJSON và grunt.file.readYAML để nhập dữ liệu JSON và YAML.
Ví dụ -
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
dist: {
src: 'src/<%= pkg.name %>.js',
dest: 'dist/<%= pkg.name %>.min.js'
}
}
});
Trong chương này, chúng ta hãy tạo một tệp Grunt đơn giản bằng các plugin sau:
- grunt-contrib-uglify
- grunt-contrib-concat
- grunt-contrib-jshint
- grunt-contrib-watch
Cài đặt tất cả các plugin ở trên và làm theo các bước dưới đây để tạo một Gruntfile.js đơn giản -
Step 1- Bạn cần tạo một hàm wrapper , đóng gói các cấu hình cho Grunt của bạn.
module.exports = function(grunt) {};
Step 2 - Khởi tạo đối tượng cấu hình của bạn như hình dưới đây -
grunt.initConfig({});
Step 3- Tiếp theo, đọc cài đặt dự án từ tệp package.json vào thuộc tính pkg . Nó cho phép chúng tôi tham chiếu đến các giá trị thuộc tính trong tệp package.json của bạn .
pkg: grunt.file.readJSON('package.json')
Step 4- Tiếp theo, bạn có thể xác định cấu hình cho các tác vụ. Hãy để chúng tôi tạo ra nhiệm vụ đầu tiên của chúng tôi concat để nối tất cả các file mà có mặt trong src / thư mục và lưu trữ nối .js tập tin dưới dist / thư mục.
concat: {
options: {
// define a string to insert between files in the concatenated output
separator: ';'
},
dist: {
// files needs to be concatenated
src: ['src/**/*.js'],
// location of the concatenated output JS file
dest: 'dist/<%= pkg.name %>.js'
}
}
Step 5- Bây giờ, chúng ta hãy tạo một tác vụ khác có tên là uglify để giảm thiểu JavaScript của chúng ta.
uglify: {
options: {
// banner will be inserted at the top of the output which displays the date and time
banner: '/*! <%= pkg.name %> <%= grunt.template.today() %> */\n'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
}
Tác vụ trên tạo một tệp trong thư mục dist / có chứa các tệp .js đã được rút gọn. Các<%= concat.dist.dest %>sẽ hướng dẫn uglify thu nhỏ tệp mà tác vụ kết hợp tạo ra.
Step 6- Hãy để chúng tôi cấu hình plugin JSHint bằng cách tạo tác vụ jshint .
jshint: {
// define the files to lint
files: ['Gruntfile.js', 'src/**/*.js'],
// configure JSHint
options: {
// more options here if you want to override JSHint defaults
globals: {
jQuery: true,
}
}
}
Tác vụ jshint ở trên chấp nhận một mảng tệp và sau đó là một đối tượng tùy chọn. Tác vụ trên sẽ tìm kiếm bất kỳ vi phạm mã hóa nào trong các tệp Gruntfile.js và src / ** / *. Js .
Step 7- Tiếp theo, chúng ta có nhiệm vụ xem tìm kiếm các thay đổi trong bất kỳ tệp nào được chỉ định và chạy các tác vụ bạn chỉ định.
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint']
}
Step 8- Tiếp theo, chúng ta phải tải các plugin Grunt đã được cài đặt qua _npm .
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
Step 9- Cuối cùng, chúng ta phải xác định nhiệm vụ mặc định .
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
Tác vụ mặc định có thể được chạy bằng cách chỉ cần gõ lệnh grunt trên dòng lệnh.
Đây là Gruntfile.js hoàn chỉnh của bạn -
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today() %> */\n'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
jshint: {
// define the files to lint
files: ['Gruntfile.js', 'src/**/*.js'],
// configure JSHint
options: {
// more options here if you want to override JSHint defaults
globals: {
jQuery: true,
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint']
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
};
Trong chương này, chúng ta hãy tìm hiểu về cách tạo tác vụ . Bất cứ khi nào bạn chạy Grunt, một hoặc nhiều nhiệm vụ được chỉ định để chạy sẽ thông báo cho Grunt biết bạn muốn nó làm gì. Nếu bạn chỉ định nhiệm vụ mặc định , thì nó sẽ chạy theo mặc định.
Nhiệm vụ bí danh
Bất cứ khi nào danh sách các nhiệm vụ được chỉ định, một hoặc nhiều tác vụ khác có thể được đặt biệt hiệu bởi một tác vụ mới. Chạy bí danh sẽ lần lượt chạy mọi tác vụ được chỉ định trong taskList . Đối số taskList phải là một mảng các tác vụ như hình dưới đây:
grunt.registerTask(taskName, [description, ] taskList)
Ví dụ: khi bạn xác định một taskList với các tác vụ jshint , concat và uglify và chỉ định taskName làm mặc định , tất cả các tác vụ được liệt kê sẽ được chạy tự động nếu Grunt được thực thi mà không chỉ định bất kỳ tác vụ nào.
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
Bạn cũng có thể chỉ định các đối số nhiệm vụ như được hiển thị bên dưới:
grunt.registerTask('dist', ['concat:dist', 'uglify:dist']);
Trong tác vụ trên, alias dist chạy cả tác vụ concat và uglify .
Đa nhiệm vụ
Bất cứ khi nào bạn chạy nhiều tác vụ, Grunt sẽ tìm kiếm một thuộc tính có cùng tên trong cấu hình Grunt. Các tác vụ này có thể có nhiều cấu hình, sẽ được xác định bằng cách sử dụng các mục tiêu được đặt tên tùy ý .
Khi bạn chỉ định cả nhiệm vụ và mục tiêu, chỉ cấu hình mục tiêu được chỉ định mới được xử lý.
grunt concat:foo
Lệnh trên sẽ chỉ chạy foo đích .
Khi bạn chỉ định một nhiệm vụ, thì tất cả các mục tiêu sẽ được xử lý.
grunt concat
Lệnh trên sẽ lặp lại trên tất cả các mục tiêu của tác vụ concat .
Khi bạn đổi tên một tác vụ bằng grunt.task.renameTask , một thuộc tính có tên tác vụ mới sẽ được Grunt tìm kiếm trong đối tượng cấu hình.
grunt.initConfig({
log: {
foo: [1, 2, 3],
bar: 'Welcome to tutorialspoint',
sap: true
}
});
grunt.registerMultiTask('log', 'Log stuff.', function() {
grunt.log.writeln(this.target + ': ' + this.data);
});
Trong ví dụ trên, đa nhiệm vụ sẽ ghi foo: 1,2,3 nếu Grunt được chạy qua grunt log: foo hoặc nó sẽ đăng nhập thanh: Chào mừng bạn đến với hướng dẫn bất cứ khi nào chạy qua grunt log: bar . Nó sẽ đăng nhập foo: 1,2,3 rồi thanh: Chào mừng bạn đến với điểm hướng dẫn rồi đến sap: true khi Grunt chạy dưới dạng nhật ký grunt .
Nhiệm vụ cơ bản
Bất cứ khi nào bạn chạy một tác vụ cơ bản, Grunt sẽ không tìm kiếm cấu hình hoặc môi trường. Thay vào đó, nó chạy hàm tác vụ được chỉ định, chuyển bất kỳ đối số được phân tách bằng dấu hai chấm nào được chỉ định làm đối số hàm.
grunt.registerTask(taskName, [description, ] taskFunction)
Trong ví dụ sau, nhiệm vụ ghi nhật ký foo, kiểm tra 123 nếu Grunt được thực thi thông qua lệnh grunt foo: testing: 123 . Bất cứ khi nào tác vụ được chạy mà không có đối số là grunt foo , tác vụ sẽ ghi foo, không có args .
grunt.registerTask('foo', 'A simple task to logs stuff.', function(arg1, arg2) {
if (arguments.length === 0) {
grunt.log.writeln(this.name + ", no args");
} else {
grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);
}
});
Nhiệm vụ tùy chỉnh
Nếu bạn không muốn làm theo cấu trúc đa tác vụ , bạn có thể xác định tác vụ tùy chỉnh của mình như hình dưới đây -
grunt.registerTask('default', 'My "default" task description.', function() {
grunt.log.writeln('Currently running the "default" task.');
});
Có thể chạy một tác vụ trong một tác vụ khác như hình dưới đây -
grunt.registerTask('foo', 'My "foo" task.', function() {
// Enqueue bar and baz tasks, to run after foo completes, in-order.
grunt.task.run('bar', 'baz');
// Or:
grunt.task.run(['bar', 'baz']);
});
Bạn cũng có thể tạo các tác vụ không đồng bộ như hình dưới đây -
grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() {
// Force task into async mode and grab a handle to the done() function.
var done = this.async();
// Run some sync stuff.
grunt.log.writeln('Processing your task..');
// Run some async stuff.
setTimeout(function() {
grunt.log.writeln('Finished!');
done();
}, 1000);
});
Bạn có thể tạo các tác vụ có thể truy cập vào tên và đối số của chúng như hình dưới đây -
grunt.registerTask('foo', 'My task "foo" .', function(a, b) {
grunt.log.writeln(this.name, a, b);
});
// Usage:
// grunt foo
// logs: "foo", undefined, undefined
// grunt foo:bar
// logs: "foo", "bar", undefined
// grunt foo:bar:baz
// logs: "foo", "bar", "baz"
Bạn có thể tạo tác vụ của mình theo cách mà bất cứ khi nào có lỗi được ghi lại, các tác vụ có thể không thành công như hình dưới đây -
grunt.registerTask('foo', 'My task "foo" .', function() {
if (failureOfSomeKind) {
grunt.log.error('This is an error message.');
}
// If this task had errors then fail by returning false
if (ifErrors) { return false; }
grunt.log.writeln('This is success message');
});
Bất cứ khi nào một tác vụ không thành công, mọi tác vụ sau sẽ bị chấm dứt trừ khi --force được chỉ định.
grunt.registerTask('foo', 'My task "foo" .', function() {
// Fail synchronously.
return false;
});
grunt.registerTask('bar', 'My task "bar" .', function() {
var done = this.async();
setTimeout(function() {
// Fail asynchronously.
done(false);
}, 1000);
});
Các tác vụ có thể phụ thuộc vào các tác vụ khác để thực hiện thành công. Hãy nhớ rằng grunt.task.requires sẽ không thực sự thực thi (các) tác vụ khác, thay vào đó nó sẽ chỉ kiểm tra xem liệu nó đã thực thi hay chưa.
grunt.registerTask('foo', 'My task "foo" .', function() {
return false;
});
grunt.registerTask('bar', 'My task "bar" .', function() {
// Fail task if foo task failed or never ran.
grunt.task.requires('foo');
// This code executes if the foo task executed successfully.
grunt.log.writeln('Hello, World.. Welcome to Tutorialspoint!..');
});
// Usage:
// grunt foo bar doesn't log, because foo failed to execute.
// **Note: This is an example of space-separated sequential commands,
// (similar to executing two lines of code: `grunt foo` then `grunt bar`)
// grunt bar doesn't log, because foo never ran.
Các tác vụ thậm chí có thể thất bại bất cứ khi nào không tìm thấy các thuộc tính cấu hình yêu cầu.
grunt.registerTask('foo', 'My task "foo" .', function() {
// Fail task if meta.name config properties is missing
// Format 1: String
grunt.config.requires('meta.name');
// or Format 2: Array
grunt.config.requires(['meta', 'name']);
// Log... conditionally.
grunt.log.writeln('This only log if meta.name is defined in the config.');
});
Các tác vụ có thể truy cập các thuộc tính cấu hình như hình dưới đây -
grunt.registerTask('foo', 'My task "foo" .', function() {
// Log the value of the property. Returns null if the property is undefined.
grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name'));
// Also logs the value of the property. Returns null if the property is undefined.
grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name']));
});