Code Monkey home page Code Monkey logo

dotenv-run's Introduction

dotenv-run

monthly downloads

dotenv-run is a collection of packages that use dotenv to support loading environment variables from .env files with multiple integrations.

Here are some of the benefits of using dotenv-run:

  • Monorepo ✨: supports monorepo projects with multiple applications.
  • Universal: supports multiple integrations including CLI, Webpack, Rollup, Vite, ESbuild and Angular.
  • TypeScript: supports TS projects with type definitions for process.env and import.meta.env.
  • ESM: supports process.env and import.meta.env in ESM modules.
  • Secure: supports filtering environment variables by prefix.

Integrations

Integration Package Status
CLI @dotenv-run/cli
Core @dotenv-run/core
ESBuild @dotenv-run/esbuild
Rollup @dotenv-run/rollup
Vite @dotenv-run/rollup
Node.js preload @dotenv-run/load
Angular @ngx-env/builder

Quick start

Assuming you have the following monorepo structure:

platform
├── apps
│   ├── vite-app
│   ├── ng-app
│   └── esbuild-app
│   │   ├── .env.local # API_BASE=http://localhost:3001
│   │   ├── package.json
│   │   └── webapp.config.mjs
├── libs
│   └── rollup-lib
│       ├── package.json
│       └── rollup.config.mjs
├── .env.dev # API_BASE=https://dev.dotenv.run
├── .env.prod # API_BASE=https://prod.dotenv.run
├── .env # API_USERS=$API_BASE/api/v1/users;API_AUTH=https://$API_BASE/auth
├── nx.json
└── package.json

and the following dotenv-run options:

{
  "verbose": true, // print debug information
  "unsecure": true, // display environment variables values
  "root": "../..", // root directory to search for .env files
  "environment": "dev", // environment to load (default: NODE_ENV)
  "files": [".env"], // .env files to load (default: .env)
  "prefix": "^API_" // prefix to filter environment variables (used with bundlers)
}

dotenv-run will search and load .env.* files located in the root workspace /home/code/platform down to the current working directory of the application.

- Root directory: /home/code/platform
- Working directory:  /codes/code/platform/apps/esbuild-app
- Files: .env
- Environment: dev
- Environment files:
 ✔ /home/code/platform/apps/esbuild-app/.env.local
 ✔ /home/code/platform/.env.dev
 ✔ /home/code/platform/.env
- Environment variables: API (Unsecure Mode)
 ✔ API_USERS http://localhost:3001/api/v1/users
 ✔ API_AUTH https://localhost:3001/auth

@dotenv-run/cli

@dotenv-run/cli is a standalone CLI that can be used to run a script.

❯ npx dotenv-run

  Usage: dotenv-run [options] -- <command>

  Options:
    -v, --verbose [regexp]         display debug information
    -u, --unsecure                 display environment variables values
    -e, --env [environment]        environment to load (default: NODE_ENV)
    -r, --root                     root directory to search for .env files
    -f, --file [.env,.secrets]     .env files to load (default: .env)
    -h, --help                     output usage information

  Examples:
    dotenv-run -d
    dotenv-run -- npm start
    dotenv-run -r ../.. -f .env,.secrets -- npm start
    dotenv-run -f ../.env,../.env.api -- npm start

@dotenv-run/core

@dotenv-run/core is the core package that can be used to load environment variables from .env files.

env({
  root: "../..",
  verbose: true,
  prefix: "^API_",
  files: [".env"],
});

@dotenv-run/esbuild

@dotenv-run/esbuild is a plugin for esbuild that can be used to inject environment variables into your applications.

import { dotenvRun } from "@dotenv-run/esbuild";

await build({
  write: false,
  bundle: true,
  entryPoints: [`test/app.js`],
  plugins: [
    dotenvRun({
      verbose: true,
      root: "../../",
      prefix: "^API",
    }),
  ],
});

@ngx-env/builder

@ngx-env/builder is a plugin for Angular CLI and a wrapper around @dotenv-run/esbuild or @dotenv-run/webpack that can be used to inject environment variables into your Angular applications.

Demos

Quick start

ng add @ngx-env/builder

Environment variables should start with NG_APP_ prefix, you can define a custom prefix.

NG_APP_VERSION=$npm_package_version
NG_APP_COMMIT=$GITHUB_SHA
NG_APP_ENABLE_SENTRY=false
@Component({
  selector: "app-footer",
  template: `{{ branch }} - {{ commit }}`,
  standalone: true,
})
export class MainComponent {
  branch = import.meta.env.NG_APP_BRANCH_NAME; // Recommended
  commit = process.env.NG_APP_COMMIT; // Deprecated
}
<!-- index.html -->
<head>
  <title>NgApp on %NG_APP_BRANCH_NAME% - %NG_APP_COMMIT%</title>
</head>

Configuration options can be passed to @ngx-env/builder using ngxEnv section in angular.json file.

{
  "builder": "@ngx-env/builder:application",
  "options": {
    "ngxEnv": {
      "verbose": true,
      "root": "../..",
      "prefix": "^NG_APP_"
    }
  }
}

You can find the full @ngx-env/builder documentation here.

@dotenv-run/webpack

@dotenv-run/webpack is a plugin for webpack that can be used to inject environment variables into your applications.

import { DotenvRunPlugin } from "@dotenv-run/webpack";
import path from "path";

