flun-env 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/LICENSE +15 -0
- package/README.md +91 -0
- package/env.js +26 -0
- package/index.d.ts +1 -0
- package/index.js +158 -0
- package/install.js +26 -0
- package/package.json +42 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, flun
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# flun-env一个简单易用的 .env 环境变量文件读取工具
|
|
2
|
+
|
|
3
|
+
## 安装
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm i flun-env
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## 特性
|
|
10
|
+
|
|
11
|
+
- ✅ 自动检查并创建 .env 示例文件
|
|
12
|
+
- ✅ 支持 `env.变量名` 的直接调用方式
|
|
13
|
+
- ✅ 支持自定义 .env 文件路径
|
|
14
|
+
- ✅ 自动将变量注入到 `process.env`
|
|
15
|
+
- ✅ 多路径自动查找 .env 文件
|
|
16
|
+
- ✅ 支持注释和空行
|
|
17
|
+
- ✅ 友好的错误提示
|
|
18
|
+
|
|
19
|
+
## .env 文件格式
|
|
20
|
+
|
|
21
|
+
在项目根目录或运行文件根目录创建 `.env` 文件:
|
|
22
|
+
|
|
23
|
+
```env
|
|
24
|
+
# 数据库配置
|
|
25
|
+
DATABASE_URL=mysql://user:password@localhost:3306/dbname
|
|
26
|
+
API_KEY=your_api_key_here
|
|
27
|
+
|
|
28
|
+
# 应用配置
|
|
29
|
+
DEBUG=false
|
|
30
|
+
PORT=3000
|
|
31
|
+
NODE_ENV=development
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API
|
|
35
|
+
|
|
36
|
+
### 属性访问
|
|
37
|
+
- `env.VARIABLE_NAME` - 直接访问变量
|
|
38
|
+
|
|
39
|
+
### 方法
|
|
40
|
+
- `env.get(key, defaultValue)` - 获取变量值
|
|
41
|
+
- `env.has(key)` - 检查变量是否存在
|
|
42
|
+
- `env.getAll()` - 获取所有变量
|
|
43
|
+
- `env.load()` - 重新加载变量
|
|
44
|
+
|
|
45
|
+
## 文件查找顺序
|
|
46
|
+
1. 自定义路径
|
|
47
|
+
2. 当前工作目录的 `.env` 文件
|
|
48
|
+
3. C盘用户主目录的 `.env` 文件
|
|
49
|
+
|
|
50
|
+
## 使用方法
|
|
51
|
+
|
|
52
|
+
### 默认配置(示例)
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
const {env} = require('flun-env');
|
|
56
|
+
|
|
57
|
+
// 直接使用变量
|
|
58
|
+
console.log(env.DATABASE_URL);
|
|
59
|
+
console.log(env.API_KEY);
|
|
60
|
+
console.log('数据库地址:', env.DATABASE_URL);
|
|
61
|
+
console.log('API密钥:', env.API_KEY);
|
|
62
|
+
|
|
63
|
+
// 或者使用方法
|
|
64
|
+
console.log(env.get('DATABASE_URL'));
|
|
65
|
+
if (env.has('SECRET_KEY')) {
|
|
66
|
+
console.log('密钥存在');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 获取所有变量
|
|
70
|
+
const allVars = env.getAll();
|
|
71
|
+
console.log('所有变量:', allVars);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 自定义配置(示例):
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
const { config } = require('flun-env');
|
|
78
|
+
const env = config({
|
|
79
|
+
path: './path/.env', // 自定义路径 (自定义路径如果是相对路径,那么请以工作路径作为基准设置->向上或向下或同级)
|
|
80
|
+
encoding: 'utf8', // 字符集 (默认utf8)
|
|
81
|
+
debug: true // 调试模式 (默认false)
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
console.log(env.PORT); // 访问配置项
|
|
85
|
+
// 其它使用方式同默认配置(示例)...
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 错误处理
|
|
89
|
+
如果未找到 .env 文件,包会自动创建示例文件并退出进程。
|
|
90
|
+
|
|
91
|
+
这个包提供了完整的 .env 文件管理功能,包括自动创建示例文件、错误处理、多路径查找等特性,用户可以通过简单的 `env.变量名` 方式直接访问环境变量
|
package/env.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// 导出示例文件供模块使用
|
|
2
|
+
const exampleLines = [
|
|
3
|
+
'# .nev 环境变量配置文件示例:',
|
|
4
|
+
'# 每行格式: 变量名 = 变量值',
|
|
5
|
+
'# 以 # 开头的行是注释',
|
|
6
|
+
'',
|
|
7
|
+
'DATABASE_URL = mysql://user:password@localhost:3306/dbname',
|
|
8
|
+
'',
|
|
9
|
+
'API_KEY = your_api_key_here',
|
|
10
|
+
'',
|
|
11
|
+
'SECRET_KEY = your_secret_key_here',
|
|
12
|
+
'',
|
|
13
|
+
'DEBUG = false',
|
|
14
|
+
'',
|
|
15
|
+
'PORT = 3000',
|
|
16
|
+
'',
|
|
17
|
+
'# 字符串值不需要引号',
|
|
18
|
+
'APP_NAME = MyApp',
|
|
19
|
+
'',
|
|
20
|
+
'NODE_ENV = development',
|
|
21
|
+
'',
|
|
22
|
+
`# 调用包: const {env} = require('flun-env');`,
|
|
23
|
+
'',
|
|
24
|
+
'# 使用格式: env.变量名'
|
|
25
|
+
];
|
|
26
|
+
module.exports = { exampleLines };
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module 'flun-env';
|
package/index.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const { exampleLines } = require('./env');
|
|
5
|
+
|
|
6
|
+
class EnvLoader {
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.options = { ...options }, this.variables = {}, this.loaded = false, this.load(); // 自动加载
|
|
9
|
+
|
|
10
|
+
// 返回代理实例以实现 env.变量名 的访问方式
|
|
11
|
+
return new Proxy(this, {
|
|
12
|
+
get: (target, prop) => {
|
|
13
|
+
if (prop in target) return target[prop];
|
|
14
|
+
const variables = target.getAll();
|
|
15
|
+
if (prop in variables) return variables[prop];
|
|
16
|
+
return undefined;
|
|
17
|
+
},
|
|
18
|
+
set(target, prop, value) {
|
|
19
|
+
console.warn('⚠️ 警告: 环境变量应在 .env 文件中设置');
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 解析 .env 文件内容
|
|
26
|
+
parse(content) {
|
|
27
|
+
const lines = content.split('\n'), result = {};
|
|
28
|
+
for (let line of lines) {
|
|
29
|
+
line = line.trim(); // 移除前后空白字符
|
|
30
|
+
if (!line || line.startsWith('#')) continue; // 跳过空行和注释
|
|
31
|
+
|
|
32
|
+
// 解析键值对
|
|
33
|
+
const equalsIndex = line.indexOf('=');
|
|
34
|
+
if (equalsIndex === -1) continue; // 跳过无效行
|
|
35
|
+
|
|
36
|
+
const key = line.slice(0, equalsIndex).trim();
|
|
37
|
+
let value = line.slice(equalsIndex + 1).trim();
|
|
38
|
+
|
|
39
|
+
// 移除值两端的引号(如果存在)
|
|
40
|
+
const firstChar = value[0];
|
|
41
|
+
if (firstChar === value.at(-1) && (firstChar === '"' || firstChar === "'"))
|
|
42
|
+
value = value.slice(1, -1);
|
|
43
|
+
|
|
44
|
+
if (key) {
|
|
45
|
+
result[key] = value;
|
|
46
|
+
if (this.options.debug) console.log(`✓ 加载变量: ${key} = ${value}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 查找文件
|
|
54
|
+
findFile(defaultFileName, customPath) {
|
|
55
|
+
let createPath; // 首选创建路径
|
|
56
|
+
|
|
57
|
+
// 1. 如果有传入自定义路径
|
|
58
|
+
if (customPath && customPath !== '.env') {
|
|
59
|
+
createPath = path.isAbsolute(customPath) ? customPath : path.resolve(process.cwd(), customPath);
|
|
60
|
+
|
|
61
|
+
// 检查自定义路径的文件是否存在
|
|
62
|
+
try {
|
|
63
|
+
if (fs.statSync(createPath).isFile()) return { found: true, path: createPath, createPath };
|
|
64
|
+
} catch (error) { }
|
|
65
|
+
return { found: false, path: null, createPath }; // 自定义路径的文件不存在,返回创建路径为自定义路径
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 2. 没有自定义路径,检查默认路径(当前工作目录和系统用户主目录)
|
|
69
|
+
const possiblePaths = [path.join(process.cwd(), defaultFileName), path.join(os.homedir(), defaultFileName)];
|
|
70
|
+
|
|
71
|
+
// 检查每个路径是否存在
|
|
72
|
+
for (const filePath of possiblePaths)
|
|
73
|
+
try {
|
|
74
|
+
if (fs.statSync(filePath).isFile()) return { found: true, path: filePath, createPath: filePath };
|
|
75
|
+
} catch (error) { }
|
|
76
|
+
|
|
77
|
+
// 3. 所有路径都不存在,返回创建路径为当前工作目录
|
|
78
|
+
createPath = path.join(process.cwd(), defaultFileName);
|
|
79
|
+
return { found: false, path: null, createPath };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 创建示例文件
|
|
83
|
+
createExampleFile(filePath, exampleContent) {
|
|
84
|
+
try {
|
|
85
|
+
const dir = path.dirname(filePath);
|
|
86
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); // 确保目录存在
|
|
87
|
+
|
|
88
|
+
fs.writeFileSync(filePath, exampleContent, 'utf8');
|
|
89
|
+
console.log(`✓ 已创建示例文件:${filePath};请编辑环境变量后重新运行程序`), process.exit(1);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error('✗ 创建示例文件失败:', error.message);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 加载环境变量
|
|
96
|
+
load() {
|
|
97
|
+
if (this.loaded) return this.variables;
|
|
98
|
+
|
|
99
|
+
const result = this.findFile('.env', this.options.path);
|
|
100
|
+
if (!result.found) {
|
|
101
|
+
console.log('未找到 .env 文件!💡 正在为您创建...');
|
|
102
|
+
this.createExampleFile(result.createPath, exampleLines.join('\n')); // 创建示例文件
|
|
103
|
+
return this.variables;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
// 读取并解析文件
|
|
108
|
+
const content = fs.readFileSync(result.path, this.options.encoding);
|
|
109
|
+
this.variables = this.parse(content), this.loaded = true;
|
|
110
|
+
|
|
111
|
+
if (this.options.debug) console.log(`✓ 加载了 ${Object.keys(this.variables).length} 个变量`);
|
|
112
|
+
for (const [key, value] of Object.entries(this.variables)) process.env[key] = value; // 将变量设置到 process.env
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error('❌ 读取 .env 文件失败:', error.message), process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
return this.variables;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 获取所有变量
|
|
120
|
+
getAll() {
|
|
121
|
+
return { ...this.variables };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 获取单个变量
|
|
125
|
+
get(key, defaultValue = null) {
|
|
126
|
+
return this.variables[key] || defaultValue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 检查变量是否存在
|
|
130
|
+
has(key) {
|
|
131
|
+
return key in this.variables;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 延迟创建默认实例
|
|
136
|
+
let defaultEnv = null;
|
|
137
|
+
|
|
138
|
+
// 获取默认实例的函数
|
|
139
|
+
function getDefaultEnv() {
|
|
140
|
+
if (!defaultEnv) defaultEnv = new EnvLoader({ path: '.env', encoding: 'utf8', debug: false });
|
|
141
|
+
return defaultEnv;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 导出对象
|
|
145
|
+
module.exports = {
|
|
146
|
+
// 默认的环境变量实例,通过 getter 延迟创建
|
|
147
|
+
get env() {
|
|
148
|
+
return getDefaultEnv();
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
// 配置加载器函数
|
|
152
|
+
config: (options = {}) => {
|
|
153
|
+
// 如果传入的是字符串,则视为路径
|
|
154
|
+
if (typeof options === 'string') options = { path: options };
|
|
155
|
+
const { path = '.env', encoding = 'utf8', debug = false } = options;
|
|
156
|
+
return new EnvLoader({ path, encoding, debug });
|
|
157
|
+
}
|
|
158
|
+
};
|
package/install.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { exampleLines } = require('./env');
|
|
4
|
+
|
|
5
|
+
// 检查项目根目录
|
|
6
|
+
const packageDir = __dirname, projectRoot = path.resolve(packageDir, '../..'), // 向上两级到项目根目录
|
|
7
|
+
projectEnvPath = path.join(projectRoot, '.env');
|
|
8
|
+
// 检查并创建示例文件
|
|
9
|
+
function checkAndCreateEnvFile() {
|
|
10
|
+
console.log('🔍 检查 .env 环境变量文件...'), console.log(`📁 项目根目录: ${projectRoot}`);
|
|
11
|
+
try {
|
|
12
|
+
if (fs.existsSync(projectEnvPath)) return true; // 检查项目根目录
|
|
13
|
+
console.log('⚠️ 在项目根目录未找到 .env 文件,正在创建...');
|
|
14
|
+
|
|
15
|
+
const formattedContent = exampleLines.join('\n'); // 动态处理示例内容
|
|
16
|
+
fs.writeFileSync(projectEnvPath, formattedContent, 'utf8');
|
|
17
|
+
console.log(`✓ 已创建 .env 示例文件: ${projectEnvPath}`), console.log('📝 请在该文件中添加环境变量');
|
|
18
|
+
return true;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error('✗ 创建 .env 文件失败:', error.message);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 执行脚本并导出函数
|
|
25
|
+
if (require.main === module) checkAndCreateEnvFile();
|
|
26
|
+
module.exports = { checkAndCreateEnvFile };
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flun-env",
|
|
3
|
+
"version": "3.0.6",
|
|
4
|
+
"description": "A simple package to read .env environment files",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"postinstall": "node install.js 2>&1",
|
|
9
|
+
"test": "echo \"Test completed\" && exit 0"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"env-init": "./install.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"index.js",
|
|
16
|
+
"install.js",
|
|
17
|
+
"env.js",
|
|
18
|
+
"index.d.ts",
|
|
19
|
+
"CHANGELOG.md"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"env",
|
|
23
|
+
"environment",
|
|
24
|
+
"variables",
|
|
25
|
+
"config",
|
|
26
|
+
"flun"
|
|
27
|
+
],
|
|
28
|
+
"author": "flun <cn@flun.top>",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/flunGit/flun_ENV.git"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://www.npmjs.com/flunGit/flun-env#readme",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/flunGit/flun_ENV/issues"
|
|
36
|
+
},
|
|
37
|
+
"license": "ISC",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=10.0.0"
|
|
40
|
+
},
|
|
41
|
+
"type": "commonjs"
|
|
42
|
+
}
|