1

A project that respects the semver directory structure for build artefacts is beginning soon, and package.json or .nmprc would seem to be the right place to define this metadata. This is some preliminary code that demonstrates how the goal is intended to be achieved:

{
  "name": "com.vendor.product"
, "version": "0.0.0"
, "directories": {
    "build": "./out"
  }
, "main": "./${npm_directories_build}/${npm_package_name}/${npm_package_version}/${npm_package_name}.js"
, "exports": "${npm_package_main}"
, "scripts": {
    "echo": "echo\"${npm_package_exports}\""
  }
}

I expected

npm run echo

to print the compound variable result to standard output,

./out/com.vendor.product/0.0.0/com.vendor.product.js

but instead, it prints the literal text

${npm_package_export}

I attempted to use array variables in .npmrc

outpath[]=./out
outpath[]=/${npm_package_name}
outpath[]=/${npm_package_version}

But

...
{
  "echo": "echo \"${npm_config_outpath}\""
}

Simply prints an empty newline


It was expected that package.json supports compound variables, but this assumption is now in question. I have checked documentation, but either I am missing something or such is not defined. Long hand repetition of the same data is to be avoided (e.g. multiple references to package variables in order to make a single path). It is intended for package name and version to always dictate the location of the build files in a reliable and predictable manner. If compound variables are not supported, could you clarify how .npmrc array variables actually work? Failing that, could you recommend an alternative method to achieve the same ends? Many thanks!

Searched documentation:

Emmington
  • 53
  • 1
  • 9
  • Thanks for the answer @RobC. Clarity is a relief. Thanks also for the external links, very helpful! Asking too much is not very good, but would you also happen to know how [array values](https://github.com/npm/ini) defined in .npmrc can be used in package.json? No problem if not, am just curious if that would provide an alternative solution. Many thanks! – Emmington Aug 20 '20 at 10:04
  • @RobC thanks for the grokback! For context, the problem is in relation to designing a project template. Compound variables would be perfect as it leads to important metadata being defined in one place only to preserve integrity of the document. The alternatives you posted are of interest too and will be explored. Will investigate build hooks and external scripts to read package metadata and inject computed paths back into package, perhaps. Please do feel free to collate your comments and post them as a formal answer and will be glad to mark this question as answered. Namaste RobC. Thanks. – Emmington Aug 20 '20 at 13:34

1 Answers1

1

Short Answer:

"Does package.json support compound variables?"

Unfortunately no, not for the way you are wanting to use them. It only has package json vars which can be used in npm scripts only. For example on *Nix defining the echo script as:

"echo": "echo $npm_package_version"

or on Windows defining it as:

"echo": "echo %npm_package_version%"

will print the version e.g. 0.0.0.

Note: cross-env provides a solution for a single syntax that works cross-platform.

You certainly cannot include parameter substitution ${...} elsewhere in package.json fields except for the scripts section.


Additional info:

Regarding your subsequent comment:

How array values defined in .npmrc can be used in package.json

AFAIK I don't think you can. For example let's say we;

  1. Save this contrived .npmrc in the root of the project directory.

    .npmrc

    quux[]="one"
    quux[]="two"
    quux[]="three"
    
    foo=foobar
    
  2. Then cd to the project directory and run the following command to print all environment variables:

    npm run env
    

    As you can see, the npm_config_foo=foobar environment variable has been added by npm. However for the quux array there is no npm_config_quux=[ ... ] environment variable added.

    So, in npm scripts using package.json vars the following does work:

    "echo": "echo $npm_config_foo"
    

    However the following, (for referencing the array), does not - simply because it does not exist;

    "echo": "echo $npm_config_quux"
    

The ini node.js package:

Maybe consider investigating the ini node.js package that npm utilizes for parsing .npmrc files. For example:

  1. If you run the following command to install the package in your project:

    npm i -D ini
    
  2. Then define the npm echo script as per this:

    "scripts": {
      "echo": "node -e \"var fs = require('fs'), ini = require('ini'); var config = ini.parse(fs.readFileSync('./.npmrc', 'utf-8')); console.log(config.quux)\""
    }
    

    Note it uses the nodejs command line option -e to evaluate the JavaScript code. It essentially executes the following:

    var fs = require('fs'),
        ini = require('ini');
    
    var config = ini.parse(fs.readFileSync('./.npmrc', 'utf-8'));
    console.log(config.quux);
    
  3. Then given the contrived .npmrc file that I mentioned previously when running:

    npm run echo
    

    it will print:

    [ 'one', 'two', 'three' ]

RobC
  • 22,977
  • 20
  • 73
  • 80