const __dirname = path.resolve();

export default {
  entry: "./src/index.js",
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "dist"),
  },
  plugins: [
    new DotenvRunPlugin(
      { prefix: "^API", verbose: true, root: "../.." },
      __dirname
    ),
  ],
};

@dotenv-run/rollup

@dotenv-run/rollup is a plugin for rollup that can be used to inject environment variables into your applications.

import env from "@dotenv-run/rollup";

export default {
  input: "src/index.js",
  output: {
    file: "dist/index.js",
  },
  plugins: [env({ prefix: "API", verbose: true, root: "../../.." })],
};

Credits

License

MIT © Chihab Otmani

dotenv-run's People

Contributors

chernodub avatar chihab avatar luca-peruzzo avatar mostafa8026 avatar otonielguajardo avatar soub4i avatar yonguelink avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

dotenv-run's Issues

SourceMap not working with Angular 13

Hi!
After try this package i see some problem with latest Angular version. There not have any sourcemap during serve in developpement mode.
Did some one have this issue and/or have any solution to solve this trouble?
Thanks!

blank defaultConfiguration throws Webpack warnings during build

I added this neat package (which works nicely in another project) to an existing project which has been migrated to angular 12 in the past.

When running ng serve, i.e. using the default environment, we get a slew of these warnings, without it affecting the app or .env functionality otherwise:

Warning: DefinePlugin
Conflicting values for 'process.env.NODE_ENV'

Apparently the angular.json has an empty "defaultConfiguration": "" line and is also not invoked with a specific environment by default. Production builds do not have this issue, likely as that has a specific environment.

The readme says that NODE_ENV should default to 'development', but in this case it is undefined, probably because { browserTarget.configuration is also undefined.
I changed dev-server/index.js to default to 'development': { env: browserTarget.configuration || 'development' }.

…but I am not sure whether he warning is the intended behavior or our project setup is somewhat broken.

Issue while building with v17 when SSR is disabled

Hi I am facing this error while building an angular application (no server or ssr) with the ngx-env/builder. The build succeeds and just straight after that I am receiving this error with an exit code 1. ng serve works fine

✖ NGX_ENV: Cannot read index.html in dist folder
✖ Error: ENOENT: no such file or directory, open '/Users/princegupta/mykaarma/mykaarma-js-starter-template/dist/demo-app/server/index.server.html'

Versions
"@ngx-env/builder": "^17.0.0-alpha.0"
"@angular/cli": "^17.0.0",
"@angular/compiler-cli": "^17.0.0",

Angular.json
This is basically a brand new application with few libraries installed and the environments configured

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "demo-app": {
      "projectType": "application",
      "schematics": {},
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@ngx-env/builder:application",
          "options": {
            "baseHref": "/demo-app",
            "outputPath": "dist/demo-app",
            "index": "src/index.html",
            "browser": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": [
              "@angular/material/prebuilt-themes/indigo-pink.css",
              "node_modules/primeng/resources/themes/md-light-indigo/theme.css",
              "node_modules/primeng/resources/primeng.min.css",
              "src/styles.css"
            ],
            "scripts": [],
            "sourceMap": true,
            "optimization": true,
            "outputHashing": "all",
            "budgets": [
              {
                "type": "initial",
                "maximumWarning": "500kb",
                "maximumError": "1mb"
              },
              {
                "type": "anyComponentStyle",
                "maximumWarning": "2kb",
                "maximumError": "4kb"
              }
            ]
          },
          "configurations": {
            "prod": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "sourceMap": false
            },
            "qa-aws": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.qa-aws.ts"
                }
              ]
            },
            "devvm": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.devvm.ts"
                }
              ]
            },
            "local": {
              "optimization": false,
              "extractLicenses": false
            }
          },
          "defaultConfiguration": "prod"
        },
        "serve": {
          "builder": "@ngx-env/builder:dev-server",
          "configurations": {
            "prod": {
              "buildTarget": "demo-app:build:prod",
              "proxyConfig": "src/proxy.conf.json"
            },
            "qa-aws": {
              "buildTarget": "demo-app:build:qa-aws",
              "proxyConfig": "src/proxy.conf.json"
            },
            "devvm": {
              "buildTarget": "demo-app:build:devvm",
              "proxyConfig": "src/proxy.conf.json"
            },
            "local": {
              "buildTarget": "demo-app:build:local"
            }
          },
          "defaultConfiguration": "local"
        },
        "extract-i18n": {
          "builder": "@ngx-env/builder:extract-i18n",
          "options": {
            "buildTarget": "demo-app:build"
          }
        },
        "test": {
          "builder": "@ngx-env/builder:karma",
          "options": {
            "polyfills": ["zone.js", "zone.js/testing"],
            "tsConfig": "tsconfig.spec.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": [
              "@angular/material/prebuilt-themes/indigo-pink.css",
              "node_modules/primeng/resources/themes/md-light-indigo/theme.css",
              "node_modules/primeng/resources/primeng.min.css",
              "node_modules/primeicons/primeicons.css",
              "src/styles.css"
            ],
            "scripts": []
          }
        },
        "lint": {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
          }
        }
      }
    }
  },
  "cli": {
    "schematicCollections": ["@angular-eslint/schematics"]
  }
}

Not working with ng v13

Hi,

I have installed(ng add @ngx-env/builder) this dependency in an angular project with version: 13.0.0 and when I try to serve it fails. I get the next error

