繁体   English   中英

React + Redux + Typescript Chrome 扩展弹出脚本 - Redux Devtools 显示“找不到商店”

[英]React + Redux + Typescript Chrome Extension Popup Script - Redux Devtools Shows "No Store Found"

我正在创建一个主要在弹出脚本中提供的 chrome 扩展。

清单文件

// public/manifest.json

{
  "manifest_version": 3,
  "version": "3.0.0",
  "name": "__MSG_appName__",
  "description": "__MSG_appDesc__",
  "default_locale": "en",
  "author": "lbragile",
  "homepage_url": "some_url_not_relevant_to_question_at_hand",
  "permissions": ["tabs", "storage"],
  "optional_permissions": ["contextMenus", "alarms", "downloads", "downloads.shelf"],
  "icons": {
    "16": "images/logo16.png",
    "48": "images/logo48.png",
    "128": "images/logo128.png"
  },
  "action": {
    "default_icon": {
      "16": "images/logo16.png",
      "48": "images/logo48.png",
      "128": "images/logo128.png"
    },
    "default_popup": "index.html",
    "default_title": "title"
  },
  "background": {
    "service_worker": "background.js"
  },
  "incognito": "split"
}

包.json

// package.json

{
  "name": "name",
  "version": "0.0.1",
  "description": "description",
  "author": "lbragile",
  "private": true,
  "dependencies": {
    "nanoid": "^3.1.30",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.5",
    "react-router-dom": "^5.3.0",
    "react-scripts": "4.0.3",
    "redux": "^4.1.1"
  },
  "devDependencies": {
    "@babel/core": "^7.13.14",
    "@babel/preset-env": "^7.13.12",
    "@babel/preset-react": "^7.13.13",
    "@fortawesome/fontawesome-svg-core": "^1.2.36",
    "@fortawesome/free-regular-svg-icons": "^5.15.4",
    "@fortawesome/free-solid-svg-icons": "^5.15.4",
    "@fortawesome/react-fontawesome": "^0.1.15",
    "@types/chrome": "0.0.159",
    "@types/express": "^4.17.13",
    "@types/node": "^16.10.3",
    "@types/react": "^17.0.15",
    "@types/react-dom": "^17.0.9",
    "@types/react-redux": "^7.1.19",
    "@types/react-router-dom": "^5.1.8",
    "@types/redux-immutable-state-invariant": "^2.1.2",
    "@types/remote-redux-devtools": "^0.5.5",
    "@types/styled-components": "^5.1.12",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "babel-loader": "^8.2.3",
    "babel-plugin-styled-components": "^1.13.2",
    "copy-webpack-plugin": "^9.0.1",
    "eslint": "^7.11.0",
    "eslint-plugin-react": "^7.24.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "eslint-plugin-styled-components-a11y": "0.0.34",
    "redux-devtools-extension": "^2.13.9",
    "styled-components": "^5.3.0",
    "stylelint": "^13.13.1",
    "stylelint-config-standard": "^22.0.0",
    "ts-loader": "^9.2.6",
    "typescript": "^4.3.5",
    "url-loader": "^4.1.1",
    "webpack": "^5.59.1",
    "webpack-cli": "^4.9.1"
  },
  "scripts": {
    "lint": "npx eslint {src,public}/**/**/*.[jt]s -c config/.eslintrc.js --ignore-path .gitignore .",
    "lint:style": "npx stylelint {src,public}/**/**/*.css --config config/.stylelintrc.json",
    "start": "webpack --config config/webpack.config.js --watch --progress"
  },
  "babel": {
    "extends": "./config/.babelrc.json"
  },
  "eslintConfig": {
    "extends": "./config/.eslintrc.js"
  },
  "stylelint": {
    "extends": "./config/.stylelintrc.json"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

网络包

// config/webpack.config.js

const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  entry: {
    popup: path.resolve(__dirname, "../src/index.tsx"),
    background: path.resolve(__dirname, "../src/background.ts"),
  },
  plugins: [
    new CopyPlugin({
      patterns: [{ from: "public", to: "." }],
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: "babel-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.ts(x)?$/,
        loader: "ts-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.png$/,
        use: [
          {
            loader: "url-loader",
            options: {
              mimetype: "image/png",
            },
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: [".js", ".jsx", ".ts", ".tsx"],
  },
  mode: "production",
  output: {
    path: path.resolve(__dirname, `../dist`),
    filename: "[name].js",
  },
};

问题

我试过redux-devtools-extension

// src/index.tsx

import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import { Provider } from "react-redux";
import { createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import rootReducer from "./store/reducers";

export const store = createStore(rootReducer, composeWithDevTools());

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

这表现了:

未找到商店

我也试过使用remote-redux-devtools

// src/index.tsx

import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import { Provider } from "react-redux";
import { createStore } from "redux";
import devToolsEnhancer from "remote-redux-devtools";
import rootReducer from "./store/reducers";

export const store = createStore(rootReducer, devToolsEnhancer());

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

这似乎更有希望,但存储中没有数据:

远程 Redux 窗口

当我在浏览器中运行时,使用npm start ( react-scripts start ),我确实在Redux DevTools扩展中看到了 store,所以我不确定问题是什么。

可能的想法

当我使用 React ( react-scripts build ) react-scripts build ,我可以很好地看到商店。 问题是我不能使用 react,因为它的构建时间太慢,而使用 webpack 似乎是最合乎逻辑的选择。 这是构建输出:

在 React 构建之后工作

有任何想法吗?

我认为问题在于__REDUX_DEVTOOLS_EXTENSION_COMPOSE__在以下代码中丑化了__REDUX_DEVTOOLS_EXTENSION_COMPOSE__

您可以尝试以下操作:

import { createStore, compose } from 'redux'
//same code as original but with bracket notation
const composeWithDevTools = (
  typeof window !== 'undefined' && window["__REDUX_DEVTOOLS_EXTENSION_COMPOSE__"] ?
    window["__REDUX_DEVTOOLS_EXTENSION_COMPOSE__"] :
    function() {
      if (arguments.length === 0) return undefined;
      if (typeof arguments[0] === 'object') return compose;
      return compose.apply(null, arguments);
    }
);
//your original code but using your composeWithDevTools 
export const store = createStore(rootReducer, composeWithDevTools());

您不需要从 redux-devtools-extension 导入 composeWithDevTools,因为您是自己创建的,但是如果这解决了问题,您应该创建一个请求括号表示法的 问题,这样 uglify 就不会破坏代码。

要查看编​​译后的代码是什么,您可以在 createStore 之前添加控制台日志: console.log("creating store")然后您可以在 chrome devtools(Command+Shift+P 或 Control+Shift+P)中禁用源映射,然后搜索控制台文本creating store快捷方式是:command+alt+f 或 control+shift+f)

注意:此答案最初是由 OP 添加作为对其原始问题的编辑,我刚刚将其重新发布为答案。

服务器需要运行,并且应该使用remote redux devtools而不是redux devtools extension

最好的方法如下:

  1. 安装 npmjs.com/package/remotedev-server
  2. 添加"remotedev": "remotedev --hostname=localhost --port=8080" npm 脚本
  3. 运行上面的脚本来启动一个服务器
  4. 右键单击弹出窗口, Redux DevTools > Open Remote DevTools (不inspect
  5. 设置 > 使用自定义本地服务器 > 输入在 npm 脚本中指定的主机名和端口。

这是我的商店的样子:

import { createStore } from "redux";
import { composeWithDevTools } from "remote-redux-devtools";
import rootReducer from "./store/reducers";

const composeEnhancers = composeWithDevTools({
  realtime: true,
  hostname: "localhost",
  port: 8080
});

export const store = createStore(rootReducer, composeEnhancers());

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM