Tôi học NodeJS thế nào?

Tôi bắt đầu từ đâu?

Tôi bắt đầu con đường lập trình của mình bằng Java & lập trình web dùng PHP. Sau đó tôi không dùng PHP nữa mà chuyển sang dùng Java Web, tôi chủ yếu sử dụng framework Spring MVC bởi vì công ty tôi chỉ dùng Spring MVC.

Đằng đẵng 3 năm trôi đi, tôi vùi đầu trong J2EE application và tôi cũng tự viết cho mình được một Java Web Framework, thứ mà cho đến bây giờ tôi không còn dùng nữa. Thực sự, tôi chỉ dùng nó cho một dự án tầm trung, sau đó là bỏ đi luôn. Khá là buồn nhưng cũng phải chấp nhận. Lý do tôi bỏ đi là vì khách hàng của tôi khá nhiều, đa số họ là khách hàng vừa và nhỏ, để triển khai các dự án kiểu như vậy quả thực khó với tôi, với khách hàng và khó cả với đồng đội của tôi... Tưởng chừng Java là thứ miễn phí nên chi phí đầu tư thấp nhưng không, thực sự tôi phải bỏ ra khá nhiều chi phí đầu tư cho hosting, cái cần để hỗ trợ cho Java Web. Và nó không rẻ...

Chi phí không phải là cái duy nhất quyết định đến việc tôi từ bỏ Java Web, còn nhiều thứ khác như, ngôn ngữ lập trình, cách lập trình, cách triển khai một dự án, ... tôi sẽ cố gắng nói chi tiết hơn ở một bài viết khác. 😄

Từ nhiều lý do ngớ ngẩn nhất có thể, tôi đi tìm một con đường khác để mang về cho mình nhiều tiền hơn, tốn ít chi phí cho lập trình, triển khai và bảo trì hơn.

Tôi gặp NodeJS thế nào?

Cũng sẽ chẳng có gì nếu không gặp thằng bạn dở hơi của tôi, nó là trùm Javascript và dĩ nhiên nó tôn sùng NodeJS. Và nó giới thiệu cho tôi biết rằng NodeJS rất nhẹ, dễ viết, nó là Javascript, có thể xử lý cả triệu request nhẹ nhàng =)), tốn ít ram, phần cứng thấp, dễ triển khai, dễ bảo trì, v.v...

OK. Quất liền. 😃

Tiếp cận NodeJS có đơn giản?