[error] TypeError: Cannot destructure property 'styles' of 'buildOptions.sourceMap' as it is undefined. at getBrowserConfig (/mypath/node_modules/@angular-devkit/build-angular/src/webpack/configs/browser.js:18:21) at /mypath/node_modules/@angular-devkit/build-angular/src/builders/dev-server/index.js:127:44 at /mypath/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js:72:16 at generateWebpackConfig (/mypath/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js:61:40) at async generateBrowserWebpackConfigFromContext (/mypath/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js:123:20) at async generateI18nBrowserWebpackConfigFromContext (/mypath/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js:70:20) at async setup (/mypath/node_modules/@angular-devkit/build-angular/src/builders/dev-server/index.js:124:47)

Thanks

@ngx-env/builder Mistargets File Path for index.server.html. ( Nx + Angular ) monorepo

I'm currently facing an issue with @ngx-env/builder. During the build(production) process, an error shows up that says the builder couldn't find the file index.server.html. Here's the error message I'm getting:

Failed to replace variables in /Users/abdulali/dev/silicon/apps/client/dist/apps/client/server/index.server.html
Error: ENOENT: no such file or directory, open '/Users/abdulali/dev/silicon/apps/client/dist/apps/client/server/index.server.html'

Screenshot 2024-01-24 at 3 04 10 AM

and it just works! even with this error I can use .env and pass the env variable during the build :)

However, my index.server.html file seems to be correctly generated and is located on this path

/Users/abdulali/dev/silicon/dist/apps/client/server/index.server.html.

After doing a bit of digging, it looks like the issue stems from how @ngx-env/builder is trying to construct the path to index.server.html. It seems to be basing this on our project's current working directory but is not correctly considering the output directory setting from the project.json file (which is dist/apps/client).
Here's the setting from the buildWithPlugin function in @ngx-env/builder/dist/builders/application/index.js:

(0, esbuild_index_html_1.indexHtml)((0, path_1.join)(cwd, options.outputPath.toString()), raw, !!options.ssr);

From my understanding, the outcome of the above is apps/client/dist/apps/client but according to our project.json, it should be just dist/apps/client

I'm not sure how to go about resolving this issue. If anyone has encountered a similar issue or has any guidance, it would be greatly appreciated.

additional details
folder tree sample

.
├── Dockerfile
├── README.md
├── apps
│   ├── api
│   ├── client
│   │   ├── jest.config.ts
│   │   ├── project.json
│   │   ├── proxy.conf.json
│   │   ├── server.ts
│   │   ├── src
│   │   │   ├── app
│   │   │   ├── assets
│   │   │   ├── env.d.ts
│   │   │   ├── environments
│   │   │   │   ├── environment.development.ts
│   │   │   │   └── environment.ts
│   │   │   ├── index.html
│   │   │   ├── main.server.ts
│   │   │   ├── main.ts
│   │   │   └── test-setup.ts
│   │   ├── tsconfig.app.json
│   │   ├── tsconfig.editor.json
│   │   ├── tsconfig.json
│   │   └── tsconfig.spec.json
├──dist/
└── apps
    └── client
        ├── 3rdpartylicenses.txt
        ├── browser
        │   ├── index.html
        │   ├── main-WRO5BJZ2.js
        │   ├── polyfills-LZBJRJJE.js
        ├── prerendered-routes.json
        └── server
            ├── index.server.html
            ├── main.server.mjs
            ├── polyfills.server.mjs
            ├── render-utils.server.mjs
            └── server.mjs
├── migrations.json
├── nx.json
├── package.json
├── tsconfig.base.json
└── yarn.lock

project.json

{
  "name": "client",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "prefix": "org",
  "sourceRoot": "apps/client/src",
  "tags": [],
  "targets": {
    "build": {
      "executor": "@ngx-env/builder:application",
      "outputs": ["{options.outputPath}"],
      "options": {
        "allowedCommonJsDependencies": ["undici"],
        "outputPath": "dist/apps/client",
        "index": "apps/client/src/index.html",
        "browser": "apps/client/src/main.ts",
        "polyfills": ["zone.js"],
        "tsConfig": "apps/client/tsconfig.app.json",
        "inlineStyleLanguage": "scss",
        "assets": ["apps/client/src/favicon.ico", "apps/client/src/assets"],
        "styles": ["apps/client/src/styles.scss"],
        "scripts": [],
        "server": "apps/client/src/main.server.ts",
        "prerender": true,
        "ssr": {
          "entry": "apps/client/server.ts"
        }
      },
      "configurations": {
        "production": {
          "budgets": [
            {
              "type": "initial",
              "maximumWarning": "500kb",
              "maximumError": "2mb"
            },
            {
              "type": "anyComponentStyle",
              "maximumWarning": "2kb",
              "maximumError": "4kb"
            }
          ],
          "outputHashing": "all"
        },
        "development": {
          "optimization": false,
          "extractLicenses": false,
          "sourceMap": true,
          "fileReplacements": [
            {
              "replace": "apps/client/src/environments/environment.ts",
              "with": "apps/client/src/environments/environment.development.ts"
            }
          ]
        }
      },
      "defaultConfiguration": "production"
    },
    "serve": {
      "executor": "@ngx-env/builder:dev-server",
      "configurations": {
        "production": {
          "buildTarget": "client:build:production"
        },
        "development": {
          "buildTarget": "client:build:development"
        }
      },
      "defaultConfiguration": "development",
      "options": {
        "proxyConfig": "apps/client/proxy.conf.json"
      }
    },
    "extract-i18n": {
      "executor": "@ngx-env/builder:extract-i18n",
      "options": {
        "buildTarget": "client:build"
      }
    },
    "lint": {
      "executor": "@nx/eslint:lint",
      "outputs": ["{options.outputFile}"]
    },
    "test": {
      "executor": "@ngx-env/builder:karma",
      "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
      "options": {
        "jestConfig": "apps/client/jest.config.ts"
      }
    },
    "serve-static": {
      "executor": "@nx/web:file-server",
      "options": {
        "buildTarget": "client:build",
        "staticFilePath": "dist/apps/client/browser"
      }
    }
  }
}

