admin管理员组

文章数量:1315829

I'm trying to build a chrome extension using React. I've ejected create-react-app and have made necessary changes to emit content.chunk.js which is included in manifest.json as below

{
  "manifest_version": 2,
  "version": "0.0.1",
  "name": "My extension",
  "description": "Some description",
  "permissions": [],
  "browser_action": {
    "default_title": "My extension",
    "default_popup": "index.html"
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "css": ["/static/css/content.chunk.css"],
    "js": ["/static/js/content.chunk.js"]
  }]
}

my content.js

import React from 'react';
import ReactDOM from 'react-dom';
import Main from 'extensionContainers/Main';

alert('bazooka!');
const app = document.createElement('div');
app.id = "extension-root";
document.body.appendChild(app);

ReactDOM.render(<Main />, app);

after build, when I load my extension this doesn't do anything. However, when I edit the contents of content.chunk.js generated by webpack to alert("something"), the extension works fine and shows alert on every URL.

Why is my react code isn't doing anything? There are no error logs.

I'm trying to build a chrome extension using React. I've ejected create-react-app and have made necessary changes to emit content.chunk.js which is included in manifest.json as below

{
  "manifest_version": 2,
  "version": "0.0.1",
  "name": "My extension",
  "description": "Some description",
  "permissions": [],
  "browser_action": {
    "default_title": "My extension",
    "default_popup": "index.html"
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "css": ["/static/css/content.chunk.css"],
    "js": ["/static/js/content.chunk.js"]
  }]
}

my content.js

import React from 'react';
import ReactDOM from 'react-dom';
import Main from 'extensionContainers/Main';

alert('bazooka!');
const app = document.createElement('div');
app.id = "extension-root";
document.body.appendChild(app);

ReactDOM.render(<Main />, app);

after build, when I load my extension this doesn't do anything. However, when I edit the contents of content.chunk.js generated by webpack to alert("something"), the extension works fine and shows alert on every URL.

Why is my react code isn't doing anything? There are no error logs.

Share Improve this question edited Jul 30, 2019 at 11:53 Vishal Sharma asked Jul 30, 2019 at 11:42 Vishal SharmaVishal Sharma 2,6101 gold badge25 silver badges43 bronze badges 2
  • The usual reason is that your config produces a module script that only registers its exported functions but never actually invokes them. I don't know react/webpack so I don't know what exactly you need to change in your config, but hopefully there are existing solutions. – woxxom Commented Jul 30, 2019 at 12:02
  • @wOxxOm I don't think that's happening. If I add the generated content.chunk.js in an HTML page as a script tag, it works as expected. However, through content script I don't see anything happening. – Vishal Sharma Commented Jul 31, 2019 at 10:00
Add a ment  | 

2 Answers 2

Reset to default 9

Answering my own question if anyone else stumbles upon this.

So, I realized that the Webpack config from [email protected] ejection had code split configurations enabled. Which was splitting react library code from my code making it inexecutable.

Here are the settings I changed in the webpack config to get it working. (note that this is only advisable to do when developing chrome extension)

In webpack.config.js remove the configuration for splitChunks under optimization node, and set runtimeChunk to false.

...
optimization: {
  .
  .
  // remove spitChunks config
  splitChunks: {
     chunks: 'all',
     name: false,
  },
  runtimeChunk: true, // set this to false
}
...

the generated bundle will now be named as content.js (considering content as the entry point) link this content.js in your manifest.json under content_scripts and you're good to go.

Now, we don't need to edit the Webpack.config.js anymore instead, we can configure our own using

  1. customize-cra,
  2. react-app-rewired,
  3. copy-webpack-plugin,
  4. react-app-rewire-multiple-entry

1 and 2 will overwrite the webpack default configuration, 3 to copy all of our assets files, and 4 to add multiple files

Just install it:

npm -i customize-cra react-app-rewired copy-webpack-plugin react-app-rewire-multiple-entry --save-dev

Yarn

yarn add customize-cra react-app-rewired copy-webpack-plugin react-app-rewire-multiple-entry --dev

Configuration

create a config-overrides.js file in your root directory / and put use this code

const {
   override,
   overrideDevServer,
   addWebpackPlugin
} = require("customize-cra");
const CopyPlugin = require('copy-webpack-plugin');

const multipleEntry = require('react-app-rewire-multiple-entry')([
   {
      // points to the popup entry point
      entry: 'src/popup/index.js',
      template: 'public/popup.html',
      outPath: '/popup.html'
   },
   {
      // points to the options page entry point
      entry: 'src/options/index.js',
      template: 'public/index.html',
      outPath: '/index.html'
   }
]);

const devServerConfig = () => config => {
   return {
      ...config,
      // webpackDevService doesn't write the files to desk
      // so we need to tell it to do so so we can load the
      // extension with chrome
      writeToDisk: true
   }
}

const copyPlugin = new CopyPlugin({
   patterns: [
      // copy assets
      { from: 'public', to: '' },
      { from: 'src/background.js', to: '' }
   ]
})

module.exports = {
   webpack: override(
      addWebpackPlugin(
         copyPlugin
      ),
      multipleEntry.addMultiEntry,
   ),
   devServer: overrideDevServer(
      devServerConfig()
   ),

};

go ahead and create two folders in src/, options/, and popup containing the index.js and app.js files, mean copy all the files from src/ when you install React and past it to these both folders. for the background.js file you should put this on the src/:

/
   src/
      background.js
      index.js // empty file only
      options
         index.js
         app.js
         app.css
      popup
         index.js
         app.js
         app.css
 

Also overide the script in the package.json file to:

"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  }

now you don't need to reload the extension after changes, it will automatically trigger when you save your code.

another file is to create is .env in the root directory and past this:

INLINE_RUNTIME_CHUNK=false

Now run the mand yarn start or npm start, load the extension you should be good to go!

Resource to learn

本文标签: javascriptChrome extension content script not injecting to the DOM when built with ReactJSStack Overflow