You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的Ionic/Angular应用编译失败?寻求技术帮助

问题:Ionic + Angular 集成Firebase时ionic serve编译失败

我用Ionic结合Angular开发应用,刚完成通过environment.ts和dotenv文件配置Firebase的操作,但运行ionic serve时项目编译失败,终端堆栈跟踪信息如下:

[ng] Warning: C:\Users\foo\projects\app\src\environments\environment.ts depends on 'dotenv'. CommonJS or AMD dependencies can cause optimization bailouts.
[ng] For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
[ng]
[ng]
[ng]
[ng] ../../node_modules/dotenv/lib/main.js:24:11-24 - Error: Module not found: Error: Can't resolve 'fs' in 'C:\Users\foo\node_modules\dotenv\lib'
[ng]
[ng] ../../node_modules/dotenv/lib/main.js:25:13-28 - Error: Module not found: Error: Can't resolve 'path' in 'C:\Users\foo\node_modules\dotenv\lib'
[ng]
[ng] BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
[ng] This is no longer the case. Verify if you need this module and configure a polyfill for it.
[ng] 
[ng] If you want to include a polyfill, you need to:
[ng]    - add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
[ng]    - install 'path-browserify'
[ng] If you don't want to include a polyfill, you can use an empty module like this:
[ng]    resolve.fallback: { "path": false }
[ng]
[ng] ../../node_modules/dotenv/lib/main.js:26:11-24 - Error: Module not found: Error: Can't resolve 'os' in 'C:\Users\foo\node_modules\dotenv\lib'
[ng]
[ng] BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
[ng] This is no longer the case. Verify if you need this module and configure a polyfill for it.
[ng]
[ng] If you want to include a polyfill, you need to:
[ng]    - add a fallback 'resolve.fallback: { "os": require.resolve("os-browserify/browser") }'
[ng]    - install 'os-browserify'
[ng] If you don't want to include a polyfill, you can use an empty module like this:
[ng]    resolve.fallback: { "os": false }
[ng]
[ng]
[ng] × Failed to compile.

相关代码文件:

main.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));

environment.ts

// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.

require('dotenv').config();

export const environment = {
  production: false,
  firebase: {
    apiKey: process.env["ANGULAR_APP_API_KEY"],
    authDomain: process.env["ANGULAR_APP_DOMAIN"],
    projectId: process.env["ANGULAR_APP_PROJECT_ID"],
    storageBucket: process.env["ANGULAR_APP_BUCKET_ID"],
    messagingSenderId: process.env["ANGULAR_APP_MESSAGING_ID"],
    appId: process.env["ANGULAR_APP_APP_ID"]
  }
};

/*
 * For easier debugging in development mode, you can import the following file
 * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
 *
 * This import should be commented out in production mode because it will have a negative impact
 * on performance if an error is thrown.
 */
// import 'zone.js/plugins/zone-error';  // Included with Angular CLI.

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

/**
 * importing firebase tools
 */

import { AngularFireModule } from '@angular/fire/compat';
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
import { environment } from 'src/environments/environment';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule, 
    IonicModule.forRoot(), 
    AppRoutingModule, 
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireAuthModule
  ],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
  bootstrap: [AppComponent],
})
export class AppModule {}

解决方法

错误原因

dotenv是Node.js环境下的工具,依赖fs、path、os等Node.js核心模块,但Angular编译的是浏览器端代码,Webpack 5不再默认提供这些模块的polyfill,因此导致编译报错。

方案一:使用Angular CLI原生环境变量(推荐)

Angular CLI自带环境变量支持,无需依赖dotenv,步骤如下:

  1. 在项目根目录创建.env文件,变量名必须以NG_APP_开头:
    NG_APP_API_KEY=你的Firebase API Key
    NG_APP_DOMAIN=你的Firebase Auth Domain
    NG_APP_PROJECT_ID=你的Firebase Project ID
    NG_APP_BUCKET_ID=你的Firebase Storage Bucket
    NG_APP_MESSAGING_ID=你的Firebase Messaging Sender ID
    NG_APP_APP_ID=你的Firebase App ID
    
  2. 修改environment.ts,删除require('dotenv').config(),直接使用process.env:
    export const environment = {
      production: false,
      firebase: {
        apiKey: process.env.NG_APP_API_KEY,
        authDomain: process.env.NG_APP_DOMAIN,
        projectId: process.env.NG_APP_PROJECT_ID,
        storageBucket: process.env.NG_APP_BUCKET_ID,
        messagingSenderId: process.env.NG_APP_MESSAGING_ID,
        appId: process.env.NG_APP_APP_ID
      }
    };
    
  3. 重启ionic serve即可,Angular CLI会自动加载.env中的变量。

方案二:自定义Webpack配置兼容dotenv(不推荐)

如果坚持使用dotenv,需要配置Webpack兼容浏览器环境:

  1. 安装依赖:
    npm install dotenv-webpack @angular-builders/custom-webpack --save-dev
    
  2. 在项目根目录创建webpack.config.js:
    const Dotenv = require('dotenv-webpack');
    
    module.exports = {
      plugins: [new Dotenv()]
    };
    
  3. 修改angular.json,替换build和serve的builder为自定义Webpack:
    "architect": {
      "build": {
        "builder": "@angular-builders/custom-webpack:browser",
        "options": {
          "customWebpackConfig": {
            "path": "./webpack.config.js"
          },
          // 保留原有其他配置
        }
      },
      "serve": {
        "builder": "@angular-builders/custom-webpack:dev-server",
        // 保留原有其他配置
      }
    }
    
  4. 修改environment.ts,删除require('dotenv').config(),直接使用process.env(变量名无需前缀)。

内容的提问来源于stack exchange,提问作者tsukingo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:07:13