1

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?

undefinederror
  • 821
  • 1
  • 8
  • 16

2 Answers2

1

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);
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • thank you @VonC, I did try that but it got completely ignored. I found that nx already injects some plugins, amongst which the DefinePlugin. So I just grabbed that and added my var to the definitions. Why pushing a new DefinPlugin had no effect I had no idea – undefinederror Aug 24 '23 at 15:15
  • I am still going to accept your answer becuase it's a good answer that would be useful to most people with a similar issue – undefinederror Aug 24 '23 at 15:27
  • @undefinederror It is possible that the way Nx is handling the webpack configuration, particularly with the DefinePlugin, is causing your custom addition to be ignored or overridden. By modifying the existing DefinePlugin instance directly, you make sure that your custom definition is incorporated into the existing plugin configuration. – VonC Aug 24 '23 at 15:37
1

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;
});
undefinederror
  • 821
  • 1
  • 8
  • 16
  • Nicely done. Upvoted. That will iterate through the existing plugins, finds the `DefinePlugin`, and then amend the definitions with the `NX_PKG_VERSION` key, pulling the value from `process.env.npm_package_version`. – VonC Aug 24 '23 at 15:39