谷歌电子表格 api 在使用 webpack 的反应应用程序中引发 crypto.createSign 错误

Posted

技术标签:

【中文标题】谷歌电子表格 api 在使用 webpack 的反应应用程序中引发 crypto.createSign 错误【英文标题】:Google spreadsheet api throws crypto.createSign error in react app with webpack 【发布时间】:2022-01-21 04:38:34 【问题描述】:

我有一个带有 webpack 最近升级到版本 5 的 react 应用。

我收到以下错误,需要帮助来修复它

Uncaught (in promise) TypeError: crypto.createSign is not a function
    at Object.sign (index.js:151)
    at Object.jwsSign [as sign] (sign-stream.js:32)
    at GoogleToken.requestToken (index.js:225)
    at GoogleToken.getTokenAsyncInner (index.js:163)
    at GoogleToken.getTokenAsync (index.js:142)
    at GoogleToken.getToken (index.js:94)
    at JWT.refreshTokenNoCache (jwtclient.js:158)
    at JWT.refreshToken (oauth2client.js:143)
    at JWT.authorizeAsync (jwtclient.js:139)
    at JWT.authorize (jwtclient.js:135)

执行以下代码时(凭据正确)

const  GoogleSpreadsheet  = require("google-spreadsheet");
.
.
.

let submitOrderDetails = async () => 
  const SPREADSHEET_ID = "working-id-here";
  const doc = new GoogleSpreadsheet(SPREADSHEET_ID);

  // this fails
  await doc.useServiceAccountAuth(
    client_email: creds.client_email,
    private_key: creds.private_key,
  );

.
.
.

webpack.config.json

const htmlWebPackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");

module.exports = 
  context: __dirname,
  entry: "./src/index.js",
  output: 
    path: path.join(__dirname, "build"),
    filename: "main.js",
    publicPath: "/",
  ,
  target: "web",
  devServer: 
    historyApiFallback: true,
  ,
  module: 
    rules: [
      
        test: /\.js$/,
        exclude: /node_modules/,
        use: "babel-loader",
      ,
      
        test: /\.scss$/,
        use: [
          "style-loader", //3. Inject styles into DOM
          "css-loader", //2. Turns css into commonjs
          "sass-loader", //1. Turns sass into css
        ],
      ,
      
        test: /\.(png|jp?g|svg|gif)?$/,
        use: 
          loader: "file-loader",
        ,
      ,
    ],
  ,
  plugins: [
    new HtmlWebPackPlugin(
      template: path.join(__dirname, "public/index.html"),
      filename: "index.html",
    ),
    new webpack.ProvidePlugin(
      process: "process/browser",
    ),
  ],
  resolve: 
    fallback: 
      fs: false,
      tls: false,
      net: false,
      path: false,
      zlib: false,
      http: false,
      https: false,
      stream: false,
      crypto: false,
      "crypto-browserify": require.resolve("crypto-browserify"),
      os: require.resolve("os-browserify/browser"),
      child_process: false,
    ,
  ,
;

package.json


  "name": "my-project",
  "version": "0.1.0",
  "private": true,
  "dependencies": 
    "crypto": "^1.0.1",
    "crypto-browserify": "^3.12.0",
    "fs": "0.0.1-security",
    "google-spreadsheet": "^3.2.0",
    "googleapis": "^67.0.0",
    "http": "0.0.1-security",
    "https-browserify": "^1.0.0",
    "net": "^1.0.2",
    "os": "^0.1.2",
    "path": "^0.12.7",
    "prettier": "^2.5.1",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-router-dom": "^5.3.0",
    "react-scripts": "4.0.1",
    "stream": "0.0.2",
    "tls": "0.0.1",
    "zlib": "^1.0.5"
  ,
  "scripts": 
    "start": "webpack serve --mode development",
    "build": "webpack --mode production",
    "pretty": "prettier --write \"./**/*.*\""
  ,
  "eslintConfig": 
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  ,
  "browserslist": 
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  ,
  "devDependencies": 
    "@babel/core": "^7.16.5",
    "@babel/plugin-proposal-class-properties": "^7.16.5",
    "@babel/plugin-transform-runtime": "^7.16.5",
    "@babel/preset-env": "^7.16.5",
    "@babel/preset-react": "^7.16.5",
    "babel-loader": "^8.2.3",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^5.2.7",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.4.5",
    "node-sass": "^6.0.1",
    "optimize-css-assets-webpack-plugin": "^6.0.1",
    "process": "^0.11.10",
    "sass-loader": "^12.4.0",
    "style-loader": "^2.0.0",
    "terser-webpack-plugin": "^5.3.0",
    "webpack": "^5.65.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^3.11.3",
    "webpack-merge": "^5.8.0"
  

【问题讨论】:

