set package version as env var in Nx

1.1k Views Asked by At

I am trying to access from browser the package.json version

In Nx, it is possible to hardcode env vars in a .env file and have them passed to process.env.{varname} if the variables are prefixed vith NX_. I can't hardcode the variable though, I need to read it from package.json.

Anyone knows how to do that?

2

There are 2 best solutions below

3
On BEST ANSWER

In a Nx workspace, the custom webpack configuration file can be named according to your preference, as you will reference it explicitly in the angular.json or workspace.json file. A common convention for naming this file is webpack.config.js or custom-webpack.config.js.
See "Configure webpack on your Nx workspace"

In your webpack configuration file, you can import the package.json:

const packageJson = require('./package.json');
const version = packageJson.version;

Use the DefinePlugin in your webpack configuration to define the variable based on version.
See "Using environment variables in Angular applications".
In your custom webpack configuration, it might look like this:

const webpack = require('webpack');

module.exports = (config) => {
  config.plugins.push(
    new webpack.DefinePlugin({
      'process.env.NX_PACKAGE_VERSION': JSON.stringify(version)
    })
  );
  return config;
};

Update your application's build options to use the custom webpack configuration. For example, if you are using Angular, you can update the angular.json file:

"architect": {
  "build": {
    "builder": "@angular-builders/custom-webpack:browser",
    "options": {
      "customWebpackConfig": {
        "path": "./custom-webpack.config.js"
      },
    }
  }
}

You should now be able to access the version in your code like this:

console.log(process.env.NX_PACKAGE_VERSION);
1
On

The solution proposed by @Vonc should work in most cases. However it did not for me. I see that nx already defines some plugins, and maybe that's why pushing a second DefinePlugin did not work (not sure).
So instead of adding another one I grab the existing one and amend the definitions.
No need to import package.json, the version is exposed in $npm_package_version

project.json

"targets": {
    "build": {
      "executor": "@nx/webpack:webpack",
      "options": {
        "compiler": "babel",
        "webpackConfig": "path-to/webpack.config.js",
      },

webpack.config.js

const { composePlugins, withNx } = require('@nx/webpack');
const { withReact } = require('@nx/react');

// Nx plugins for webpack.
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => {
  const definePlugin = config.plugins.find((x) => x.constructor.name === 'DefinePlugin');

  if (definePlugin) {
    definePlugin.definitions['process.env'] = {
      ...(definePlugin.definitions['process.env'] || {}),
      NX_PKG_VERSION: JSON.stringify(process.env.npm_package_version),
    };
  }

  return config;
});