Đơn giản hơn tôi nghĩ các bạn ạ. Đơn giản đến độ không thể đơn giản hơn...

  1. Cài Node & npm NODE là cái quái gì nhỉ, lúc đấy tôi cũng chả biết đâu, cứ nghĩ đại nó giống Java JDK, thế là cứ cài đại nó vô. Còn npm, giời ơi, mệt quá cơ. Lắm thứ phải học dữ trời. Nhưng không, nó đơn giản lắm. Tôi đang cần tìm thư viện xxx thì tôi chỉ cần gõ 1 dòng lệnh đơn giản: npm install xxx, done!! Không cần phải google xxx.jar rồi download package đó từ trên maven repository rồi lại đẩy vào trong thư mục lib của project. 😄 Đại khái, nó giống maven hay gradle nếu ai đã xài qua.

  2. Tạo project mới hmm... Nghe có vẻ khó khăn, chắc phải kiếm cái IDE nào ngon ngon, rồi Tool -> New Project -> Project Type -> Project Name -> Framework -> Blah, ... Haha. 😄 Đơn giản hơn thế, Thích cái gì thì tạo cái đấy thôi. =)) npm init Vâng, khởi tạo một dự án mới bằng command line, nghe có vẻ ngầu ha... Đơn giản quá. Và cái project của tôi nhìn như thế này đây.

    --
      - package.json
    

    Có 1 file duy nhất. Are you kidding me? Lúc đầu tôi tưởng nó sẽ hầm hố lắm, ai dè có mỗi file json con con. -> Thất vọng ê chề.

         {
           "name": "demo-nodejs",
           "version": "1.0.0",
           "description": "Demo NodeJS",
           "main": "index.js",
           "scripts": {
             "test": "echo \"Error: no test specified\" && exit 1"
           },
           "author": "Luc Duong",
           "license": "MIT"
         }
    
  3. Ví dụ kinh điển trên index.js Tôi đã tạo file index.js và viết Helloworld example xem nó chạy như thế nào. :v

    ╭─[email protected]  ~/Projects/demo-nodejs
    ╰─$ vi index.js
    ╭─[email protected]  ~/Projects/demo-nodejs
    ╰─$ node index.js
    Hello World
    

    Cái file nó nhìn thế này đây

    console.log("Hello World");
    

    Chỉ có một dòng duy nhất. 😦 Haha. Great!!

  4. Dạo chơi với Express framework. Đúng là chỉ có vài dòng thôi... Haha. Trước tiên tôi cài nodejs Express framework. npm install express --save Sau đó sửa lại file index.js

        var express = require('express')
        var app = express()
    
        app.get('/', function (req, res) {
          res.send('Hello World!')
        })
    
        app.listen(3000, function () {
          console.log('Example app listening on port 3000!')
        })
    

    Và kết quả thì thật bất ngờ. 😄

  5. Vận dụng những gì mình đã biết Vâng, vận dụng những gì tôi đã biết ở Java Web và kiến thức căn bản của lập trình web, tôi đã tiếp cận NodeJS nhanh hơn rất nhiều. Xem nào...

    1. Khi người dùng duyệt web http://domain.com/ thì chuyện gì sẽ xảy ra nhỉ? Ai là người xử lý và kết quả trả ra là gì?
    2. Từ câu hỏi trên, tôi mới suy nghĩ đến DispatchServlet trong Java, tôi cần phải tạo một HttpServletHandlermapping với đường dẫn / để sau này, khi người dùng vào web / thì nó sẽ hiểu và đưa cho ServletHandler của tôi đã tạo ra xử lý. Vậy trong Express framework, tôi làm thế nào?
    3. Here we are... (Cái file index.js này có vẻ là khởi nguồn của mọi câu chuyện. haha)
          app.get('/', function (req, res) {
            res.send('Hello World!')
          })
      
    4. Tức là tôi xử lý ngay trong cái anonymous function? Really? Tôi tưởng là vậy, và tôi phải tìm xem nếu tôi muốn xử lý nó ở file khác và chỉ config ở đây thì làm thế nào.
    5. Tạo một file mới mang tên: HelloController.js trong thư mục nodejs
    6. Viết 1 hàm mang tên getHelloViewexport hàm đó ra ngoài.
          const getHelloView = function(req, res) {
            return res.send("Hello World!!");
          };
          exports.getHelloView = getHelloView;
      
    7. Quay lại index.js include file HelloController.js vào và sửa lại một chút. 😄
          var app = express()
          var HelloController = require('./controller/HelloController') // Chỗ này tôi include file HelloController.js
      
          app.get('/', HelloController.getHelloView) // Chỗ này tôi nói rằng, tôi muốn giao cho hàm getHelloView trong HelloController xử lý đường dẫn '/'
      
          app.listen(3000, function () {
            console.log('Example app listening on port 3000!')
          })
      
    8. Vậy là xong cái đầu tiên, get view đơn giản quá, nên tôi nghĩ chắc post cũng tương tự. (rofl) Yes, I think so, and It' true. haha.
    9. Vấn đề tiếp tục nảy sinh, tôi mới chỉ đưa ra cái chữ Hello World!! chết tiệt chứ có cái view html gì đâu, rồi còn template và còn page content nữa. Làm thế nào bây giờ. Nó làm tôi nghĩ đến phải có view resolver. Đúng rồi, phải search google xem làm thế nào để config view resolver, rồi layout, 😄
    10. Thực tế chả đâu xa, tôi lên trang chủ của express và vào mục document tìm đến tempalte engine thì nó được kết quả thế này app.set('view engine', 'pug') // thêm dòng này vào trong file index.js app.set('views', './views') // chỗ này chỉ định thư mục chứa file view Trước đó cũng không quên cài gói html engine vào 😄 npm install pug --save
    11. Tạo thư mục views rồi tạo file hello.pug (Thực chất .pug cũng chả khác gì .html đâu, trong đó là html😄)
          --
              - controller
                  - HelloController.js
              - node_modules
              - views
                  - hello.pug
              - package.json
              - index.js
      
      Nội dung file hello.pug
          html
            head
              title Hello World
            body
              h1 Hello World!!
      
      Sửa lại HelloController.js
          var getHelloView = function(req, res) {
            return res.render('hello'); // Sửa có dòng này à. Ý là không có send text như lúc đầu nữa, bây giờ render cái file hello.pug ra và trả về cho trình duyệt. :D
          };
          exports.getHelloView = getHelloView;
      
    12. OK. Chạy, kết quả đẹp như mơ. Tôi đã có kết quả như ý muốn khi tách file html riêng ra, file controller riêng ra.
    13. Tuy nhiên mỗi một view (UI hay page) đều phải html rồi head rồi body à, lỡ include một đống js vào thì chả lẽ file nào cũng phải copy, mang qua, dán vào. Ngu xuẩn!! =))
    14. Tôi nghĩ ngay đến layout. Bất chợt tôi tạo file layout.pug Làm giống ASP.net thì phải. =))
          html
            head
             title Hello World
            body
             h1 Here is the header
             hr
             block content
             hr
             h1 Here is the footer
      
      Tiếp đến, sửa lại file hello.pug
          extends ./layout
          block content
              h1 Here is the content of Hello World Page
      
      Chạy lại server thôi node index.js
    15. Kết quả có vẻ như ý muốn của tôi, lúc này tôi đã hoàn thành việc layout cho cái web của mình rồi, cứ thế mà chiến tiếp thôi. 😄 Cơ mà, lại có vấn đề. Làm sao để đưa dữ liệu xuống view nhỉ? hmm... phải có cách chứ, và tôi tiếp tục sửa một vài thứ như thế này: File HelloController.js -> Hẳn là file này rồi, vì chỗ này gọi render cái view mà, không nó thì ai. haha.
          var getHelloView = function(req, res) {
            return res.render('hello', {title: 'Title cua page', user:{name: 'Luc Duong', email: '[email protected]'}}); // Tôi chỉ nghĩ là tôi muốn đưa 1 object trong đó có 2 props `title` và `user` (Giống Javascript bình thường thôi)
          };
          exports.getHelloView = getHelloView;
      
      Tiếp đến file hello.pug -> Lúc này tôi muốn dùng cái user name & user email đây.
          extends ./layout
          block content
              h1 Hi, #{user.name} your email is #{user.email}
      
      Còn cái title tôi muốn đưa vào cái layout.pug và kết quả sau khi node index.js thì đúng là tuyệt vời.
    16. Cứ thế, tôi chơi với NodeJS trong 1 tiếng đồng hồ thì tôi biết cách sử dụng NodeJSExpress framework.
    17. Những ngày sau tôi tìm hiểu thêm nhiều thứ như làm sao để giải quyết các file tĩnh css, js, fonts, images, ... Hay làm sao để sử dụng MySQL database, MongoDB, hoặc làm sao để đọc, ghi file, ...
    18. Sau đó tôi tìm hiểu đến Middleware, Authentication, ...