package.json

"dependencies": {
    "@angular/animations": "~17.0.0",
    "@angular/cdk": "^17.0.1",
    "@angular/common": "~17.0.0",
    "@angular/compiler": "~17.0.0",
    "@angular/core": "~17.0.0",
    "@angular/fire": "^17.0.0",
    "@angular/forms": "~17.0.0",
    "@angular/material": "^17.0.1",
    "@angular/platform-browser": "~17.0.0",
    "@angular/platform-browser-dynamic": "~17.0.0",
    "@angular/platform-server": "~17.0.0",
    "@angular/router": "~17.0.0",
    "@angular/ssr": "~17.0.0",
    "@ngrx/component-store": "17.0.1",
    "@ngrx/effects": "17.0.1",
    "@ngrx/entity": "17.0.1",
    "@ngrx/router-store": "17.0.1",
    "@ngrx/store": "17.0.1",
    "@ngx-env/builder": "^17.1.1",
    "@nx/angular": "17.2.3",
    "express": "~4.18.2",
    "firebase-admin": "^12.0.0",
    "firebase-functions": "^4.5.0",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.14.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~17.0.0",
    "@angular-devkit/core": "~17.0.0",
    "@angular-devkit/schematics": "~17.0.0",
    "@angular-eslint/eslint-plugin": "~17.0.0",
    "@angular-eslint/eslint-plugin-template": "~17.0.0",
    "@angular-eslint/template-parser": "~17.0.0",
    "@angular/cli": "~17.0.0",
    "@angular/compiler-cli": "~17.0.0",
    "@angular/language-service": "~17.0.0",
    "@ngrx/schematics": "17.0.1",
    "@ngrx/store-devtools": "17.0.1",
    "@nx/cypress": "17.2.3",
    "@nx/eslint": "17.2.3",
    "@nx/eslint-plugin": "17.2.3",
    "@nx/jest": "17.2.3",
    "@nx/js": "17.2.3",
    "@nx/web": "17.2.3",
    "@nx/workspace": "17.2.3",
    "@schematics/angular": "~17.0.0",
    "@swc-node/register": "~1.6.7",
    "@swc/core": "~1.3.85",
    "@types/express": "4.17.14",
    "@types/jest": "^29.4.0",
    "@types/node": "18.16.9",
    "@typescript-eslint/eslint-plugin": "^6.9.1",
    "@typescript-eslint/parser": "^6.9.1",
    "autoprefixer": "^10.4.0",
    "concurrently": "^8.2.2",
    "cypress": "^13.0.0",
    "eslint": "8.48.0",
    "eslint-config-prettier": "^9.0.0",
    "eslint-plugin-cypress": "^2.13.4",
    "jasmine-marbles": "~0.9.1",
    "jest": "^29.4.1",
    "jest-environment-jsdom": "^29.4.1",
    "jest-preset-angular": "13.1.4",
    "jsonc-eslint-parser": "^2.1.0",
    "nx": "17.2.3",
    "postcss": "^8.4.5",
    "prettier": "^2.6.2",
    "tailwindcss": "^3.0.2",
    "ts-jest": "^29.1.0",
    "ts-node": "10.9.1",
    "typescript": "~5.2.2"
  }

Support angular workspace for ng-add

Hello,

When running in an angular workspace, the ng-add command can recognize the proper project for the modifications of the angular.json file.
But for the env.d.ts file, this is only a use of src folder, which makes that you have to move the file.

The following move function could use the project path :

export default function (options: any): Rule {
  return chain([
    mergeWith(apply(url("./template"), [move(normalize("./src"))])),
    builder(options),
  ]);
}

This can be helpful when we want to call the schematics from another schematics with externalSchematic method, giving the project as argument :

function addNgxEnvBuilder(): Rule {
	return (tree: Tree, context: SchematicContext) => {
		context.logger.log('info', `🛠 Adding ngx-env builder...`);
		return externalSchematic('@ngx-env/builder', 'ng-add', {
			project: 'sandbox'    //or options.project for example
		})(tree, context);
	}
}

Cheers !

@ngx-env not loading variables

When I run npm run start, it appears that my .env.local file is being loaded (it's listed under "Environment Files"), but the values in it aren't shown like in the demos, and they aren't loaded in the app. If I console.log(import.meta.env), only the built in ones appear:

{
  BASE_URL: '/',
  MODE: 'development',
  DEV: true,
  PROD: false,
  SSR: true
}

I've modified env.d.ts to have the keys I want (APP_BASE_URL: string for example).

I am using the Angular project variation - so my source code is actually in a projects folder and not the default src folder.

Update to Angular 13 broke installation

@chihab thanks for the update to Angular 13 but after upgrading my app to Angular 13 and trying to install @ngx-env/core, the following error showed up

npm install @ngx-env/core   
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: frontend@0.0.0
npm ERR! Found: @angular/common@13.0.2
npm ERR! node_modules/@angular/common
npm ERR!   @angular/common@"^13.0.2" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @angular/common@"^13.3.0" from @ngx-env/core@2.0.0
npm ERR! node_modules/@ngx-env/core
npm ERR!   @ngx-env/core@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

Loading variables from parent folders

Hi! My angular app lives in a monorepo, and all the environment variables live in the monorepo root folder .env file. Is there a way to make ngx-env/builder load the variable values not from the Angular project root, but from a folder above (or any other custom file)? This is supported by dotenv itself, but does not seem to be supported by ngx-env/builder

Make the mandatory NG_APP prefix configurable

Currently we must create custom environment variables beginning with NG_APP_.

Any other variables will be ignored to avoid accidentally exposing a private key on the machine that could have the same name.

Should we make the prefix configurable?

Some might want a shorter prefix like NG_ or might want to access some domain specific variables without referencing them in a .env file

Angular 17 support

With angular 17 this doesn't work and throws an error of
Error: Schema validation failed with the following errors: Data path "" must have required property 'main'.

Add browser-esbuild builder

Motivation:
The application builder always creates browser dir in the build target directory, breaking the deployment pipeline. The official recommended way is to use the browser-esbuild, however, dotenv-run doesn't wrap that particular builder.

Suggestion:
Wrap and expose the browser-esbuild builder in the same manner as the application builder.

Problem with module federation

I have an error "Error: Schema validation failed with the following errors: Data path "" must NOT have additional properties(extraWebpackConfig)."

If delete all definitions for extraWebpack the module federation in angular 16 it corrupts and dont'n generate remoteEntry.js

--
My package.json is:

"dependencies": {
"@angular-architects/module-federation": "^16.0.4",
"@angular/animations": "^16.1.0",
"@angular/cdk": "^16.1.3",
"@angular/common": "^16.1.0",
"@angular/compiler": "^16.1.0",
"@angular/core": "^16.1.0",
"@angular/forms": "^16.1.0",
"@angular/material": "^16.1.3",
"@angular/platform-browser": "^16.1.0",
"@angular/platform-browser-dynamic": "^16.1.0",
"@angular/router": "^16.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^16.1.1",
"@angular/cli": "~16.1.1",
"@angular/compiler-cli": "^16.1.0",
"@ngx-env/builder": "^16.1.2",
"@types/jasmine": "~4.3.0",
"jasmine-core": "~4.6.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"ngx-build-plus": "^16.0.0",
"typescript": "~5.1.3"
}

Support of Angular 14

It would be great to add support of Angular 14 version since it was officially released by the Angular team

How to use with jest?

TypeError: Cannot read properties of undefined (reading 'NG_APP_GRAPHQL_ENDPOINT')

  1 | export const environment = {
> 2 |     graphqlEndpoint: import.meta.env.NG_APP_GRAPHQL_ENDPOINT
    |                                      ^
  3 | }

  at src/app/environment.ts:2:38

Looks like @ngx-env/builder is not loaded, how I can setup env from code. I would probably put it in setupJest.ts file, where it will be loaded on jest startup.

NG_APP_ENV not taken from .env file

Hi,

I face a problem, similar to #45 (I create a new issue because I am not sure that it is exactly the same)

Angular CLI: 16.0.3
Node: 20.0.0 (Unsupported)
Package Manager: npm 9.6.4
OS: linux x64 (WSL2)

"@ngx-env/builder": "^16.1.1"

I have a .env file in the root project (next to angular.json, tsconfig.json, ...)
It is the only one existing and the content is :

NG_APP_ENV=localhost
NG_APP_API_URL=http://localhost:6000
NG_APP_DISPLAY_URL=http://localhost:7000
NG_APP_CDN_URL=http://localhost:8000

But when I launch app (ng serve), the NG_APP_ENV is not set (but the other are taken)


------- @ngx-env/builder -------
- Verbose:  true
- Prefix:  NG_APP
- Working directory:  /workspaces/myapp
- Environment files: 
 ✔ /workspaces/myapp/.env
- Injected keys:
 ✔ NG_APP_ENV => undefined
 ✔ NG_APP_API_URL
 ✔ NG_APP_CDN_URL
 ✔ NG_APP_DISPLAY_URL
---------------------------------

{
  appEnv: undefined,
  stringified: {
    NG_APP_API_URL: '"http://localhost:6000"',
    NG_APP_CDN_URL: '"http://localhost:8000"',
    NG_APP_DISPLAY_URL: '"http://localhost:7000"',
    NG_APP_ENV: undefined
  }
}

Si I tried to set NG_APP_ENV in command line and it works.


------- @ngx-env/builder -------
- Verbose:  true
- Prefix:  NG_APP
- Working directory:  /workspaces/myapp
- Environment files: 
 ✔ /workspaces/myapp/.env
- Injected keys:
 ✔ NG_APP_ENV => localhost
 ✔ NG_APP_API_URL
 ✔ NG_APP_CDN_URL
 ✔ NG_APP_DISPLAY_URL
 ✔ NG_APP_ENV
---------------------------------

{
  appEnv: 'localhost',
  stringified: {
    NG_APP_API_URL: '"http://localhost:6000"',
    NG_APP_CDN_URL: '"http://localhost:8000"',
    NG_APP_DISPLAY_URL: '"http://localhost:7000"',
    NG_APP_ENV: '"localhost"'
  }
}

So is it an issue that the env is not take from the dotenv file ? Or is it normal and I have to give i with command line each time ?
Or maybe I misunderstand something and I have to set NODE_ENV or something else ?

Conflict with block-scoped `@types/node` on `env.d.ts`

Hi guys, thanks for your work! I was wondering how do you resolve the issue with overriding node-provided process? Also, the type definition is not checked by the compiler (since the file is not incuded into the files section of tsconfig.app.json for multiproject structure), is it intended only to be used by the IDE's autocomplete?

Environment:
Angular v13.0.0
@ngx-env/builder 2.0.0
image

Thanks!

version info for import.meta.env

Please highlight in the docs, that import.meta.env is only available starting with version 16.0.0.
This is important since the ngx-env version is strongly coupled to the angular version of the project.

I did not find updates for previous major versions, that make import.meta.env available.

Angular 11 - Error Variable 'process' must be of type 'Process'

I'm using Angular 11 and added version 1.1.0 of @ngx-env/builder manually and when I run the npm run start command (which is an ng serve) I get the following error:

Subsequent variable declarations must have the same type. Variable 'process' must be of type 'Process', but here has type '{ env: { [key: string]: any; NG_APP_ENV: string; }; }'.ts(2403)
globals.d.ts(171, 13): 'process' was also declared here.

Captura de Pantalla 2022-08-10 a la(s) 2 43 07 p  m

The steps I did were the following:

  • Manually add the line "@ngx-env/builder": "^1.1.0", in the "devDependencies": section of the package.json file.

  • In the angular.json file add the following lines:

    • "builder": "@ngx-env/builder:browser", in the "architect" section
    • "builder": "@ngx-env/builder:dev-server", in the "serve" section
    • "builder": "@ngx-env/builder:extract-i18n", in the "extract-i18n" section
    • "builder": "@ngx-env/builder:karma", in the "test" section
    • "builder": "@ngx-env/builder:tslint", in the "lint" section
    • "builder": "@ngx-env/builder:protractor", in the "e2e" section
  • Add the file src/env.d.ts which contains the following:

declare var process: {
  env: {
    NG_APP_ENV: string;
    // Replace the line below with your environment variable for better type checking
    [key: string]: any;
  };
};

What would I need to do to make it work in Angular 11?

Thank you for making this

I spent a good chunk of yesterday wrestling with different approaches and libraries to environmental values in Angular - until I came across your comment here: angular/angular-cli#4318 (comment)

We're working on a docs page soon that recommends various dotenv convenience libraries built by the community - particularly per framework (every framework has its quirks with different dotenv libs that help solve them).

Mind if we feature yours for the Angular section when we do? It will go somewhere at https://www.dotenv.org/docs/

env.local not working

Hello, according to the documentation you can use ".env.local" file but when using it does not return the values, it returns an "undefined", instead if I use only the ".env" file it does return the values. Any clue to solve this?

I cannot access my environment variables in my environment.ts

I encountered an error while trying to build my Angular application. The specific error message is as follows:
`ERROR in ./src/environments/environment.ts 6:19
Module parse failed: Unexpected token (6:19)
You may need an appropriate loader to handle this file type.

baseURL: import.meta.env["BASE_URL"],

| ssoURL: import.meta.env["SSO_URL"],
| chatURL: import.meta.env["CHAT_URL"],`

Here's my environment.prod.ts code:
export const environment = { production: true, baseURL: import.meta.env["BASE_URL"], ssoURL: import.meta.env["SSO_URL"], chatURL: import.meta.env["CHAT_URL"], };

I'm using angular 7

Thank you

ng build throws rxjs switchmap error

Hey, I am trying to build my project using ng build but am getting the following error:

An unhandled exception occurred: (0 , rxjs_1.switchMap) is not a function

I am using import.meta.env everywhere.

Here is my env.d.ts

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

interface ImportMetaEnv {
  /**
   * Built-in environment variable.
   * @see Docs https://github.com/chihab/ngx-env#ng_app_env.
   */
  readonly NG_APP_ENV: string;
  // Add your environment variables below
  // readonly NG_APP_API_URL: string;
  [key: string]: any;
}
declare namespace NodeJS {
  export interface ProcessEnv {
    readonly NG_APP_ENV: string;
    // Add your environment variables below
    [key: string]: any;
  }
}

rxjs version- 6.5.5

Replace variables on pre-rendered pages

I'm using angular 17.0.3 and @ngx-env/builder 17.0.1-alpha.0

My angular.json looks something like this:

{
  "architect": {
    "build": {
      "builder": "@ngx-env/builder:application",
      "options": {
        "server": "src/main.server.ts",
        "prerender": {
          "routesFile": "routes.txt"
        },
        "ssr": {
          "entry": "server.ts"
        }
      }
    }
  }
}

After build, i get this error:

URIError: Failed to decode param '/%NG_APP_CDN_URL%/resources/brand/favicon'
    at decodeURIComponent (<anonymous>)
    at Xy (file:///<dist-dir>/server/server.mjs:74:4297)
    at In.match (file:///<dist-dir>/server/server.mjs:74:4169)
    at tO (file:///<dist-dir>/server/server.mjs:74:10738)
    at v (file:///<dist-dir>/server/server.mjs:74:8145)
    at jf (file:///<dist-dir>/server/server.mjs:113:6080)
    at In.handle_request (file:///<dist-dir>/server/server.mjs:74:3780)
    at x (file:///<dist-dir>/server/server.mjs:74:8906)
    at file:///<dist-dir>/server/server.mjs:74:8500
    at Nr.process_params (file:///<dist-dir>/server/server.mjs:74:9022)

I noticed that in the dist/<app-name>/browser/<prerendered-page> directories, the index.html files weren't transformed.

long time recompilation

When i use:

        "build": {
          "builder": "@ngx-env/builder:browser",
         }

instead of my:

        "build": {
          "builder": "@angular-devkit/build-angular:browser",
         }

recompilation takes about a minute each time.
in serve i can use:

        "serve": {
          "builder": "@ngx-env/builder:dev-server",
         }

and everything okay. But i need to use builder to deploy my code to production. Any ideas? I tried on 1.1.0 version and 2.0.0 versions. Angular 11

Conflict with block-scoped @types/node on env.d.ts

Hi

I'd like to reopen #8

I have the same problem but I didn't understand the fix.

I have src/env.d.ts:

declare let process: {
  env: {
    NG_APP_ENV: string;
    // Replace the line below with your environment variable for better type checking
    NG_APP_apiHost: string;
    NG_APP_apiURL: string;
  };
};

and when I run my linter:

tsc --noEmit && eslint . --ext js,ts --quiet --fix

"Cannot redeclare block-scoped variable 'process'."

image

Schema validation failed on `ng serve`

I recently upgraded Angular to v17.1.0 and ng serve is outputting this error message:

Error: Schema validation failed with the following errors:
  Data path "" must have required property 'main'.

It seems that ng build is not affected by this issue tho.

To reproduce this issue:
install a new app ng new <app> and add the builder ng add @ngx-env/builder

process is not defined

Hi guys

I have Angular 14 installed and using ngx-env to get env variables but I got the error "process is not defined". I added the code below in polyfills.ts but it is not working for me. I followed the demo and I have exactly everything as the demo.

 import * as process from 'process';
 window['process'] = process;

If I used the code above, I got error below

Module not found: Error: Can't resolve 'process' in 'C:\Projects\project\apps\dashboard\src'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "process": require.resolve("process/browser") }'
        - install 'process'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "process": false }

The order of environment variables are important for k8s pods

I'm using this awesome package to inject environment variables into my web service. Everything works fine when we have one single pod in a k8s deployment, but when we have more than one pod, the production goes down. Why?
Because the hash of the mian.hash.js will be different for each pod (the codebase is the same). After investigating a lot, I've realized that this package injects the environment without alphabetically sorting them and it sometimes causes a random order and makes the main.js hash different.
To solve the issue I simply add the .sort() to the plugin.ts file. I will open a PR later.

NOTE: It is worth mentioning, I have an issue with the version of the chalk package. and the problem has been fixed by installing the chalk and then publishing the pcakge.

Vulnerability due to [email protected]

  High            glob-parent before 5.1.2 vulnerable to Regular Expression     
                  Denial of Service in enclosure regex                          

  Package         glob-parent                                                   

  Patched in      >=5.1.2                                                       

  Dependency of   @ngx-env/builder [dev]                                        

  Path            @ngx-env/builder > cpy > globby > fast-glob > glob-parent     

  More info       https://github.com/advisories/GHSA-ww39-953v-wcq6   

Should be easy fixed when updating to cpy@9 :)

Impossible to use the project's builder with Angular Universal

Steps to reproduce:

  • Clone any project repo with Angular Universal, I used this one: https://github.com/Angular-RU/universal-starter
  • Install all dependencies and add ngx-env dependency:
    npm install && ng add @ngx-env/builder
  • Run serving of the newly created app in ssr mode:
    npm run ssr

Expected behaviour:

  • The application successfully starts rendering

Actual behaviour:

  • The application fails with the following error:
A server error has occurred.
node exited with 1 code.
connect ECONNREFUSED 127.0.0.1:36745

Curiously, if I change @ngx-env/builder:server to @angular-devkit/build-angular:server in the server's section builder in the angular.json everything works fine

Specify path to .env file(s)

@otonielguajardo PR #42 follow up

dotenv supports specifying the path of the .env file, this PR tries to acomplish the same.

It would be awesome for proyects with structures like this:
Screenshot 2023-05-27 at 1 46 21 a m

The only potential confustion is that we specify the .env file but we might have other files like .env.dev or .env.local that are also parsed when present.
I wonder if it wouldn't be better to set path as the folder containing the .env files rather than the file itself. WDYT?

            "ngxEnv": {
              "prefix": "NGX_",
              "path": ".." // could be relative or absolute
            },

There also another use case in monorepo setup on which we'd want have a root .env file and each project in the workspace might have their .env files that override the properties from the parent.

cvnl-map
  apps/
      frontend1
          .env
       frontend2
          .env
.env

In that case the base config of frontend1 and frontend2 would target the root .env

            "ngxEnv": {
              "prefix": "NGX_",
              "path": "../../" 
            },

the plugin would load all the .env files from the root down to the project one(s), the latter can override keys from the former.

Empty env.d.ts

I have defined my environment variables in a .env file in the root of my project, and when I run 'ng add @ngx-env/builder,' an env.d.ts file gets created in the src folder. However, that file contains only an empty template. Is the env.d.ts supposed to be automatically populated with the variables defined in the .env file?

Property 'env' does not exist on type 'ImportMeta'.

  • Extension installed with the "ng add @ngx-env/builder" command as it's told in the readme file.
  • env.d.ts file is successfully created by ng add command.
  • Removed the deprecated lines from env.d.ts and added some variable definitions in it. It looks like this:
interface ImportMeta {
  readonly env: ImportMetaEnv;
}

interface ImportMetaEnv {
  /**
   * Built-in environment variable.
   * @see Docs https://github.com/chihab/ngx-env#ng_app_env.
   */
  readonly NG_APP_ENV: string;
  // Add your environment variables below
  // readonly NG_APP_API_URL: string;
  readonly NG_APP_VERSION: string;
  [key: string]: any;
}
  • It is also picking up my .env file and declared variables within it:
------- @ngx-env/builder -------
- Verbose:  true
- Prefix:  NG_APP
- Working directory:  C:\Users\Windows\VSCRepos\prtime-frontend
- Environment files: 
 ✔ C:\Users\Windows\VSCRepos\prtime-frontend\.env
- Injected keys:
 ✔ NG_APP_ENV => undefined
 ✔ NG_APP_VERSION
---------------------------------

But when i try to read the NG_APP_VERSION in my environment.ts file like this:

export const environment = {
  production: false,
  version: import.meta.env.NG_APP_VERSION,
};

i'm getting this error:

./src/environments/environment.ts - Error: Module parse failed: parser.destructuringAssignmentPropertiesFor is not a function
File was processed with these loaders:
 * ./node_modules/@angular-devkit/build-angular/src/babel/webpack-loader.js
 * ./node_modules/@ngtools/webpack/src/ivy/index.js
You may need an additional loader to handle the result of these loaders.
TypeError: parser.destructuringAssignmentPropertiesFor is not a function

Error: src/environments/environment.ts:7:24 - error TS2339: Property 'env' does not exist on type 'ImportMeta'.

I can see that builders are changed to ngx-env builders in my angular.json file:

"serve": {
  "builder": "@ngx-env/builder:dev-server",
  "options": {
    "browserTarget": "prtime:build"
  },
  "configurations": {
    "production": {
      "browserTarget": "prtime:build:production"
    }
  }
},

What might be causing this error?

Validate .env schema using `dotenv-extended` package

Hi @chihab,

I was reading through in-depth articles and got to see your article. I was interested since my team has done a similar thing in the angular app but seems like it's a kind of more makeshift. So I read the article and was fascinated by the way you explain via DefinePlugin.

I cloned the repo and wanted to contribute to validating the .env file schema via the dotenv-extended package. I tried to dig around this library and did changes, but seems like this couldn't work for me. If you think this is possible to implement, then I think you could help me in contributing and understand some quirky parts which I'm not able to grab.

Thanks.

Set the environment with--configuration option

The extension/CLI is not picking up .env files for example .env.production (present in the same dir as package.json) with NG_APP_ENV being undefined even though valid Angular configuration was provided through ng build.

PS C:\Git\myproj> ng build --configuration production
------- @ngx-env/builder -------

  • Verbose: true
  • Prefix: NG_APP
  • Working directory: C:\Git\myproj
  • Environment files:
    ✔ C:\Git\myproj.env
  • Injected keys:
    ✔ NG_APP_ENV => undefined
    ✔ NG_APP_API_FQDN
    ✔ NG_APP_API_URL

None of the default (development, production) files are being picked up, it only detects .env and .env.local (if I place it in the same dir).

Polyfills should be excluded from "expansion" process

I think the polyfills should be excluded from the "expansion" process as they're not part of the application src.

process.env["NG_APP_PRETTY_CAR"];

// after build, turns into: 
{ NG_APP_PRETTY_CAR: "value", NG_APP_ENV: "production" }.NG_APP_PRETTY_CAR

The reflect-metadata polyfill has references to process.env in it's code. See here

Variable expansion in `.env` does not work any more

It seems that since the 16.1, variable expansion does not work anymore.

# .env file

MY_ENV=develop

NG_APP_URL=https://${MY_ENV}.example.com

NG_APP_URL used to be https://develop.example.com until 16.0.2 and now it is https://${MY_ENV}.example.com

By the way, thanks for this great project!
👍

environment variables not being set

Hey, I am trying to use the library for something i am working on. I followed the steps listed but I cannot access the .env files and variables inside them. I tried to log the import.meta.env it says {NG_APP_ENV: undefined}

I used: ng serve which prints the following.

  • Verbose: true
  • Prefix: NG_APP
  • Root directory: .
  • Working directory: /home/urjit.desai/Desktop/ABC/ABC-ui/client
  • Environment files:
    ✔ /home/urjit.desai/Desktop/ABC/ABC-ui/client/.env
  • Injected keys:
    ✔ NG_APP_ENV => undefined

I have my .env file at the package.json level here are its contents:

SERVER_URL=http://google.com
NUMBER_OF_FILES=10

I want to access them within my code but it gives me undefined.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.