Node.js và biến môi trường .env
TIL
491
@100daysTIL
38
White

ngminhtrung viết ngày 09/02/2018

Node.js và biến môi trường .env

Day17

Bài toán của ngày hôm nay:

  • Cần deploy một Node.js / Express app lên heroku hoặc glitch.me, app thì kết nối với database của mLab.
  • Muốn kết nối đến database của mLab thì cần trỏ đến database url (DB-URL) mà mLab cung cấp. Url này có dạng mongodb://<dbuser>:<dbpassword>@ds229878.mlab.com:29878/kdaldaksf phải chứa username và password của Database Users.
  • Nếu đặt luôn username và password trong DB_URL, rồi DB-URL lại được đặt trong app.js, thì nếu push source code lên Github, cả thiên hạ sẽ biết ta là ai. Với dự án mang tính học tập thì đương nhiên chả thằng cha nào để ý, nhưng dự án thương mại, hoặc dự án cá nhân đóng, thì việc để lộ username và password của Database là không được phép.

Cách xử lý: Sử dụng biến môi trường. Mấy hôm nay nhìn thấy process.env suốt, nhưng đọc mấy bài tutorial tiếng Việt mà không thể hiểu nó là cái gì. Hóa ra cũng đơn giản.

Trước tiên process.env là gì?

Node.js khi thực thi sẽ thực hiện 1 loạt tiền trình (process) gì đó. Mình không tìm hiểu chính xác, nhưng process.env là 1 object để chứa tất cả các thông tin về môi trường (máy tính) mà Node.js đang chạy. env là viết tắt của environment.

Tốt nhất, muốn hiểu thì thêm dòng console.log(process.env) vào trong file khởi nguồn của ứng dụng, như của mình là app.js. Thêm vào đâu cũng được. Sau đó chạy ứng dụng bằng npm start. Nó sẽ ra cả loạt thứ, từ hệ điều hành đang chạy, thư mục chứa ứng dụng, phiên bản node.js, ... tầm vài chục cái gì đó.

Ví dụ:

 npm_package_name: 'fcc-learn-npm-package-json',
  npm_package_repository_type: 'git',
  npm_config_prefer_offline: '',
  NODE: '/usr/bin/node',
  LC_ADDRESS: 'en_US.UTF-8',
  XDG_RUNTIME_DIR: '/run/user/1000',
  XDG_SESSION_PATH: '/org/freedesktop/DisplayManager/Session0',
  npm_config_color: 'true',

Một khi ta cần chính xác thông tin nào, ta có thể gọi console.log(process.env.npm_package_name) chẳng hạn, nó sẽ trả về 'fcc-learn-npm-package-json' như ở trên.

Có bổ sung thêm dữ liệu vào process.env được không?

Được. Thông qua 2 thứ:

  1. File .env (vâng. File .env, không có tên file, chỉ có file extension). Đặt ở trong thư mục gốc của app.
  2. NPM package tên là dotenv, cài thông qua npm install dotenv --save. Sau đó thêm dòng require('dotenv').config(); vào ngay đầu file app.js (hoặc file nào là khởi nguồn của app của bạn). Vâng, chỉ cần thế thôi, không cần truyền cái require đó cho 1 biến nào khác. Ghi thế để khỏi thắc mắc hồi hộp.

Sửa file .env như thế nào?

Sửa bằng editor thôi. Chú ý là file .env cần đặt ở trong thư mục gốc. Ban đầu file .env này trống (nếu do bạn tự tạo). Có thể thêm bất kỳ thứ gì tùy thích. Ví dụ, thêm vào file này dòng sau:

VIETNAM="Độc lập, tự do, hạnh phúc"

