DEV Community

Pallat Anchaleechamaikorn
Pallat Anchaleechamaikorn

Posted on

auto load .env กัน

หนึ่งในวิธีที่จะทำให้เรา dev ได้สะดวกขึ้นคือการทำให้พฤติกรรมของ app เราที่ run บนเครื่องมีความเหมือนกับที่ run บน production ให้ได้มากที่สุด ซึ่งหนึ่งในเรื่องนี้ก็คือการ load ค่า configurations ซึ่งความคุ้นเคยในอดีต หลายๆคนจะชินกับการใช้ config file ต่างๆ ไม่ว่าจะเป็น yaml, tomal หรืออื่นๆก็ตาม

แต่พอเอาขึ้น production จริงส่วนใหญ่เราก็ใช้ค่าใน env ซึ่งเป็นคำแนะนำจาก 12factors นั่นเอง

ยกตัวอย่างเวลาผมเขียน Go ในอดีตก็เคยใช้ viper เข้ามาช่วยอยู่พักหนึ่ง เพราะมันยืดหยุ่น ให้สามารถใช้ค่า config จาก file ก็ได้ หรือใช้จาก env ก็ได้ใน code ชุดเดียวกัน แต่ เอาเข้าจริง พฤติกรรมมันก็ต่างกันโดยสิ้นเชิง เพราะถ้าเราไป copy example ของ viper มาใช้ตรงๆ ก็จะพบว่า ถ้าเราไม่โยน config file เข้าไปใน dockerfile มันจะ run ไม่ขึ้น เรามาดู code ตัวอย่างกัน

viper.SetConfigName("config") // name of config file (without extension)
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
viper.AddConfigPath("/etc/appname/")   // path to look for the config file in
viper.AddConfigPath("$HOME/.appname")  // call multiple times to add many search paths
viper.AddConfigPath(".")               // optionally look for config in the working directory
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
    panic(fmt.Errorf("fatal error config file: %w", err))
}
Enter fullscreen mode Exit fullscreen mode

code นี้มันจะ panic เมื่อไม่เจอ config file ซึ่งถ้าเราอ่านมันเข้าใจ เราก็แค่แก้มัน ไม่ให้มัน panic ก็ได้ แต่อย่างไรก็ดีมันก็จะทำให้ พฤติกรรมของ code ที่ทำงานบนเครื่องเรา กับที่ทำงานบน production จริงต่างกันอยู่ดี

วันนี้ก็เลยอยากชวนมาใช้ .env file แทน ซึ่งจำเป็นจะต้องใช้คู่กับ direnv

เริ่มต้นเราก็ install ตามคู่มือกันก่อน และผมก็เลือกใช้ HomeBrew เนื่องจากผมใช้ Mac

brew install direnv

จากนั้นก็ไป hook ตามที่คู่มือบอก ซึ่งผมใช้ zsh ก็เอาบรรทัดนี้ไปวางใน .zshrc

eval "$(direnv hook zsh)"
Enter fullscreen mode Exit fullscreen mode

ทีนี้โดยปกติ direnv จะทำงานคู่กับไฟล์ .envrc โดยเมื่อวางไว้ที่ directory ใดก็ตาม เราก็จะต้องทำการ allow ให้ direnv ยอมโหลดค่าจากไฟล์นี้ก่อนด้วยคำสั่ง

direnv allow
Enter fullscreen mode Exit fullscreen mode

แต่เนื่องจากโดยปกติเรามักจะคุ้นกับการใช้ไฟล์ .env กันมากกว่า แต่ถ้าจะให้ direnv รู้ว่าเราจะใช้ .env แทน ก็จำเป็นจะต้องทำ config กันก่อน โดยเราจะทำไว้ที่ระดับ global กันไปเลย จะได้ไม่ต้องมาทำมันบ่อยๆ

ให้สร้างไฟล์ไว้ที่ .config/direnv/direnv.toml

แล้วใส่เนื้อหานี้ลงไป

[global]
load_dotenv = true
Enter fullscreen mode Exit fullscreen mode

เมื่อทำครบทุกขั้นตอนแล้ว หลังจากนี้ เวลาเราจะ dev อะไรก็ตาม แล้วต้องการใช้ค่า env เป็น configurations เราก็เพียงแค่สร้างไฟล์ .env วางไว้ใน directory นั้น เช่น

PORT=8080
LOG_LEVEL=INFO
Enter fullscreen mode Exit fullscreen mode

และเมื่อมีการแก้ไขไฟล์นี้ หรือสร้างไฟล์นี้ขึ้นมาใหม่ เราก็ต้องทำการ allow มันด้วยคำสั่ง

direnv allow
Enter fullscreen mode Exit fullscreen mode

หลังจาก allow มันแล้ว ตราบเท่าที่ไฟล์นี้ไม่มีการแก้ไขใดใด มันก็จะ auto load ค่าใน .env มาให้เราทุกครั้งที่เราเข้าไปทำงานใน directory นั้นๆ ทีนี้ใน code ของเรา ก็แค่เรียกค่า config มาจาก env ได้โดยตรง แล้วก็จะทำให้ code ที่รันบนเครื่องเรา กับบน prodution ทำงานแบบเดียวกันได้แล้ว

Top comments (0)