为何我的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,步骤如下:
- 在项目根目录创建
.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 - 修改
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 } }; - 重启
ionic serve即可,Angular CLI会自动加载.env中的变量。
方案二:自定义Webpack配置兼容dotenv(不推荐)
如果坚持使用dotenv,需要配置Webpack兼容浏览器环境:
- 安装依赖:
npm install dotenv-webpack @angular-builders/custom-webpack --save-dev - 在项目根目录创建
webpack.config.js:const Dotenv = require('dotenv-webpack'); module.exports = { plugins: [new Dotenv()] }; - 修改
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", // 保留原有其他配置 } } - 修改
environment.ts,删除require('dotenv').config(),直接使用process.env(变量名无需前缀)。
内容的提问来源于stack exchange,提问作者tsukingo
相关产品推荐
相关产品推荐