Không chấm phẩy cuống dòng gì sất. Sau đó trong app.js, thay vì gọi console.log(process.env), ta gọi conso.log(process.env.VIETNAM, kết quả trong console sẽ là Độc lập, tự do, hạnh phúc ngay tắp lự.

Vậy là ta có thể dùng .env để chèn những thứ mình muốn vào process.env, rồi thông qua process.env truyền lại vào ứng dụng của mình.

Ủa thế tại sao không đặt biến trực tiếp trong app.js cho xong?

Tại .evn theo thống nhất của giới lập trình Node.js thì không được commit lên host theo git. Người ta đặt trong gitignore, mỗi lần commit tự động git sẽ bỏ qua .env. Vì vậy, .env sẽ không xuất hiện trên Github theo đường git thông thường (trừ khi cố tình up nó). Còn đối với host mà ta sẽ deploy sản phẩm (ví dụ heroku hay glitch.me), ta sẽ cần vào host và up riêng file này lên. Cho nên những thông tin cần giữ bí mật như username và password sẽ được lưu ở .env.

Ngoài chuyện lưu thông tin bí mật, .evn còn dùng làm gì?

Nó còn dùng để giúp ta chuyển qua lại giữa các môi trường (testing, phát triển, production).

Ví dụ, lúc đang phát triển trên máy, sử dụng localhost cổng 3000 cho server, database cũng cài luôn trên máy (localhost ở 1 cổng 27017 chẳng hạn). Lúc này đây, mọi đường đường dẫn đều trỏ về localhost và các cổng trên.

Ví dụ, mình cài MongoDB trên máy, thì đường dẫn đến database sẽ là:

DB_LOCALHOST="mongodb://localhost:27017/fcc-backend-shortenURL"

nhưng khi deploy lên glitch.me chẳng hạn, database của mLabl là 1 bên thứ 3, đường dẫn lại là:

mLab_URL="mongodb://kippa:kippa696969@ds229878.mlab.com:29878/fcchanoi"

trong đó kippa là username, kippa696969 là password database của mình trên mLab.

Đường dẫn trên sẽ đươc truyền vào mongoose.connect(dbURL).then(...) trong app.js để kết nối đến database.

Vậy thì:

  • trong .env, chỉ cần đặt:
`DB_LOCALHOST="mongodb://localhost:27017/fcc-backend-shortenURL"`
`mLab_URL="mongodb://kippa:kippa696969@ds229878.mlab.com:29878/fcchanoi"`
  • còn trong app.js, ngay phía mấy dòng đầu khai báo import, đặt tiếp:
const dbURL = process.env.DB_LOCALHOST ||  process.env.mLab_URL ;

Việc khai báo dbURL như thế trên sẽ giúp ta những gì?

  • Khi chạy trên localhost để phát triển hoặc kiểm thử, thì dbURL sẽ chứa url của database trên localhost, không cần truy cập đến mLab online làm gì.
  • Khi deploy sản phẩm, chỉ cần xóa phần DB_LOCALHOST trong file .env (vốn chứa trong folder root của host), thì phần process.env.DB_LOCALHOST sẽ bị bỏ qua, const dbURL sẽ nhận giá trị của process.env.mLab_URL.
  • Tất nhiên là sẽ cần cách làm ngon lành hơn chứ không quá thủ công như thế này. Nhưng nguyên lý chung có lẽ vẫn gần gần như thế.

Kết luận:

Với việc sử dụng .env, ta bắn 1 mũi tên mà trúng 2 đích:

  • Giấu các thông tin bí mật (username, password) trong file .env, không được commit thông qua git thông thường.
  • Tận dụng để chuyển qua lại giữa các môi trường ứng với mục đích sử dụng khác nhau.

Tham khảo sau này:

ngminhtrung 09-02-2018

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

ngminhtrung

29 bài viết.
14 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
25 5
Ghi chú: Tiêu đề hoàn toàn mang tính câu view. Bài copy từ blog của tác giả :) Tại sao lại có bài viết này? Một ngày đẹp giời tôi cần kiểm t...
ngminhtrung viết 2 tháng trước
25 5
White
4 11
Nói thực, tôi cũng không biết gì về (Link) cho đến hôm bị cô bạn (Linh Ngô) đè ra cài ngấu nghiến trên máy và bảo cái này là "bắt buộc" nếu dùng Ma...
ngminhtrung viết 1 tháng trước
4 11
White
4 0
Vẽ Spirograph bằng D3.js Chắc hồi trẻ con ai cũng đã từng một lần nghịch 1 cái thước "sáng tạo" tên là "Spirograph" (/ˈspīrəˌɡraf/). Khi ấy ta đặt...
ngminhtrung viết 30 ngày trước
4 0
Bài viết liên quan
White
2 0
D3.js Biểu diễn dữ liệu dạng tree bằng việc trải nó ra trên bản đồ Series Today I Learn trong vòng 100 ngày thử thách bản thân ngày 15. Mỗi ngày 1...
ngminhtrung viết 13 ngày trước
2 0
White
18 1
Toán tử XOR có tính chất: + A XOR A = 0 + 0 XOR A = A Với tính chất này, có thể cài đặt bài toán sau với độ phức tạp O(N) về runtime, và với O(1)...
kiennt viết hơn 1 năm trước
18 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
29 bài viết.
14 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!