Home > Back-end >  Node/Webpack: Load package.json with ES6
Node/Webpack: Load package.json with ES6

Time:10-04

I want to load my package.json in an ES6 environment and access it like pkg.name.
My solution so far is making a simple module for reading the file with fs, parsing it and import this module in every place I need to access it.

The problem is, I want to bundle my script with webpack and the path to the package.json is resolved to my current path from my pc I bundle everything. Like: D:/dev/app-name/package.json

This is wrong, I need a way to run the bundled script afterwards on e.g. a separate pc, or linux and still find the package.json. Is there a way to tell webpack to not resolve this path, or is there another (simpler) way to use the "root" path in my script?

My bundled app is an express server and I'm using webpack 5.

src/api/package-json.js:

import path from 'path'
import { fileURLToPath } from 'url'
import fs from 'fs-extra'

// Path CONST
// we need to change up how __dirname is used for ES6 purposes
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const PROJECT_ROOT = path.join(__dirname, '..', '..')
const PKG_FILE = path.join(PROJECT_ROOT, 'package.json')

// Package.json
const pkg = JSON.parse(fs.readFileSync(PKG_FILE)) // import pkg from '~root/package.json'

export default pkg

src/api/app.js:

import pkg from './package-json.js'
console.log(pkg.name)

webpack.config.js:

import path from 'path'
import { fileURLToPath } from 'url'
// import nodeExternals from 'webpack-node-externals'

// we need to change up how __dirname is used for ES6 purposes
const __dirname = path.dirname(fileURLToPath(import.meta.url))

const { NODE_ENV = 'production' } = process.env

export default {
    entry: './src/api/app.js',
    mode: NODE_ENV,
    target: 'node',
    node: {
        global: false,
        __filename: false,
        __dirname: false
    },
    output: {
        path: path.resolve(__dirname, 'dist', 'server'),
        filename: 'app.cjs'
    },
    resolve: {
        extensions: ['.js', '.jsx', '.ts', '.tsx']
    },
    externals: {
        'node-pty': 'commonjs2 node-pty'
    }
}

CodePudding user response:

I found a workaround with process.cwd(), but I don't think this is a good solution for my problem. The problem is, process.cwd() can be changed in runtime as far as I know. :(

src/api/package-json.js:

import path from 'path'
import fs from 'fs-extra'

// Path CONST
const PROJECT_ROOT = process.cwd()
const PKG_FILE = path.join(PROJECT_ROOT, 'package.json')

// Package.json
const pkg = JSON.parse(fs.readFileSync(PKG_FILE)) // import pkg from '~root/package.json'

export default pkg
  • Related