简体   繁体   中英

Target is not a DOM element in an Electron-React-Typescript-Webpack app

For the mainWindow alone the rendering is fine.

webpack.config.js :

var renderer_config =  {
  mode: isEnvProduction ? 'production' : 'development',
  entry: {
    app: './src/app/index.tsx',
    //app_A: './src/app_A/index_A.tsx',
  },
  target: 'electron-renderer',
  output: {
    path: __dirname + '/dist/',
      //filename: 'renderer.js'
    filename: '[name].js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      //title: 'MainWindowTemplate',
      filename: 'index.html',
      template: './src/app/index.html'
      })

在此处输入图像描述

But when I add the second window, I get this error for the second window:

First Window:

在此处输入图像描述

Second Window:

在此处输入图像描述

webpack.config.js :

var renderer_config =  {
    mode: isEnvProduction ? 'production' : 'development',
    entry: {
      app: './src/app/index.tsx',
      app_A: './src/app_A/index_A.tsx',
    },
    target: 'electron-renderer',     output: {
      path: __dirname + '/dist/',
        //filename: 'renderer.js'
      filename: '[name].js',
    },
    plugins: [
      new HtmlWebpackPlugin({
        //title: 'MainWindowTemplate',
        filename: 'index.html',
        template: './src/app/index.html'
      }),
      new HtmlWebpackPlugin({
        title:'WindowTypeATemplate',
        filename: 'index_A.html',
        template: './src/app_A/index_A.html',
      }) 
var main_config = {
    mode: isEnvProduction ? 'production' : 'development',
    entry: './src/main/main.ts',
    target: 'electron-main',
    output: {
      path: __dirname + '/dist',
      filename: 'main.js'
    },

This is main.ts :

let mainWindow
let WindowTypeA;

function createMainWindow () {

  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      enableRemoteModule: false,
      contextIsolation: true,
      nodeIntegrationInWorker: false,
      nodeIntegrationInSubFrames: false,
      webSecurity: true,
      webviewTag: false,
      preload: path.join(__dirname, "./preload/preload.js"), /* eng-disable PRELOAD_JS_CHECK  
*/
    }
  })

  let mainFilePath = path.join(__dirname, '../index.html');

  mainWindow.loadURL(`file://${mainFilePath}`).finally(() => {
    console.log("mainWindow loaded");
  });

  // Open the DevTools only once DOM is ready
  mainWindow.webContents.once("dom-ready", async() => {
    mainWindow.webContents.openDevTools();
  });

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    mainWindow = null
  })
}

function createWindowTypeA () {
  WindowTypeA = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      enableRemoteModule: false,
      contextIsolation: true,
      nodeIntegrationInWorker: false,
      nodeIntegrationInSubFrames: false,
      webSecurity: true,
      webviewTag: false,
      preload: path.join(__dirname, "./preload/preload.js"), /* eng-disable PRELOAD_JS_CHECK
 */
   }
      })
  let WindowAFilePath = path.join(__dirname, '../index_A.html');
  WindowTypeA.loadURL(`file://${WindowAFilePath}`).finally(() => {
    console.log("WindowTypeA loaded");
  });
  // Open the DevTools once the DOM is ready
  WindowTypeA.webContents.once("dom-ready", async() => {
    WindowTypeA.webContents.openDevTools()
  });

  // Emitted when the window is closed.
  WindowTypeA.on('closed', () => {
    WindowTypeA = null
  })
}

 ipcMain.handle("open-type-A-window", (IpcMainEvent, message) => {
  createWindowTypeA();
  WindowTypeA.show();

  WindowTypeA.webContents.on('did-finish-load', function () {
    mainWindow.webContents.send('window-A-opened', 'ok');
  });
});

src/app_A/index_A.html :

 <!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Second Type of Window</title>
  </head>
  <body>
    <h1>Welcome to Type-A Window</h1>
    <div id="app_A"></div>
    <script type="javascript" defer src="./app_A/index_A.js"></script>
  </body>
</html>

src/app_A/index_A.tsx :

import React from 'react';
import ReactDOM from 'react-dom';
import App_A from './components/App_A';
import './styles/index.less';

ReactDOM.render(
  <React.StrictMode>
    <App_A />
  </React.StrictMode>,
  document.getElementById('app_A')
);
console.log("index_A.tsx loaded"); 

src/app_A/components/App_A.tsx :

import * as React from 'react';
function App_A() {
  console.log("rendering page App_A.tsx called!!"); 
} 
export default App_A;  

This is the compiled folder dist :

/dist$ ls -lah
total 9,7M
drwxr-xr-x 6 marco marco 4,0K feb 20 18:02 .
drwxr-xr-x 7 marco marco 4,0K feb 20 18:08 ..
drwxr-xr-x 3 marco marco 4,0K feb 20 18:02 app
drwxr-xr-x 3 marco marco 4,0K feb 20 18:02 app_A
-rw-r--r-- 1 marco marco 1,1M feb 20 18:02 app_A.js
-rw-r--r-- 1 marco marco 1,1M feb 20 18:02 app.js
-rw-r--r-- 1 marco marco  111 feb 20 18:02 global.js
-rw-r--r-- 1 marco marco  104 feb 20 18:02 global.js.map
-rw-r--r-- 1 marco marco  347 feb 20 18:02 index_A.html
-rw-r--r-- 1 marco marco  372 feb 20 18:02 index.html
drwxr-xr-x 3 marco marco 4,0K feb 20 18:02 main
-rw-r--r-- 1 marco marco 7,7M feb 20 18:02 main.js

