Bootstrap - CSS Framework
Tác vụ watch (Bài trước)
(Bài tiếp) Grunt với JS

Trong phần này ta sẽ tìm hiểu sử dụng Grunt để thi hành tác vụ dịch SCSS thành CSS, sau đó xây dựng một dự án tùy biến thư viện Bootstrap, có nghĩa bạn có thể tùy chỉnh, thêm bớt, tạo theme riêng từ Bootstrap (nói cách khác tạo ra một phiên bản Bootstrap riêng bạn).

Biên dịch SASS/SCSS

Tất nhiên đến đây bạn đã hiểu cú pháp viết CSS theo kiểu SASS/SCSS rồi (nếu chưa thì cần học SASS - SCSS trước).

Để biên dịch SASS/SCSS thành CSS ta dùng đến package grunt-sass (V 3.0.2), plugin này dùng đến package nodejs là node-sass nên ta cần thêm 2 package này vào package.json

{
     ...
    "devDependencies": {
      ...
      "grunt-sass":"~3.0.2",
      "node-sass": "~4.10.0"
      ...
    }
  }

Package này cung cấp cho Grunt tác vụ có tên sass, tạo ra tác vụ trong Gruntfile.js cơ bản như sau:

sass: {
    options: {
        implementation: sass,
        sourceMap: true                 //Có sinh map
    },
    dist: {
        files: {
            'file.css': 'file.scss'     //Chỉ ra sass và nơi lưu css
        }
    }
}

Bây giờ thực hiện từng bước kiểm thức tác vụ này xem:

Tạo ra một thư mục có tên mybootstrap (Đặt tên như vậy vì sắp tới sẽ dùng thư mục này lưu dự án tùy biến Bootstrap), bên trong thư mục đó tạo 2 file: package.json, Gruntfile.js đồng thời tạo ra thư mục con src (dự định lưu code của bạn). Cập nhật các file như sau:

{
    "name": "mybootstrap",
    "version": "0.1.0",
    "devDependencies": {
        "@babel/core": "^7.1.6",
        "@babel/preset-env": "^7.1.6",
        "grunt": "~0.4.5",
        "grunt-babel": "^8.0.0",
        "grunt-contrib-concat": "~1.0.1",
        "grunt-contrib-uglify": "~0.5.0",
        "grunt-contrib-jshint": "2.0.0",
        "grunt-contrib-clean": "2.0.0",
        "grunt-contrib-watch": "1.0.1", 
        "grunt-sass": "~3.0.2",
        "node-sass": "~4.10.0"
    }
}

Tại terminate gõ luôn dòng sau để cài các package

# npm install

File Gruntfile.js

const sass = require('node-sass');

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sass: {
            options: {
                implementation: sass,
                sourceMap: true

            },

            build: {
                files: {
                    'build/test.css' : 'src/test.scss'
                }
            }
        }
    });

  //Nạp package
  grunt.loadNpmTasks('grunt-sass');

  grunt.registerTask('default', ['sass']);
}

Như vậy khi chạy Grunt mặc định sẽ dịch file nguồn src/test.scss, kết quả lưu thành build/test.css

Hãy viết code SCSS của bạn trong src/test.scss ví dụ

File src/test.scss

$background: red;
$color: white;

body {
    background-color: $background;
    color: $color;
    .header {
        background: white;
        color: green;
        border: 1px solid gray;

        span {
            font-weight: 700;
        }
    }
}

Chạy lệnh grunt

# grunt
Running "sass:build" (sass) task

Done, without errors.

Kết quả buil thành công, có được build/test.css

body {
  background-color: red;
  color: white; }
  body .header {
    background: white;
    color: green;
    border: 1px solid gray; }
    body .header span {
      font-weight: 700; }

/*# sourceMappingURL=test.css.map */

Tải ví dụ mẫu ở trên về bằng git

# git clone git@github.com:xuanthulabnet/mybootstrap.git
# git cd mybootstrap
# git checkout vd01
# npm install

Từ ví dụ trên bạn có thể kết hợp nhiều task phức tạp hơn để xây dựng cho mình một Task runer đáp ứng công việc của mình. Sau đây sẽ tùy biến thư viện Bootstrap thành riêng của bạn.

Bootstrap gồm cả JS và CSS ở đây trước tiên tùy biến CSS

Tùy biến Bootstrap với Grunt

Toàn bộ mã nguồn Bootstrap có cung cấp như là một module package trong NodeJS (Package đó ở đây bootstrap ), để tích hợp vào dự án của bạn bạn chỉ việc thêm vào package.json dòng

"bootstrap":"4.1.3"

Sau đó chạy npm install để tải package đó về dự án, mã nguồn này lưu tại node_modules/bootstrap, trong đó có các thành phần SCSS của bootrap lưu ở node_modules/bootstrap/scss, còn thành phần Javascript của nó lưu tại node_modules/bootstrap/js (JS ta sẽ tùy biến sau)

Giờ ta tạo ra file src/mybootstrap.scss, file này gộp tất cả các thành phần SCSS của thư viện bootstrap. Nội dung file đó có thể như sau:

src/mybootstrap.scss
$blue:    #007bff;
$indigo:  #6610f2;
$purple:  #6f42c1;
$pink:    #e83e8c;
$red:     #dc3545;
$orange:  #fd7e14;
$yellow:  #ffc107 !default;
$green:   #28a745 !default;
$teal:    #20c997 !default;
$cyan:    #17a2b8 !default;

