在 Seuqelize 中使用環境變數的方式

只是個設定,但卻踩了不少雷。

簡述

首先來看一下 官方的教學 是怎麼說的:

This is a special configuration file. It lets you specify the following options that you would usually pass as arguments to CLI:

Some scenarios where you can use it:

  • You want to override default path to migrations, models, seeders or config folder.
  • You want to rename config.json to something else like database.json
  • And a whole lot more. Let’s see how you can use this file for custom configuration.

To begin, let’s create the .sequelizerc file in the root directory of your project, with the following content:

1
2
3
4
5
6
7
8
9
// .sequelizerc
const path = require('path');

module.exports = {
'config': path.resolve('config', 'database.json'),
'models-path': path.resolve('db', 'models'),
'seeders-path': path.resolve('db', 'seeders'),
'migrations-path': path.resolve('db', 'migrations')
};

With this config you are telling the CLI to:

  • Use config/database.json file for config settings;
  • Use db/models as models folder;
  • Use db/seeders as seeders folder;
  • Use db/migrations as migrations folder.

OK,簡單來說就是在你的專案根目錄寫一個 .sequelizerc 的設定檔,裡面可以指定 config / model 和 seed 的路徑位置。

但我試過了,沒有用就是沒有用。

我爬過 Stackoverflow 也爬過 GitHub issue,有人說要把 .sequelizerc 放在「不是根目錄的位置」才讀的到,這個我也試過,一樣沒效。所以等一下會解釋我最後是怎麼解決的。

真正的解法

首先第一步是先去改寫原本用 sequelize-cli init 後產生的 config.json。

改這個是因為我們希望在裡面使用環境變數,但 JSON 只能寫純文字沒辦法寫變數,所以得先把它變成 config.js,再搭配 dotenv 來使用。總而言之,寫好的內容大概會是這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// config/json -> config.js

require('dotenv').config(); // <- 記得一定要引入,不然你沒辦法用

module.exports = {
"development": {
"username": process.env.DB_USERNAME, // 方法一
"password": process.env.DB_PASSWORD, // 方法一
"database": process.env.DB_DATABASE, // 方法一
"host": "127.0.0.1",
"dialect": "mysql",
"use_env_variable": "DB_URL" // 方法二
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}

如果有專心看註解應該就會注意到有兩種寫法,第一種是把資料分別填入到每個欄位,第二種是透過 use_env_variable(Sequelize 提供的另一種格式)來設定。這兩種我測試結果都是 OK 的,所以看你喜歡用哪個就用哪個吧。

不過特別強調一下,use_env_variable 要填入的值是「環境變數的名稱」,不是「你想傳入的值」。這個要搞清楚,不要像我一樣傻傻的。

接下來是下一個步驟,如果按照剛剛的官方說明你得去新建一個 .sequelizerc 然後設定 config 去讀取剛剛寫好的 config.js,不過我一開始說過了這對我無效。

我的做法是直接到 ./models/index.js 改內容:

1
2
3
4
5
6
7
8
9
'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
// 原本是引入 config.json,直接改成 config.js
const config = require(__dirname + '/../config/config.js')[env];

當時為了研究這東西還特地花時間看一下這整段 code 是在幹嘛用的,有興趣知道的話可以參考這篇:從解讀 Sequelize 的執行檔來學習 Node.js 的檔案相關 API

總而言之,把這個路徑指向你的設定檔就好了。如果讀取不到通常是你路徑寫錯了,可以用 console 印出來檢查看看。

沒意外的話,到這一步就全部設定好了,恭喜恭喜。

關於 Express 中的 session-secret mentor-program-day109
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×