【问题标题】:SyntaxError: "Cannot use import statement outside a module" - JavaScript in PythonSyntaxError: \"Cannot use import statement outside a module\" - Python 中的 JavaScript
【发布时间】:2022-11-26 11:28:52
【问题描述】:

问题陈述

我正在尝试使用 stpyv8 在 Python 中运行 JavaScript 代码。但是,我收到以下错误:

Traceback (most recent call last):
  File "/home/bobby/uni_balances_stpyv8/main.py", line 4, in <module>
    output = ctxt.eval("""
SyntaxError: SyntaxError: Cannot use import statement outside a module (  @ 3 : 0 )  -> import { JSBI } from "@uniswap/sdk";

我确实有一个 package.json 文件,我的直觉是 Python 代码没有考虑 json 文件,因为上面的错误实际上是由 package.json 文件解决的 Fixing module error in JS:

{
  "type": "module",
  "devDependencies": {
    "@babel/cli": "^7.19.3",
    "@babel/core": "^7.20.2",
    "@babel/preset-env": "^7.20.2"
  },
  "dependencies": {
    "@uniswap/sdk": "^3.0.3",
    "ethers": "^5.7.2"
  }
}

我有 package.json

JavaScript 确实运行并输出以下内容:

这是 JavaScript 文件:

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)

Python3代码:

import STPyV8

with STPyV8.JSContext() as ctxt:
  output = ctxt.eval("""

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("https://eth-mainnet.g.alchemy.com/v2/fRrLGBzCur7V6wCQjGRPdtmTUQzjCk2F")

    // 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)
  """
  )

output = ctxt.eval()
print(output())

再次回到我的预感,Python 是否有可能无法识别我的项目文件夹中的 package.json

【问题讨论】:

  • 我知道这本身可能是一个有趣的问题,但就实际解决方案而言,创建一个带有 webpack 或 rollup 的独立 JS 包,然后收工。
  • 谢谢@JaredSmith。我不确定“带有 webpack 或 rollup 的自包含 JS 捆绑包,收工”是什么意思。你有一些我可以阅读的资源吗?我没有确定我的解决方案并且对任何解决方案都持开放态度。我只需要以某种方式将 JS 的输出转换为 Python。
  • webpack.js.org/concepts。它是一个 CLI 程序,它采用 JS 应用程序,解析所有依赖关系,并将其连接到一个独立的源文件中,就像本机代码编译器可以生成静态链接的二进制可执行文件一样。它经常用于 JS 领域,因为给定的客户端 JS 应用程序将具有数百个依赖项,您通常不希望浏览器发出数百个 HTTP 请求。

标签: javascript python-3.x ethereum


【解决方案1】:

我认为您需要按照nodejs-convert-from-import-to-require 中的描述进行操作

所以改变:

import { JSBI } from "@uniswap/sdk";
import { ethers } from 'ethers';
import * as fs from 'fs';

const { JSBI } = require ("@uniswap/sdk")
const { ethers } = require ('ethers')
const fs = require('fs')

【讨论】:

  • 但现在我收到 required not defined 错误:`Traceback(最近一次调用最后一次):文件“/home/bobby/uni_balances_stpyv8/main.py”,第 4 行,在 <module> output = ctxt.eval(“”” ReferenceError: ReferenceError: require is not defined ( @ 3 : 17 ) -> const { JSBI } = require ("@uniswap/sdk") `
【解决方案2】:
SyntaxError: "Cannot use import statement outside a module"

这个错误很明显,你在错误的地方使用了import语句。例如,创建一个test.js文件并只添加这行代码

 import fs from "fs";

然后用node test.js执行文件。你会得到这个错误。

因为当您使用node命令执行文件时,它是node.js环境,它支持commonjs而不是es6 modules

一种解决方案是将文件扩展名从 js 更改为 mjs。如果您将 test.js 更改为 test.mjs 并运行 node test.mjs,您的代码将成功执行。

第二种解决方案是使用此语法代替 import

 const ethers = require('ethers');

第三种解决方案是将其添加到package.json 文件

 "type": "module"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2022-11-21
    • 2021-11-21
    • 2020-08-30
    • 2021-08-11
    • 2022-09-26
    相关资源
    最近更新 更多