Webpack打包后无法访问Dotenv环境变量:导出语法错误排查
解决方案:修复Webpack导出歧义并安全部署Google API密钥到GitHub Pages
错误根源
你遇到的ambiguous indirect export错误,本质是Webpack默认打包输出CommonJS模块,但前端浏览器尝试用ES模块语法导入,两种模块系统不兼容导致导出歧义。同时你的配置存在几个关键问题:
- build脚本错误用
node运行bundle(这是后端执行逻辑,非前端打包流程) - 导出语法混用CommonJS(
module.exports)和ES模块(import) - Webpack配置未指定前端兼容的模块输出格式
分步修复方案
1. 修正Webpack配置(输出ES模块)
更新webpack.config.js,指定输出为ES模块,用DefinePlugin直接注入密钥(比dotenv-webpack更直接):
const webpack = require('webpack'); require('dotenv').config({ path: './.env' }); module.exports = { entry: './src/keys.js', // 重命名文件更清晰 output: { filename: 'keys.bundle.js', library: { type: 'module', // 关键:输出ES模块 }, environment: { module: true, // 启用ES模块支持 }, }, plugins: [ new webpack.DefinePlugin({ 'process.env.GOOGLE_MAPS_KEY': JSON.stringify(process.env.KEY), }), ], experiments: { outputModule: true, // 允许输出ES模块 }, };
2. 重写密钥导出文件(统一ES模块)
新建src/keys.js替代原nodeside.js,用ES模块语法暴露密钥:
// Webpack会在构建时自动替换process.env.GOOGLE_MAPS_KEY为实际密钥 export const GOOGLE_MAPS_KEY = process.env.GOOGLE_MAPS_KEY;
3. 修正package.json脚本
把build脚本改成Webpack打包命令,添加type: module让Node支持ES模块:
{ "type": "module", "dependencies": { "dotenv": "^16.3.1" }, "scripts": { "build": "webpack --mode production" }, "devDependencies": { "webpack": "^5.89.0", "webpack-cli": "^5.1.4" } }
4. 前端导入修正
在js/browsersidemaps.js等文件中,正确导入ES模块:
import { GOOGLE_MAPS_KEY } from '../dist/keys.bundle.js'; console.log(GOOGLE_MAPS_KEY); // 直接用于Google Maps API调用 initMap(GOOGLE_MAPS_KEY);
5. 调整GitHub Actions工作流
确保构建时注入DOTENV_KEY,同时添加部署到GitHub Pages的步骤:
name: Build and Deploy to GitHub Pages on: [push] jobs: build-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: npm install - run: npm run build env: DOTENV_KEY: ${{ secrets.DOTENV_KEY }} # 部署dist目录到GitHub Pages - uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./dist
更适合GitHub Pages的简化方案
因为GitHub Pages是纯静态托管,可直接让Webpack在构建时把密钥替换到前端代码中,无需单独导出模块:
- 前端代码直接使用
process.env.GOOGLE_MAPS_KEY - Webpack的DefinePlugin会在打包时自动将该变量替换为实际密钥
- 最终打包代码不会出现
process.env,仅包含明文密钥(但密钥不会出现在仓库代码中,仅在构建时注入)
同时必须给Google API密钥设置HTTP引用限制,仅允许你的GitHub Pages域名(如your-username.github.io/your-repo)访问,避免密钥被滥用。
内容的提问来源于stack exchange,提问作者Leo-Code
相关产品推荐
相关产品推荐