@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/code";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/input-group";
@import "../node_modules/bootstrap/scss/custom-forms";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/jumbotron";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/media";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/utilities";
@import "../node_modules/bootstrap/scss/print";

//My Items

@import "customs/footer"

Trên đây là các thành phần đầy đủ của Bootstrap được gộp vào, nếu Website của bạn không sử dụng SCSS nào thì bỏ dòng đó đi, ví dụ không sử dụng forms thì comment vào dòng @import "../node_modules/bootstrap/scss/forms";

Bootstrap có nhiều biến để tùy chọn, ví dụ trên có đưa lấy ra các biến như $blue, $yellow ... bạn có thể tùy biến những biến kiểu này để có một Bootstrap riêng của bạn (ví dụ nếu bạn gán $blue bằng màu khác, thì các thành phần như .bg-primary, .btn-primary ... sẽ có màu theo biến này (Còn rất nhiều biến, nó định nghĩa trong file: variables, thay đổi biến nào thì lấy ra như trên).

Ngoài các thành phần Bootstrap, bạn cũng có các SCSS riêng của bạn, ví dụ lưu tại src/custom, và import vào, như ví dụ trên tạo ra một file src/customs/_footer.scss nội dung như sau:

.myfooter {
    background-color: $blue;
    color: $yellow;
    border: 1px solid green;

    a {
        text-decoration: none;
        :hover {
            color: red;
        }
    }
}

Rồi gộp vào mybootstap.scss ở đoạn code:

@import "customs/footer"

Đến đây các thao tác tạo ra mã nguồn, tích hợp các thành phần Bootstrap đã xong, giờ chỉ còn thao tác tạo tác vụ sass dịch file src/mybootstrap.scss thành file build/mybootstrap.css của bạn trong Gruntfile.js

const sass = require('node-sass');

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sass: {
            options: {
                implementation: sass,
                sourceMap: true

            },

            build: {
                files: {
                    'build/mybootstrap.css' : 'src/mybootstrap.scss'
                }
            }
        }
    });

  //Nạp package
  grunt.loadNpmTasks('grunt-sass');


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

}

Đến đây đã hoàn thành, giờ muốn bất kỳ khi nào muốn dịch ra css của riêng bạn chỉ việc gõ grunt, kết quả thu được build/mybootstrap.css là Bootstrap đã tùy biến của bạn.

Tải ví dụ mẫu ở trên về bằng git

# git clone git@github.com:xuanthulabnet/mybootstrap.git
# git cd mybootstrap
# git checkout vd02
# npm install

Thêm tùy biến cho dự án

Để tiện dụng hơn bạn thêm vào dự án các tác vụ:

  • Tự động kiểm tra xem CSS có lỗi không (ví dụ mã màu không chính xác), tự động sinh ra Vendor prefix để CSS phù hợp với nhiều trình duyệt (-webkit-, -moz- ...) để có chức năng này cần cài các package: postcss, pixrem, grunt-postcss. Sau khi cài các package này thì sẽ xây dựng được tác vụ postcss để convert.
  • Thêm tác vụ cssmin (bạn cần thêm package grunt-contrib-cssmin), để nén file kết quả build/mybootstrap.css thành build/mybootstrap.min.css
  • Sử dụng tác vụ watch để giám sát, mỗi khi các file src/mybootstrap.scss, src/customs/*.scss thì tự động dịch SCSS thành CSS

Sau khi cài grunt-contrib-cssmin bằng các bước như đã biết ở phần trước, thêm vào tác vụ cssmin

cssmin: {
    options: {
      mergeIntoShorthands: false,
      roundingPrecision: -1
    },
    build: {
      files: {
        'build/mybootstrap.min.css' : 'build/mybootstrap.css'
      }
    }
  }

Tác vụ postcss kiểm tra lỗi CSS và tự động thêm Vendor prefix vào mybootstrap.css

  postcss: {
    options: {
        processors: [
          require('pixrem')(),
          require('autoprefixer')({browsers: 'last 2 versions'}),
        ]
      },
    build: {
        src: 'build/mybootstrap.css'
      }
  }

Tiếp theo thêm tác vụ watch (xem phần trước) để giám sát file nguồn thay đổi thì tự động biên dịch.

Đồng thời đăng tác vụ mặc định, và nạp thư viện

//Nạp package
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-postcss');

grunt.registerTask('runwatch', ['watch']);
grunt.registerTask('default', ['sass','postcss', 'cssmin']);

Cấu hình dự án đã hoàn thành, giờ bạn gõ lệnh

# grunt runwatch
Running "watch" task
Waiting...

Bạn chỉ việc tập trung viết code trong các file mybootstrap.scss và các thành phần trong src/custome/*.scss, mỗi khi code thay đổi sẽ tự động chạy tất cả các tác vụ trên để có file mybootstrap.min.css

Chúc thành công, toàn bộ thư mục dự án mẫu này bạn có thể tải về bằng lệnh git như sau:

Tải ví dụ mẫu ở trên về bằng git

# git clone git@github.com:xuanthulabnet/mybootstrap.git
# git cd mybootstrap
# git checkout vd03
# npm install

Đăng ký nhận bài viết mới
Tác vụ watch (Bài trước)
(Bài tiếp) Grunt với JS