1) 您能否附加指向 Google 表格的链接? 2) 使用 Google Apps Script 不是更容易吗? @taylor.2317 您所说的“您能附加到 Google 表格的链接吗?”是什么意思? 2)我需要从网站提交信息到谷歌文档。 Google Apps 脚本怎么可能做到这一点? 抱歉,标题为“Google 电子表格”和标签 google-sheets-api,我以为您指的是 Google 表格。 请将您的标签更改为google-docs-api。 【参考方案1】:

回答我自己的问题。我通过添加后备更新了 webpack 配置。 以下是更新后的webpack.config.jsonpackage.json

webpack.config.json

const HtmlWebPackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");

module.exports = 
  context: __dirname,
  entry: "./src/index.js",
  output: 
    path: path.join(__dirname, "build"),
    filename: "main.js",
    publicPath: "/",
  ,
  target: "web",
  devServer: 
    historyApiFallback: true,
  ,
  module: 
    rules: [
      
        test: /\.js$/,
        exclude: /node_modules/,
        use: "babel-loader",
      ,
      
        test: /\.scss$/,
        use: [
          "style-loader", //3. Inject styles into DOM
          "css-loader", //2. Turns css into commonjs
          "sass-loader", //1. Turns sass into css
        ],
      ,
      
        test: /\.(png|jp?g|svg|gif)?$/,
        use: 
          loader: "file-loader",
        ,
      ,
    ],
  ,
  plugins: [
    new HtmlWebPackPlugin(
      template: path.join(__dirname, "public/index.html"),
      filename: "index.html",
    ),
    new webpack.ProvidePlugin(
      process: "process/browser",
      Buffer: ["buffer", "Buffer"],
    ),
  ],
  resolve: 
    fallback: 
      fs: false,
      tls: "empty",
      child_process: false,
      util: require.resolve("util/"),
      buffer: require.resolve("buffer"),
      assert: require.resolve("assert/"),
      http: require.resolve("stream-http"),
      path: require.resolve("path-browserify"),
      https: require.resolve("https-browserify"),
      os: require.resolve("os-browserify/browser"),
      stream: require.resolve("stream-browserify"),
      crypto: require.resolve("crypto-browserify"),
      "crypto-browserify": require.resolve("crypto-browserify"),
    ,
  ,
;

package.json


  "name": "sigmaprints",
  "version": "1.0.0",
  "private": true,
  "scripts": 
    "start": "webpack serve --mode development",
    "build": "webpack --mode production",
    "pretty": "prettier --write \"./**/*.*\""
  ,
  "devDependencies": 
    "@babel/core": "^7.12.1",
    "@babel/plugin-proposal-class-properties": "^7.12.1",
    "@babel/plugin-transform-runtime": "^7.14.5",
    "@babel/preset-env": "^7.12.1",
    "@babel/preset-react": "^7.12.1",
    "babel-loader": "^8.1.0",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^6.2.1",
    "cross-env": "^7.0.2",
    "css-loader": "^5.0.0",
    "file-loader": "^6.2.0",
    "css-minimizer-webpack-plugin": "^1.1.5",
    "process": "0.11.10",
    "html-webpack-plugin": "^4.5.0",
    "node-sass": "^4.14.1",
    "optimize-css-assets-webpack-plugin": "^5.0.4",
    "prettier": "^2.1.2",
    "sass-loader": "^10.0.3",
    "style-loader": "^2.0.0",
    "terser-webpack-plugin": "^4.2.3",
    "webpack": "^5.1.2",
    "webpack-cli": "^4.0.0",
    "webpack-dev-server": "^3.11.0",
    "webpack-merge": "^5.2.0"
  ,
  "browser": 
    "crypto": false
  ,
  "dependencies": 
    "assert": "^2.0.0",
    "buffer": "^6.0.3",
    "crypto-browserify": "^3.12.0",
    "google-spreadsheet": "^3.1.15",
    "http-browserify": "^1.7.0",
    "https-browserify": "^1.0.0",
    "net": "^1.0.2",
    "os-browserify": "^0.3.0",
    "path-browserify": "^1.0.1",
    "react": "^16.14.0",
    "react-dom": "^16.14.0",
    "react-router-dom": "^5.2.0",
    "stream-browserify": "^3.0.0",
    "stream-http": "^3.2.0",
    "tls": "0.0.1",
    "util": "^0.12.4"
  

【讨论】:

以上是关于谷歌电子表格 api 在使用 webpack 的反应应用程序中引发 crypto.createSign 错误的主要内容,如果未能解决你的问题,请参考以下文章

html 谷歌驱动器api,电子表格

谷歌表格 API 请求上的 CORS 授权

如何在谷歌云功能中使用谷歌表格 API

Chrome 扩展写入谷歌电子表格 [关闭]

谷歌表格 API 上的“更新”方法

使用 Google Data API 使用 C# 访问 Google 电子表格