Sử dụng Grunt trong ASP.NET Core
Nguồn: Use Grunt in ASP.NET Core
Grunt là một trình chạy tác vụ JavaScript (JavaScript task runner) tự động hóa việc minification script, biên dịch TypeScript, các công cụ kiểm tra chất lượng code "lint", CSS pre-processors, và hầu hết các tác vụ lặp đi lặp lại cần thiết để hỗ trợ phát triển client. Grunt được hỗ trợ đầy đủ trong Visual Studio.
Ví dụ này sử dụng một dự án ASP.NET Core rỗng làm điểm bắt đầu, để chỉ cách tự động hóa quy trình build client từ đầu.
Ví dụ hoàn chỉnh sẽ dọn sạch thư mục triển khai đích, kết hợp các file JavaScript, kiểm tra chất lượng code, nén nội dung file JavaScript và triển khai ra thư mục gốc của ứng dụng web. Chúng ta sẽ sử dụng các gói sau:
- grunt: Gói trình chạy tác vụ Grunt.
- grunt-contrib-clean: Plugin xóa file hoặc thư mục.
- grunt-contrib-jshint: Plugin kiểm tra chất lượng code JavaScript.
- grunt-contrib-concat: Plugin ghép các file thành một file duy nhất.
- grunt-contrib-uglify: Plugin minify JavaScript để giảm kích thước.
- grunt-contrib-watch: Plugin theo dõi hoạt động file.
Chuẩn bị ứng dụng
Để bắt đầu, hãy thiết lập một ứng dụng web trống mới và thêm các file TypeScript mẫu. Các file TypeScript được tự động biên dịch thành JavaScript bằng cài đặt mặc định của Visual Studio và sẽ là nguyên liệu thô để xử lý bằng Grunt.
- Trong Visual Studio, tạo một ASP.NET Web Application mới.
- Trong hộp thoại New ASP.NET Project, chọn template Empty của ASP.NET Core và nhấn OK.
- Trong Solution Explorer, xem lại cấu trúc dự án. Thư mục
\srcbao gồm các nodewwwrootvàDependenciestrống.
- Thêm thư mục mới tên
TypeScriptvào thư mục dự án. - Trước khi thêm file, hãy đảm bảo Visual Studio có tùy chọn 'compile on save' (biên dịch khi lưu) cho file TypeScript được bật. Điều hướng đến Tools > Options > Text Editor > Typescript > Project:
!options setting auto compilation of TypeScript files
- Nhấp chuột phải vào thư mục
TypeScriptvà chọn Add > New Item từ menu ngữ cảnh. Chọn mục JavaScript file và đặt tên file làTastes.ts(lưu ý phần mở rộng \*.ts). Sao chép dòng code TypeScript dưới đây vào file (khi bạn lưu, một fileTastes.jsmới sẽ xuất hiện với source JavaScript).
``typescript enum Tastes { Sweet, Sour, Salty, Bitter } ``
- Thêm file thứ hai vào thư mục TypeScript và đặt tên là
Food.ts. Sao chép code dưới đây vào file.
```typescript class Food { constructor(name: string, calories: number) { this._name = name; this._calories = calories; }
private _name: string; get Name() { return this._name; }
private _calories: number; get Calories() { return this._calories; }
private _taste: Tastes; get Taste(): Tastes { return this._taste } set Taste(value: Tastes) { this._taste = value; } } ```
Cấu hình npm
Tiếp theo, cấu hình npm để tải xuống grunt và grunt-tasks.
- Trong Solution Explorer, nhấp chuột phải vào dự án và chọn Add > New Item từ menu ngữ cảnh. Chọn mục npm Configuration File, giữ tên mặc định
package.json, và nhấn nút Add. - Trong file
package.json, bên trong dấu ngoặc nhọn của objectdevDependencies, nhập "grunt". Chọngrunttừ danh sách IntelliSense và nhấn Enter. Visual Studio sẽ đặt tên gói grunt trong dấu nháy và thêm dấu hai chấm. Ở bên phải dấu hai chấm, chọn phiên bản ổn định mới nhất của gói từ đầu danh sách IntelliSense (nhấnCtrl-Spacenếu IntelliSense không hiện).
> Lưu ý: npm sử dụng semantic versioning để tổ chức các dependency (phụ thuộc). Semantic versioning, còn được gọi là SemVer, xác định các gói với sơ đồ đánh số <major>.<minor>.<patch>. IntelliSense đơn giản hóa semantic versioning bằng cách chỉ hiển thị một vài lựa chọn phổ biến. Mục đầu tiên trong danh sách IntelliSense (0.4.5 trong ví dụ trên) được coi là phiên bản ổn định mới nhất. Ký hiệu dấu mũ (^) khớp với phiên bản major mới nhất và dấu ngã (~) khớp với phiên bản minor mới nhất.
- Thêm nhiều dependency hơn để tải các gói grunt-contrib-\ cho clean, jshint, concat, uglify, và watch* như trong ví dụ dưới đây. Các phiên bản không cần phải khớp với ví dụ.
``json "devDependencies": { "grunt": "0.4.5", "grunt-contrib-clean": "0.6.0", "grunt-contrib-jshint": "0.11.0", "grunt-contrib-concat": "0.5.1", "grunt-contrib-uglify": "0.8.0", "grunt-contrib-watch": "0.6.1" } ``
- Lưu file
package.json.
Các gói cho mỗi mục devDependencies sẽ được tải xuống, cùng với các file mà mỗi gói yêu cầu. Bạn có thể tìm thấy các file gói trong thư mục node\_modules bằng cách bật nút Show All Files trong Solution Explorer.
Lưu ý: Nếu cần, bạn có thể khôi phục các dependency thủ công trong Solution Explorer bằng cách nhấp chuột phải vào Dependencies\npm và chọn tùy chọn menu Restore Packages.
Cấu hình Grunt
Grunt được cấu hình bằng một file manifest (tệp kê khai) tên Gruntfile.js để định nghĩa, tải và đăng ký các tác vụ có thể chạy thủ công hoặc được cấu hình để chạy tự động dựa trên các sự kiện trong Visual Studio.
- Nhấp chuột phải vào dự án và chọn Add > New Item. Chọn template mục JavaScript File, đổi tên thành
Gruntfile.js, và nhấn nút Add. - Thêm code sau vào
Gruntfile.js. HàminitConfigđặt các tùy chọn cho mỗi gói, và phần còn lại của module tải và đăng ký các tác vụ.
``javascript module.exports = function (grunt) { grunt.initConfig({ }); }; ``
- Bên trong hàm
initConfig, thêm các tùy chọn cho tác vụcleannhư trong ví dụGruntfile.jsdưới đây. Tác vụcleanchấp nhận một mảng các chuỗi thư mục. Tác vụ này xóa các file từ wwwroot/lib và xóa toàn bộ thư mục /temp.
``javascript module.exports = function (grunt) { grunt.initConfig({ clean: ["wwwroot/lib/*", "temp/"], }); }; ``
- Bên dưới hàm
initConfig, thêm lời gọi đếngrunt.loadNpmTasks. Điều này sẽ làm cho tác vụ có thể chạy từ Visual Studio.
``javascript grunt.loadNpmTasks("grunt-contrib-clean"); ``
- Lưu
Gruntfile.js. - Nhấp chuột phải vào
Gruntfile.jsvà chọn Task Runner Explorer từ menu ngữ cảnh. Cửa sổ Task Runner Explorer sẽ mở ra. - Xác minh rằng
cleanhiển thị dưới Tasks trong Task Runner Explorer. - Nhấp chuột phải vào tác vụ clean và chọn Run từ menu ngữ cảnh. Một cửa sổ lệnh hiển thị tiến trình của tác vụ.
- Trong hàm
initConfig, thêm một entry choconcatbằng code dưới đây.
Mảng thuộc tính src liệt kê các file cần kết hợp, theo thứ tự chúng nên được kết hợp. Thuộc tính dest gán đường dẫn đến file kết hợp được tạo ra.
``javascript concat: { all: { src: ['TypeScript/Tastes.js', 'TypeScript/Food.js'], dest: 'temp/combined.js' } }, ``
- Thêm tác vụ
jshintbằng code dưới đây.
Tiện ích jshint code-quality được chạy trên mọi file JavaScript tìm thấy trong thư mục temp.
``javascript jshint: { files: ['temp/*.js'], options: { '-W069': false, } }, ``
> Lưu ý: Tùy chọn "-W069" là một lỗi do jshint tạo ra khi JavaScript sử dụng cú pháp dấu ngoặc vuông để gán thuộc tính thay vì ký hiệu chấm, Tastes["Sweet"] thay vì Tastes.Sweet. Tùy chọn này tắt cảnh báo để cho phép phần còn lại của quá trình tiếp tục.
- Thêm tác vụ
uglifybằng code dưới đây.
Tác vụ minify file combined.js tìm thấy trong thư mục temp và tạo file kết quả trong wwwroot/lib theo quy ước đặt tên chuẩn <tên file>.min.js.
``javascript uglify: { all: { src: ['temp/combined.js'], dest: 'wwwroot/lib/combined.min.js' } }, ``
- Dưới lời gọi đến
grunt.loadNpmTaskstảigrunt-contrib-clean, hãy thêm lời gọi tương tự cho jshint, concat, và uglify bằng code dưới đây.
``javascript grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); ``
- Lưu
Gruntfile.js. - Lưu ý rằng danh sách Tasks của Task Runner Explorer bao gồm các tác vụ
clean,concat,jshintvàuglify. Chạy từng tác vụ theo thứ tự và quan sát kết quả trong Solution Explorer. Mỗi tác vụ sẽ chạy không có lỗi.
Tác vụ concat tạo một file combined.js mới và đặt nó vào thư mục temp. Tác vụ jshint đơn giản chạy và không tạo ra output. Tác vụ uglify tạo một file combined.min.js mới và đặt nó vào wwwroot/lib.
Kết hợp tất cả lại
Sử dụng phương thức registerTask() của Grunt để chạy một loạt tác vụ theo một trình tự cụ thể. Ví dụ, để chạy các bước ví dụ trên theo thứ tự clean -> concat -> jshint -> uglify, thêm code dưới đây vào module. Code nên được thêm ở cùng cấp với các lời gọi loadNpmTasks(), bên ngoài initConfig.
grunt.registerTask("all", ['clean', 'concat', 'jshint', 'uglify']);Tác vụ mới xuất hiện trong Task Runner Explorer dưới Alias Tasks. Bạn có thể nhấp chuột phải và chạy nó giống như các tác vụ khác. Tác vụ all sẽ chạy clean, concat, jshint và uglify, theo thứ tự.
Theo dõi các thay đổi
Tác vụ watch theo dõi file và thư mục. watch kích hoạt các tác vụ tự động nếu phát hiện thay đổi. Thêm code dưới đây vào initConfig để theo dõi các thay đổi với file \*.js trong thư mục TypeScript. Nếu một file JavaScript bị thay đổi, watch sẽ chạy tác vụ all.
watch: {
files: ["TypeScript/*.js"],
tasks: ["all"]
}Thêm lời gọi đến loadNpmTasks() để hiển thị tác vụ watch trong Task Runner Explorer.
grunt.loadNpmTasks('grunt-contrib-watch');Nhấp chuột phải vào tác vụ watch trong Task Runner Explorer và chọn Run từ menu ngữ cảnh. Cửa sổ lệnh hiển thị tác vụ watch đang chạy sẽ hiển thị thông báo "Waiting…". Mở một trong các file TypeScript, thêm một khoảng trắng, sau đó lưu file. Điều này sẽ kích hoạt tác vụ watch và kích hoạt các tác vụ khác chạy theo thứ tự.
Liên kết đến các sự kiện Visual Studio
Trừ khi bạn muốn khởi động tác vụ thủ công mỗi lần làm việc trong Visual Studio, hãy liên kết các tác vụ với các sự kiện Before Build, After Build, Clean, và Project Open.
Liên kết watch để nó chạy mỗi khi Visual Studio mở. Trong Task Runner Explorer, nhấp chuột phải vào tác vụ watch và chọn Bindings > Project Open từ menu ngữ cảnh.
!bind a task to the project opening
Unload và reload dự án. Khi dự án tải lại, tác vụ watch bắt đầu chạy tự động.
Tóm tắt
Grunt là một trình chạy tác vụ mạnh mẽ có thể được sử dụng để tự động hóa hầu hết các tác vụ build client. Grunt tận dụng npm để cung cấp các gói và có tích hợp công cụ với Visual Studio. Task Runner Explorer của Visual Studio phát hiện các thay đổi đối với file cấu hình và cung cấp giao diện thuận tiện để chạy tác vụ, xem các tác vụ đang chạy và liên kết các tác vụ với các sự kiện Visual Studio.