Problem Statement
I wrote a JavaScript code to pull data from Uniswap V3 SDK (https://www.npmjs.com/package/#uniswap/v3-sdk) and I would like to open-source this code on GitHub because currently this isn't possible (for specific use cases). I am not an amazing system designer/programmer so please bare with me (I can only code in Python and barely understand JavaScript).
Essentially, I have a JavaScript code that pulls data and I wanted to wrap it in a Python code, so I can then take the data and do other things with the data (create alerts, flask app, etc.)
I am using Ubuntu, JS6, npm v8.19.2 and Node v16.18.1.
In my research, I found two packages that could help enable me wrapping this JS code in Python:
py2js - https://github.com/PiotrDabkowski/Js2Py
stpyv8 - https://github.com/cloudflare/stpyv8
Coding Attempt
py2js attempt
This package only works for JS5 and below, not JS6. Here is a quote from the GitHub that helps explain the workaround for this issue (which uses babel) https://github.com/PiotrDabkowski/Js2Py:
JavaScript 6 support was achieved by using Js2Py to translate javascript library called Babel. Babel translates JS 6 to JS 5 and afterwards Js2Py translates JS 5 to Python.
While trying this solution out, I am getting the following error:
/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/es6/__init__.py:10: UserWarning:
Importing babel.py for the first time - this can take some time.
Please note that currently Javascript 6 in Js2Py is unstable and slow. Use only for tiny scripts!
warnings.warn(
/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/base.py:2854: FutureWarning: Possible nested set at position 5
self.pat = re.compile(
Initialised babel!
Traceback (most recent call last):
File "/home/bobby/uni_balances/main.py", line 104, in <module>
result = js2py.eval_js6(js) # executing JavaScript and converting the result to python string
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/evaljs.py", line 120, in eval_js6
return eval_js(js6_to_js5(js))
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/evaljs.py", line 115, in eval_js
return e.eval(js)
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/evaljs.py", line 204, in eval
self.execute(code, use_compilation_plan=use_compilation_plan)
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/evaljs.py", line 199, in execute
exec (compiled, self._context)
File "<EvalJS snippet>", line 4, in <module>
File "<EvalJS snippet>", line 3, in PyJs_LONG_0_
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/base.py", line 949, in __call__
return self.call(self.GlobalObject, args)
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/base.py", line 1464, in call
return Js(self.code(*args))
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/host/jseval.py", line 17, in Eval
py_code = translate_js(code.to_string().value, '')
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/translators/translator.py", line 70, in translate_js
parsed = parse_fn(js)
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/js2py/translators/translator.py", line 62, in pyjsparser_parse_fn
return parser.parse(code)
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/pyjsparser/parser.py", line 3008, in parse
program = self.parseProgram()
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/pyjsparser/parser.py", line 2974, in parseProgram
body = self.parseScriptBody()
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/pyjsparser/parser.py", line 2963, in parseScriptBody
statement = self.parseStatementListItem()
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/pyjsparser/parser.py", line 2110, in parseStatementListItem
return self.parseStatement()
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/pyjsparser/parser.py", line 2718, in parseStatement
self.consumeSemicolon()
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/pyjsparser/parser.py", line 1120, in consumeSemicolon
self.throwUnexpectedToken(self.lookahead)
File "/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/pyjsparser/parser.py", line 1046, in throwUnexpectedToken
raise self.unexpectedTokenError(token, message)
js2py.internals.simplex.JsException: SyntaxError: Line 34: Unexpected token function
What have I done to try to fix this?
I have updated node and even downgraded to version 5 as some suggested, but nothing worked.
JavaScript Code
Here is the JavaScript code (note that you would need an Alchemy API ID to run this script):
import { JSBI } from "#uniswap/sdk";
import { ethers } from 'ethers';
import * as fs from 'fs';
// ERC20 json abi file
let ERC20Abi = fs.readFileSync('Erc20.json');
const ERC20 = JSON.parse(ERC20Abi);
// V3 pool abi json file
let pool = fs.readFileSync('V3PairAbi.json');
const IUniswapV3PoolABI = JSON.parse(pool);
// V3 factory abi json
let facto = fs.readFileSync('V3factory.json');
const IUniswapV3FactoryABI = JSON.parse(facto);
let NFT = fs.readFileSync('UniV3NFT.json');
const IUniswapV3NFTmanagerABI = JSON.parse(NFT);
const provider = new ethers.providers.JsonRpcProvider(ALCHEMY_API_ID)
// V3 standard addresses (different for celo)
const factory = "0x1F98431c8aD98523631AE4a59f267346ea31F984";
const NFTmanager = "0xC36442b4a4522E871399CD717aBDD847Ab11FE88";
async function getData(tokenID){
let FactoryContract = new ethers.Contract(factory, IUniswapV3FactoryABI, provider);
let NFTContract = new ethers.Contract(NFTmanager, IUniswapV3NFTmanagerABI, provider);
let position = await NFTContract.positions(tokenID);
let token0contract = new ethers.Contract(position.token0, ERC20, provider);
let token1contract = new ethers.Contract(position.token1, ERC20, provider);
let token0Decimal = await token0contract.decimals();
let token1Decimal = await token1contract.decimals();
let token0sym = await token0contract.symbol();
let token1sym = await token1contract.symbol();
let V3pool = await FactoryContract.getPool(position.token0, position.token1, position.fee);
let poolContract = new ethers.Contract(V3pool, IUniswapV3PoolABI, provider);
let slot0 = await poolContract.slot0();
let pairName = token0sym +"/"+ token1sym;
let dict = {"SqrtX96" : slot0.sqrtPriceX96.toString(), "Pair": pairName, "T0d": token0Decimal, "T1d": token1Decimal, "tickLow": position.tickLower, "tickHigh": position.tickUpper, "liquidity": position.liquidity.toString()}
return dict
}
const Q96 = JSBI.exponentiate(JSBI.BigInt(2), JSBI.BigInt(96));
const MIN_TICK = -887272;
const MAX_TICK = 887272;
function getTickAtSqrtRatio(sqrtPriceX96){
let tick = Math.floor(Math.log((sqrtPriceX96/Q96)**2)/Math.log(1.0001));
return tick;
}
async function getTokenAmounts(liquidity,sqrtPriceX96,tickLow,tickHigh,token0Decimal,token1Decimal){
let sqrtRatioA = Math.sqrt(1.0001**tickLow).toFixed(18);
let sqrtRatioB = Math.sqrt(1.0001**tickHigh).toFixed(18);
let currentTick = getTickAtSqrtRatio(sqrtPriceX96);
let sqrtPrice = sqrtPriceX96 / Q96;
let amount0wei = 0;
let amount1wei = 0;
if(currentTick <= tickLow){
amount0wei = Math.floor(liquidity*((sqrtRatioB-sqrtRatioA)/(sqrtRatioA*sqrtRatioB)));
}
if(currentTick > tickHigh){
amount1wei = Math.floor(liquidity*(sqrtRatioB-sqrtRatioA));
}
if(currentTick >= tickLow && currentTick < tickHigh){
amount0wei = Math.floor(liquidity*((sqrtRatioB-sqrtPrice)/(sqrtPrice*sqrtRatioB)));
amount1wei = Math.floor(liquidity*(sqrtPrice-sqrtRatioA));
}
let amount0Human = (amount0wei/(10**token0Decimal)).toFixed(token0Decimal);
let amount1Human = (amount1wei/(10**token1Decimal)).toFixed(token1Decimal);
console.log("Amount Token0 wei: "+amount0wei);
console.log("Amount Token1 wei: "+amount1wei);
console.log("Amount Token0 : "+amount0Human);
console.log("Amount Token1 : "+amount1Human);
return [amount0wei, amount1wei]
}
async function start(positionID){
let data = await getData(positionID);
let tokens = await getTokenAmounts(data.liquidity, data.SqrtX96, data.tickLow, data.tickHigh, data.T0d, data.T1d);
}
start(273381)
// Also it can be used without the position data if you pull the data it will work for any range
getTokenAmounts(12558033400096537032, 20259533801624375790673555415)
Python Code
Here is the python code I wrote using the js2py package. To save space, I removed the JS Code in the js variable below, but you can copy it from above and place it in the triple quotes:
import js2py
js = """
<<< JS CODE COPIED HERE >>>
""".replace("document.write", "return ")
result = js2py.eval_js6(js) # executing JavaScript and converting the result to python string
One other note, you will need to install babel as well to make it work. Babel will help convert the code from JS6 to JS5.
stpyv8 attempt
This package is maintained by Cloudflare, which makes this a much more attractive approach, but I am having difficulty installing the pyv8 package on my machine.
I was able to successfully run:
sudo apt install python3 python3-dev build-essential libboost-dev libboost-system-dev libboost-python-dev libboost-iostreams-dev
The probem is that I now need to run setup.py, which I can't find. I also below, if you look at the pyv8 installation I tried below, it does it automatically, but it throws an error. Seems like I am getting stuck at trying to run setup.py
pyv8 attempt (alternative to stpyv8 I believe)
https://code.google.com/archive/p/pyv8/
When I run pip3 install -v pyv8, I get the following error:
Using pip 22.0.2 from /home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/pip (python 3.10)
Collecting pyv8
Using cached PyV8-0.5.zip (22 kB)
Running command python setup.py egg_info
running egg_info
creating /tmp/pip-pip-egg-info-g__o7shf/PyV8.egg-info
writing /tmp/pip-pip-egg-info-g__o7shf/PyV8.egg-info/PKG-INFO
writing dependency_links to /tmp/pip-pip-egg-info-g__o7shf/PyV8.egg-info/dependency_links.txt
writing top-level names to /tmp/pip-pip-egg-info-g__o7shf/PyV8.egg-info/top_level.txt
writing manifest file '/tmp/pip-pip-egg-info-g__o7shf/PyV8.egg-info/SOURCES.txt'
reading manifest file '/tmp/pip-pip-egg-info-g__o7shf/PyV8.egg-info/SOURCES.txt'
writing manifest file '/tmp/pip-pip-egg-info-g__o7shf/PyV8.egg-info/SOURCES.txt'
Preparing metadata (setup.py) ... done
Using legacy 'setup.py install' for pyv8, since package 'wheel' is not installed.
Installing collected packages: pyv8
Running command Running setup.py install for pyv8
running install
/home/bobby/uni_balances/uni_venv/lib/python3.10/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.10
copying PyV8.py -> build/lib.linux-x86_64-3.10
running build_ext
building '_PyV8' extension
creating build/temp.linux-x86_64-3.10
creating build/temp.linux-x86_64-3.10/src
x86_64-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DBOOST_PYTHON_STATIC_LIB -Ilib/python/inc -Ilib/boost/inc -Ilib/v8/inc -I/home/bobby/uni_balances/uni_venv/include -I/usr/include/python3.10 -c src/Context.cpp -o build/temp.linux-x86_64-3.10/src/Context.o
In file included from src/Wrapper.h:8,
from src/Context.h:7,
from src/Context.cpp:1:
src/Exception.h:6:10: fatal error: v8.h: No such file or directory
6 | #include <v8.h>
| ^~~~~~
compilation terminated.
error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
error: subprocess-exited-with-error
× Running setup.py install for pyv8 did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
full command: /home/bobby/uni_balances/uni_venv/bin/python3 -u -c '
exec(compile('"'"''"'"''"'"'
# This is <pip-setuptools-caller> -- a caller that pip uses to run setup.py
#
# - It imports setuptools before invoking setup.py, to enable projects that directly
# import from `distutils.core` to work with newer packaging standards.
# - It provides a clear error message when setuptools is not installed.
# - It sets `sys.argv[0]` to the underlying `setup.py`, when invoking `setup.py` so
# setuptools doesn'"'"'t think the script is `-c`. This avoids the following warning:
# manifest_maker: standard file '"'"'-c'"'"' not found".
# - It generates a shim setup.py, for handling setup.cfg-only projects.
import os, sys, tokenize
try:
import setuptools
except ImportError as error:
print(
"ERROR: Can not execute `setup.py` since setuptools is not available in "
"the build environment.",
file=sys.stderr,
)
sys.exit(1)
__file__ = %r
sys.argv[0] = __file__
if os.path.exists(__file__):
filename = __file__
with tokenize.open(__file__) as f:
setup_py_code = f.read()
else:
filename = "<auto-generated setuptools caller>"
setup_py_code = "from setuptools import setup; setup()"
exec(compile(setup_py_code, filename, "exec"))
'"'"''"'"''"'"' % ('"'"'/tmp/pip-install-b9d0zoul/pyv8_c9dfd2e4ec0e4c66a2bff47f44972004/setup.py'"'"',), "<pip-setuptools-caller>", "exec"))' install --record /tmp/pip-record-pel12p8h/install-record.txt --single-version-externally-managed --compile --install-headers /home/bobby/uni_balances/uni_venv/include/site/python3.10/pyv8
cwd: /tmp/pip-install-b9d0zoul/pyv8_c9dfd2e4ec0e4c66a2bff47f44972004/
Running setup.py install for pyv8 ... error
error: legacy-install-failure
× Encountered error while trying to install package.
╰─> pyv8
note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.
Conclusion
I am not married to using the two options I mentioned above, but I would like to pull the data into Python from the JS code.
Also this is the output from the JS code that I need to port over into Python:
Is there a way to get the version set in package.json in a nodejs app? I would want something like this
var port = process.env.PORT || 3000
app.listen port
console.log "Express server listening on port %d in %s mode %s", app.address().port, app.settings.env, app.VERSION
I found that the following code fragment worked best for me. Since it uses require to load the package.json, it works regardless of the current working directory.
var pjson = require('./package.json');
console.log(pjson.version);
A warning, courtesy of #Pathogen:
Doing this with Browserify has security implications.
Be careful not to expose your package.json to the client, as it means that all your dependency version numbers, build and test commands and more are sent to the client.
If you're building server and client in the same project, you expose your server-side version numbers too.
Such specific data can be used by an attacker to better fit the attack on your server.
If your application is launched with npm start, you can simply use:
process.env.npm_package_version
See package.json vars for more details.
Using ES6 modules you can do the following:
import {version} from './package.json';
Or in plain old shell:
$ node -e "console.log(require('./package.json').version);"
This can be shortened to
$ node -p "require('./package.json').version"
There are two ways of retrieving the version:
Requiring package.json and getting the version:
const { version } = require('./package.json');
Using the environment variables:
const version = process.env.npm_package_version;
Please don't use JSON.parse, fs.readFile, fs.readFileSync and don't use another npm modules it's not necessary for this question.
For those who look for a safe client-side solution that also works on server-side, there is genversion. It is a command-line tool that reads the version from the nearest package.json and generates an importable CommonJS module file that exports the version. Disclaimer: I'm a maintainer.
$ genversion lib/version.js
I acknowledge the client-side safety was not OP's primary intention, but as discussed in answers by Mark Wallace and aug, it is highly relevant and also the reason I found this Q&A.
Here is how to read the version out of package.json:
fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version
EDIT: Wow, this answer was originally from 2012! There are several better answers now. Probably the cleanest is:
const { version } = require('./package.json');
There is another way of fetching certain information from your package.json file namely using pkginfo module.
Usage of this module is very simple. You can get all package variables using:
require('pkginfo')(module);
Or only certain details (version in this case)
require('pkginfo')(module, 'version');
And your package variables will be set to module.exports (so version number will be accessible via module.exports.version).
You could use the following code snippet:
require('pkginfo')(module, 'version');
console.log "Express server listening on port %d in %s mode %s", app.address().port, app.settings.env, module.exports.version
This module has very nice feature - it can be used in any file in your project (e.g. in subfolders) and it will automatically fetch information from your package.json. So you do not have to worry where you package.json is.
I hope that will help.
NPM one liner:
From npm v7.20.0:
npm pkg get version
Prior to npm v7.20.0:
npm -s run env echo '$npm_package_version'
Note the output is slightly different between these two methods: the former outputs the version number surrounded by quotes (i.e. "1.0.0"), the latter without (i.e. 1.0.0).
One solution to remove the quotes in Unix is using xargs
npm pkg get version | xargs echo
Option 1
Best practice is to version from package.json using npm environment variables.
process.env.npm_package_version
more information on: https://docs.npmjs.com/using-npm/config.html
This will work only when you start your service using NPM command.
Quick Info: you can read any values in pacakge.json using process.env.npm_package_[keyname]
Option 2
Setting version in environment variable using https://www.npmjs.com/package/dotenv as .env file and reading it as process.env.version
Just adding an answer because I came to this question to see the best way to include the version from package.json in my web application.
I know this question is targetted for Node.js however, if you are using Webpack to bundle your app just a reminder the recommended way is to use the DefinePlugin to declare a global version in the config and reference that. So you could do in your webpack.config.json
const pkg = require('../../package.json');
...
plugins : [
new webpack.DefinePlugin({
AppVersion: JSON.stringify(pkg.version),
...
And then AppVersion is now a global that is available for you to use. Also make sure in your .eslintrc you ignore this via the globals prop
If you are looking for module (package.json: "type": "module") (ES6 import) support, e.g. coming from refactoring commonJS, you should (at the time of writing) do either:
import { readFile } from 'fs/promises';
const pkg = JSON.parse(await readFile(new URL('./package.json', import.meta.url)));
console.log(pkg.version)
or, run the node process with node --experimental-json-modules index.js to do:
import pkg from './package.json'
console.log(pkg.version)
You will however get a warning, until json modules will become generally available.
If you get Syntax or (top level) async errors, you are likely in a an older node version. Update to at least node#14.
You can use ES6 to import package.json to retrieve version number and output the version on console.
import {name as app_name, version as app_version} from './path/to/package.json';
console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);
A safe option is to add an npm script that generates a separate version file:
"scripts": {
"build": "yarn version:output && blitz build",
"version:output": "echo 'export const Version = { version: \"'$npm_package_version.$(date +%s)'\" }' > version.js"
}
This outputs version.js with the contents:
export const Version = { version: "1.0.1.1622225484" }
To determine the package version in node code, you can use the following:
const version = require('./package.json').version; for < ES6 versions
import {version} from './package.json'; for ES6 version
const version = process.env.npm_package_version;
if application has been started using npm start, all npm_* environment variables become available.
You can use following npm packages as well - root-require, pkginfo, project-version.
we can read the version or other keys from package.json in two ways
1- using require and import the key required e.g:
const version = require('./package.json')
2 - using package_vars as mentioned in doc
process.env.npm_package_version
You can use the project-version package.
$ npm install --save project-version
Then
const version = require('project-version');
console.log(version);
//=> '1.0.0'
It uses process.env.npm_package_version but fallback on the version written in the package.json in case the env var is missing for some reason.
Why don't use the require resolve...
const packageJson = path.dirname(require.resolve('package-name')) + '/package.json';
const { version } = require(packageJson);
console.log('version', version)
With this approach work for all sub paths :)
In case you want to get version of the target package.
import { version } from 'TARGET_PACKAGE/package.json';
Example:
import { version } from 'react/package.json';
I know this isn't the intent of the OP, but I just had to do this, so hope it helps the next person.
If you're using docker-compose for your CI/CD process, you can get it this way!
version:
image: node:7-alpine
volumes:
- .:/usr/src/service/
working_dir: /usr/src/service/
command: ash -c "node -p \"require('./package.json').version.replace('\n', '')\""
for the image, you can use any node image. I use alpine because it is the smallest.
The leanest way I found:
const { version } = JSON.parse(fs.readFileSync('./package.json'))
I've actually been through most of the solutions here and they either did not work on both Windows and Linux/OSX, or didn't work at all, or relied on Unix shell tools like grep/awk/sed.
The accepted answer works technically, but it sucks your whole package.json into your build and that's a Bad Thing that only the desperate should use temporarily to get unblocked, and in general should be avoided, at least for production code. The alternative is to use that method only to write the version to a single constant that can be used instead of the whole file.
So for anyone else looking for a cross-platform solution (not reliant on Unix shell commands) and local (without external dependencies):
Since it can be assumed that Node.js is installed, and it's already cross-platform for this, I just created a make_version.js file with:
const PACKAGE_VERSION = require("./package.json").version;
console.log(`export const PACKAGE_VERSION = "${PACKAGE_VERSION}";`);
console.error("package.json version:", PACKAGE_VERSION);
and added a version command to package.json:
scripts: {
"version": "node make_version.js > src/version.js",
and then added:
"prebuild": "npm run version",
"prestart": "npm run version",
and it creates a new src/versions.js on every start or build. Of course this can be easily tuned in the version script to be a different location, or in the make_version.js file to output different syntax and constant name, etc.
I do this with findup-sync:
var findup = require('findup-sync');
var packagejson = require(findup('package.json'));
console.log(packagejson.version); // => '0.0.1'
I am using gitlab ci and want to automatically use the different versions to tag my docker images and push them. Now their default docker image does not include node so my version to do this in shell only is this
scripts/getCurrentVersion.sh
BASEDIR=$(dirname $0)
cat $BASEDIR/../package.json | grep '"version"' | head -n 1 | awk '{print $2}' | sed 's/"//g; s/,//g'
Now what this does is
Print your package json
Search for the lines with "version"
Take only the first result
Replace " and ,
Please not that i have my scripts in a subfolder with the according name in my repository. So if you don't change $BASEDIR/../package.json to $BASEDIR/package.json
Or if you want to be able to get major, minor and patch version I use this
scripts/getCurrentVersion.sh
VERSION_TYPE=$1
BASEDIR=$(dirname $0)
VERSION=$(cat $BASEDIR/../package.json | grep '"version"' | head -n 1 | awk '{print $2}' | sed 's/"//g; s/,//g')
if [ $VERSION_TYPE = "major" ]; then
echo $(echo $VERSION | awk -F "." '{print $1}' )
elif [ $VERSION_TYPE = "minor" ]; then
echo $(echo $VERSION | awk -F "." '{print $1"."$2}' )
else
echo $VERSION
fi
this way if your version was 1.2.3. Your output would look like this
$ > sh ./getCurrentVersion.sh major
1
$> sh ./getCurrentVersion.sh minor
1.2
$> sh ./getCurrentVersion.sh
1.2.3
Now the only thing you will have to make sure is that your package version will be the first time in package.json that key is used otherwise you'll end up with the wrong version
I'm using create-react-app and I don't have process.env.npm_package_version available when executing my React-app.
I did not want to reference package.json in my client-code (because of exposing dangerous info to client, like package-versions), neither I wanted to install an another dependency (genversion).
I found out that I can reference version within package.json, by using $npm_package_version in my package.json:
"scripts": {
"my_build_script": "REACT_APP_VERSION=$npm_package_version react-scripts start"
}
Now the version is always following the one in package.json.
I made a useful code to get the parent module's package.json
function loadParentPackageJson() {
if (!module.parent || !module.parent.filename) return null
let dir = path.dirname(module.parent.filename)
let maxDepth = 5
let packageJson = null
while (maxDepth > 0) {
const packageJsonPath = `${dir}/package.json`
const exists = existsSync(packageJsonPath)
if (exists) {
packageJson = require(packageJsonPath)
break
}
dir = path.resolve(dir, '../')
maxDepth--
}
return packageJson
}
If using rollup, the rollup-plugin-replace plugin can be used to add the version without exposing package.json to the client.
// rollup.config.js
import pkg from './package.json';
import { terser } from "rollup-plugin-terser";
import resolve from 'rollup-plugin-node-resolve';
import commonJS from 'rollup-plugin-commonjs'
import replace from 'rollup-plugin-replace';
export default {
plugins: [
replace({
exclude: 'node_modules/**',
'MY_PACKAGE_JSON_VERSION': pkg.version, // will replace 'MY_PACKAGE_JSON_VERSION' with package.json version throughout source code
}),
]
};
Then, in the source code, anywhere where you want to have the package.json version, you would use the string 'MY_PACKAGE_JSON_VERSION'.
// src/index.js
export const packageVersion = 'MY_PACKAGE_JSON_VERSION' // replaced with actual version number in rollup.config.js
const { version } = require("./package.json");
console.log(version);
const v = require("./package.json").version;
console.log(v);
Import your package.json file into your server.js or app.js and then access package.json properties into server file.
var package = require('./package.json');
package variable contains all the data in package.json.
Used to version web-components like this:
const { version } = require('../package.json')
class Widget extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
}
public connectedCallback(): void {
this.renderWidget()
}
public renderWidget = (): void => {
this.shadowRoot?.appendChild(this.setPageTemplate())
this.setAttribute('version', version)
}
}
I need a reliable way to clone a github repo and paste it into a local directory using node.js and any necessary npm packages.
This code is using the nodegit library and doesn't work to clone a github repo. it creates a single folder named .git and copies none of the files from the repo. I have tried several libraries most of which have extremely complicated code or don't work. This was working before but now isn't. (it goes on and off as it pleases). pls help, I need a reliable code that clones a github repo from url and pastes it into a local directory. Thank you.
var nodegit = require('nodegit'),
path = require('path');
var url = "https://github.com/atomicptr/dauntless-builder", //also tried https://github.com/atomicptr/dauntless-builder.git
local = "C:/data",
cloneOpts = {};
nodegit.Clone(url, local, cloneOpts).then(function (repo) {
console.log("cloning succesful!");
console.log("Cloned " + path.basename(url) + " to " + repo.workdir());
}).catch(function (err) {
console.log(err);
});
this code shows no errors, yet doesn't actually work to clone the repo.
You can use shelljs for this.
const shell = require('shelljs')
const path = 'absolute/path/to/folder'
shell.cd(path)
shell.exec('git clone https://github.com/atomicptr/dauntless-builder')
Assuming you have git installed on the machine you could simply run the clone command from node.
const path = require('path');
const{ execSync } = require('child_process');
execSync('git clone repolink', {
stdio: [0, 1, 2], // we need this so node will print the command output
cwd: path.resolve(__dirname, ''), // path to where you want to save the file
})
Try the git-clone npm package
npm i git-clone
var clone = require('git-clone');
clone(repo, targetPath, [options], cb);
Supported options:
git: path to git binary; default: git (optional).
shallow: when true, clone with depth 1 (optional).
checkout: revision/branch/tag to check out (optional).