dist/app_A :

total 20K
drwxr-xr-x 3 marco marco 4,0K feb 20 18:02 .
drwxr-xr-x 6 marco marco 4,0K feb 20 18:02 ..
drwxr-xr-x 2 marco marco 4,0K feb 20 18:02 components
-rw-r--r-- 1 marco marco 1,2K feb 20 18:02 index_A.js
-rw-r--r-- 1 marco marco  399 feb 20 18:02 index_A.js.map

dist/app_A/components :

drwxr-xr-x 2 marco marco 4,0K feb 20 18:02 .
drwxr-xr-x 3 marco marco 4,0K feb 20 18:02 ..
-rw-r--r-- 1 marco marco 3,1K feb 20 18:02 App_A.js
-rw-r--r-- 1 marco marco 1,7K feb 20 18:02 App_A.js.map

I tried also to add a listener "DOMContenttLoaded": index_A.html :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Second Type of Window</title>
  </head>
  <body>
    <h1>Welcome to Type-A Window</h1>
    <div id="app_A"></div>
    <script type="javascript">
      document.addEventListener("DOMContentLoaded", function(event) {
        defer src="./app_A/index_A.js"
      });
    </script>
  </body>
</html>

But still the same error: Target is not a DOM element for the second window.

I do not understand:

  • why while the rendering of the mainWindow works fine, the rendering of the second window gives this error Target container is not a DOM element
  • why I get the correct console.log rendering page App_A.tsx called!! if Target container is not a DOM element

And why Target container is not a DOM element for WindowTypeA (Second Window) if the compilation loads index_A.html , index_a.tsx and App_A.tsx :

yarn run v1.22.5
$ yarn run build && electron ./dist/main/main.js
$ webpack --config ./webpack.config.js
asset main.js 7.65 MiB [emitted] (name: main)
runtime modules 1.06 KiB 6 modules
javascript modules 6.04 MiB
  cacheable modules 6.03 MiB 1212 modules
  29 modules
json modules 393 KiB
  modules by path ./node_modules/har-schema/lib/*.json 6.93 KiB 18 modules
  modules by path ./node_modules/encoding/node_modules/iconv-lite/encodings/tables/*.json 
86.7 KiB 8 modules
  modules by path ./node_modules/ajv/lib/refs/*.json 5.58 KiB
    ./node_modules/ajv/lib/refs/json-schema-draft-06.json 2.46 KiB [built] [code generated]
    ./node_modules/ajv/lib/refs/json-schema-draft-07.json 2.72 KiB [built] [code generated]
    ./node_modules/ajv/lib/refs/data.json 409 bytes [built] [code generated]
  7 modules
webpack 5.23.0 compiled successfully in 7730 ms

assets by path *.js 2 MiB
  asset app_A.js 1 MiB [emitted] (name: app_A)
  asset app.js 1 MiB [emitted] (name: app)
assets by path *.html 719 bytes
  asset index.html 372 bytes [emitted]
  asset index_A.html 347 bytes [emitted]
runtime modules 1.83 KiB 8 modules
cacheable modules 993 KiB
  modules by path ./node_modules/ 981 KiB
    modules by path ./node_modules/scheduler/ 31.8 KiB 4 modules
    modules by path ./node_modules/react/ 70.6 KiB 2 modules
    modules by path ./node_modules/react-dom/ 875 KiB 2 modules
    ./node_modules/css-loader/dist/runtime/api.js 1.57 KiB [built] [code generated]
    ./node_modules/object-assign/index.js 2.06 KiB [built] [code generated]
  modules by path ./src/ 12.4 KiB
    modules by path ./src/app/ 5.04 KiB 3 modules
    modules by path ./src/app_A/ 7.34 KiB
      ./src/app_A/index_A.tsx 1.02 KiB [built] [code generated]
      ./src/app_A/components/App_A.tsx 5.15 KiB [built] [code generated]
      ./src/app_A/styles/index.less 1.17 KiB [built] [code generated]
webpack 5.23.0 compiled successfully in 4063 ms
  • electron: 11.2.3
  • webpack: 5.23.0
  • node: 14.5.0
  • OS: Ubuntu 18.04.4 Desktop

Looking forward to your expert help. I'm here to learn

An Electron and Webpack Expert explained me two things to fix:

First: My scripts were loaded in the head (even if I put them at the end of the body in.html files,). so before the element is renderered yet. The solution is to inject the scripts in the body

Second: I needed to load the script for a particular page: app_A for index_A.html, app for index.html

new HtmlWebpackPlugin({
    filename: 'index.html',
    template: './src/app/index.html',
    inject: 'body',
    chunks: ["app"]
  }),
  new HtmlWebpackPlugin({
    filename: 'index_A.html',
    template: './src/app_A/index_A.html',
    inject: 'body',
    chunks: ["app_A"]
  })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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