Làm cách nào mà tôi lại tìm hiểu nhanh đến vậy?

Thực tế thì tôi dùng các câu hỏi như thế này trên google: What is NodeJS? -> Đọc sơ sơ bằng tiếng việt rồi tiếng anh What is express framework? -> Ngắm nghía sơ sơ rồi mãi sau này mới đọc sâu hơn về mỗi cái mình cần How to write the 'HelloWorld' example by using NodeJS? -> Ờ, nó giống cái trên tôi nói How to config route nodejs? -> Đơn giản, chả cần đúng ngữ pháp cũng ra một đống, lướt xem vài cái ví dụ. 😄 How to handle url in nodejs? -> thậm chí có thể hỏi câu này nếu mù về routing. View resolver in NodeJS -> À há. Câu này cũng đơn giản How to parse data in view nodejs -> 😄 Hí hí. How to secure nodejs express -> Chắc là Authentication Chủ yếu là mấy câu hỏi how. 😄 Ngoài ra, bằng một vài kiến thức cơ bản về web như sau: - Khi người dùng vào link nào đó thì chắc chắn là phải có một đối tượng xử lý. VD: vào /users thì phải có UserController.getUsers xử lý. 😄, giờ chỉ cần tìm hiểu làm sao làm như vậy trong NodeJS - Mỗi một request thì phải có response. Tức là cần tìm hiểu thêm, làm sao để lấy thông tin từ request (VD: lấy từ query, lấy từ body). Còn response thì trả về html hay json hay xml hoặc là file 😃 Vậy thôi à.