Skip to content

🔑 管理环境变量

在项目开发中,处理敏感信息(如 API 密钥)和环境特定配置(如服务端口)是一项核心任务。将这些值硬编码到代码中会带来安全风险和维护困难。最佳实践是通过环境变量来管理它们。

然而在神岛项目中,标准的 dotenv 包在运行时加载变量的方式并不可行。此时,我们需要一个能在 构建时 将环境变量注入代码的工具。

dotenv-webpack 就是解决这个问题的理想选择。它是一个 Webpack 插件,可以在打包过程中读取你的 .env 文件,并将其中的变量替换到代码中。

🤔 为什么不能直接用 dotenv?

这与神岛平台的运行机制有关。神岛平台只接受 JavaScript 文件(例如 server.jsclient.js)。创作者无法将项目中的 .env 文件或其他辅助文件一同上传到平台。

  • dotenv (运行时方案 - 不可行 ❌): 它的工作方式是在代码启动时,去服务器的文件系统中寻找并读取 .env 文件来加载环境变量。由于我们无法上传 .env 文件,这个库在平台上会因为找不到文件而彻底失效。

  • dotenv-webpack (构建时方案 - 可行 ✅): 它在创作者的本地计算机上运行构建命令时工作。它会读取创作者本地的 .env 文件,然后像"查找与替换"一样,将代码中所有 process.env.VAR 的引用替换成 .env 文件里的真实字符串值,并生成最终的 JS 文件。

因此,上传到平台的 JS 文件已经是一个包含了所有配置值的"成品",它本身不再需要去外部寻找 .env 文件。这是在神岛项目中正确使用环境变量的关键。

✨ 核心优势

优势说明
🛡️ 安全性将密钥、密码等敏感信息与源代码分离,避免其泄露到 Git 等版本控制系统中
⚙️ 构建时注入变量在打包时被直接注入,最终代码中不包含对 dotenv 的依赖,符合平台要求
🤝 环境一致性确保无论在哪个环境部署,代码都能获取到正确的配置

📦 安装与配置

⬇️ 安装

由于 dotenv-webpack 只在开发和构建阶段使用,我们将其安装为开发依赖 (--save-dev)。

bash
npm install dotenv-webpack --save-dev

📝 创建 .env 文件

在项目根目录(与 package.json 同级)创建一个 .env 文件。

txt
# .env

# 服务配置
PORT=3000
HOST=

# API 密钥
API_KEY=ABC-123-XYZ-456

⚙️ 配置 Webpack

在你的 webpack.config.js 文件中引入并使用该插件。

javascript
// webpack.config.js
const Dotenv = require("dotenv-webpack");

module.exports = {
  // ... 其他 webpack 配置,如 entry, output, module ...

  plugins: [
    new Dotenv({
      // 查找根目录下的.env文件
      path: path.resolve(__dirname, "../.env"),
    }),
  ],

  // ...
};

🚀 在代码中使用

配置好 Webpack 后,你就可以在代码中直接使用 process.env 来访问这些变量了。

javascript
// Webpack 在打包时已经将 .env 中的变量注入到 process.env
const port = process.env.PORT || 8080;

// 验证 API 密钥是否可用
// 在打包后的代码中,process.env.API_KEY 会被替换为实际的值
console.log(`API 密钥: ${process.env.API_KEY},端口:${port}`); // API 密钥: ABC-123-XYZ-456,端口:3000

💡 常见用途

以下是一些常见场景,创作者可以利用 .env 文件让项目变得更灵活、更安全。

用途说明与示例
🔌 管理第三方密钥 如果你的作品需要连接外部服务(如排行榜 API、数据统计),应将 API Key 存放在 .env 中。
示例: LEADERBOARD_API_KEY=abc-123-def-456
🚩 控制功能开关 无需修改代码即可轻松启用或禁用某个功能,非常适合用于测试新功能或控制活动开关。
示例: ENABLE_NEW_YEAR_EVENT=true
代码: if (process.env.ENABLE_NEW_YEAR_EVENT === 'true') { /* ... */ }
🔧 区分开发与生产 为本地测试和线上正式版设置不同的参数,例如 API 服务器地址。
示例: 本地用 API_URL=http://localhost:3000, 线上用 API_URL=https://api.mygame.com
🐛 开启调试模式 通过一个开关控制是否输出详细的调试日志,方便开发时排查问题。
示例: DEBUG_MODE=true
代码: if (process.env.DEBUG_MODE === 'true') { console.log('Debug info...'); }

🌟 最佳实践

实践类别建议
🚫 Git 忽略 • 务必将 .env 文件添加到 .gitignore
• 永远不要将包含敏感信息的文件提交到版本控制系统
📄 示例文件 • 创建一个 .env.example 文件作为团队配置模板
• 该文件应包含所有必需的变量名,但值为示例或空
.env.example 文件应当提交到 Git 仓库

⚠️ 重要注意事项:避免运行时错误

由于 dotenv-webpack 插件的工作原理是 在构建时进行文本替换,因此存在一个非常关键的细节需要注意,否则会导致代码在神岛平台上运行失败。

问题根源: ReferenceError: process is not defined

  • 当你在代码中写入 process.env.MY_VARIABLE 时,dotenv-webpack 会在你的 .env 文件中寻找 MY_VARIABLE
  • 如果找到了,它会把 process.env.MY_VARIABLE 替换成你在文件中定义的值(一个字符串)。
  • 如果没有找到,插件 不会进行任何替换。你的最终代码中将保留 process.env.MY_VARIABLE 这段原始代码。
  • 由于神岛的客户端/服务端脚本运行环境 不是标准的 Node.js 环境,其中并不存在 process 这个全局对象。
  • 因此,当代码尝试访问不存在的 process 对象时,会立即抛出 ReferenceError: process is not defined 错误。

✅ 如何规避

最简单且最可靠的方法是:确保你在代码中使用的每一个 process.env 变量都在 .env 文件中有定义。

即便是某个变量暂时不需要值,也应该在 .env 文件中为其保留一个空条目。

txt
# .env

# 正确的做法
API_URL=https://my-api.com
EVENT_NAME=NewYearEvent

# 即使暂时不用,也需要定义,否则代码中用到 process.env.DEBUG_FLAG 会报错
DEBUG_FLAG=

遵循此规则可以完全避免 ReferenceError,确保你的代码在神岛平台上稳定运行。

📝 总结

dotenv-webpack 是在 Webpack 项目中管理环境变量的便捷工具。通过遵循最佳实践并注意安全风险,可以极大地改善项目的配置管理流程。对于神岛开发者来说,这是分离配置与代码、提升协作效率的有效手段。