ค้นหาเว็บไซต์

javascript - electron webpack เกิดข้อผิดพลาด Uncaught ReferenceError: require ยังไม่ได้กำหนด "querystring"


ฉันกำลังพยายามรันแอป Electron เก่า แต่ฉันไม่สามารถหาว่าควรใช้เวอร์ชัน Node ไหน หรือควรอัปเดตส่วนไหนของการตั้งค่าหรือการพึ่งพา

ฉันเพิ่ม webPreferences ของอิเล็กตรอนในหน้าต่าง แต่ก็ไม่ได้ช่วยอะไร

    webPreferences: {
      nodeIntegration: true,
      nodeIntegrationInWorker: true,
      contextIsolation: false,
      enableRemoteModule: true,
    },

มีใครพอจะมีไอเดียไหมว่าควรตรวจสอบอะไรเป็นอันดับแรก? ฉันควรลองแก้ไขคำเตือนในสภาพปัจจุบันของแอปก่อนหรือควรอัปเดต dependencies แล้วค่อยแก้ไขปัญหาใหญ่ ๆ?

yarn dev

yarn run v1.22.19
webpack-dev-server --hot --watch --config webpack.config.dev.js
i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from http://localhost:8080/
i 「atl」: Using [email  from typescript
i 「atl」: Using tsconfig.json from ./tsconfig.json
i 「atl」: Using [email  from typescript
i 「atl」: Using tsconfig.json from ./tsconfig.json
i 「atl」: Checking started in a separate process...
i 「atl」: Time: 3514ms
i 「atl」: Checking started in a separate process...
i 「atl」: Time: 2355ms
‼ 「wdm」: Hash: 4697290ef706a2a99ad5e1b5fab076995682e95f
Version: webpack 4.30.0
Child
    Hash: 4697290ef706a2a99ad5
    Time: 17242ms
    Built at: 2023-05-24 15:55:15
        Asset      Size  Chunks             Chunk Names
    bundle.js  6.53 MiB    main  [emitted]  main
    Entrypoint main = bundle.js
    [0] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./src/index.tsx 52 bytes {main} [built]
    [./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
    [./node_modules/mousetrap/mousetrap.js] 33.1 KiB {main} [built]
    [./node_modules/react-dom/index.js] 1.33 KiB {main} [built]
    [./node_modules/react-redux/es/index.js] 416 bytes {main} [built]
    [./node_modules/react/index.js] 190 bytes {main} [built]
    [./node_modules/strip-ansi/index.js] 161 bytes {main} [built]
    [./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 8.26 KiB {main} [built]
    [./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.59 KiB {main} [built]
    [./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {main} [built]
    [./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
    [./node_modules/webpack/hot/dev-server.js] (webpack)/hot/dev-server.js 1.61 KiB {main} [built]
    [./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built]
    [./node_modules/webpack/hot/log-apply-result.js] (webpack)/hot/log-apply-result.js 1.27 KiB {main} [built]
    [./src/index.tsx] 7.99 KiB {main} [built]
        + 695 hidden modules

    WARNING in ./node_modules/fluent-ffmpeg/lib/options/misc.js 27:21-40
    Critical dependency: the request of a dependency is an expression
     @ ./node_modules/fluent-ffmpeg/lib/fluent-ffmpeg.js
     @ ./node_modules/fluent-ffmpeg/index.js
     @ ./src/common/Util.js
     @ ./src/views/Duplicates.tsx
     @ ./src/index.tsx
Child
    Hash: e1b5fab076995682e95f
    Time: 13857ms
    Built at: 2023-05-24 15:55:11
            Asset      Size  Chunks             Chunk Names
    background.js  4.33 MiB    main  [emitted]  main
    Entrypoint main = background.js
    [0] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./background.ts 52 bytes {main} [built]
    [./background.ts] 1010 bytes {main} [built]
    [./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
    [./node_modules/strip-ansi/index.js] 161 bytes {main} [built]
    [./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 8.26 KiB {main} [built]
    [./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.59 KiB {main} [built]
    [./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {main} [built]
    [./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
    [./node_modules/webpack/hot/dev-server.js] (webpack)/hot/dev-server.js 1.61 KiB {main} [built]
    [./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built]
    [./node_modules/webpack/hot/log-apply-result.js] (webpack)/hot/log-apply-result.js 1.27 KiB {main} [built]
    [./node_modules/webpack/hot/log.js] (webpack)/hot/log.js 1.11 KiB {main} [built]
    [./src/background/BackgroundWindow.ts] 10.1 KiB {main} [built]
    [./src/main/Logger.js] 1010 bytes {main} [built]
    [querystring] external "querystring" 42 bytes {main} [built]
        + 586 hidden modules

    WARNING in ./node_modules/fluent-ffmpeg/lib/options/misc.js 27:21-40
    Critical dependency: the request of a dependency is an expression
     @ ./node_modules/fluent-ffmpeg/lib/fluent-ffmpeg.js
     @ ./node_modules/fluent-ffmpeg/index.js
     @ ./src/background/ScreenshotEngine.ts
     @ ./src/background/BackgroundWindow.ts
     @ ./background.ts

    WARNING in ./node_modules/chokidar/lib/fsevents-handler.js
    Module not found: Error: Can't resolve 'fsevents' in '.\node_modules\chokidar\lib'
     @ ./node_modules/chokidar/lib/fsevents-handler.js
     @ ./node_modules/chokidar/index.js
     @ ./src/background/Watcher.ts
     @ ./src/background/BackgroundWindow.ts
     @ ./background.ts
i 「wdm」: Compiled with warnings.

คอนโซล :

Uncaught ReferenceError: require is not defined
    at eval (external_"querystring":1:18)
    at Object.querystring (bundle.js:8870:1)
    at __webpack_require__ (bundle.js:703:30)
    at fn (bundle.js:77:20)
    at Object.eval (webpack:///(:8080/webpack)-dev-server/client?:6:19)
    at eval (webpack:///(:8080/webpack)-dev-server/client?:299:30)
    at ./node_modules/webpack-dev-server/client/index.js?http://localhost:8080 (bundle.js:7798:1)
    at __webpack_require__ (bundle.js:703:30)
    at fn (bundle.js:77:20)
    at eval (webpack:///multi_(:8080/webpack)-dev-server/client?:1:1)

yarn start

yarn run v1.22.19
cross-env NODE_ENV=development electron .

process.env.NODE_ENV: development
Done in 72.06s.

คอนโซล :

bundle.js:1 Failed to load resource: net::ERR_CONNECTION_REFUSED
.\node_modules\electron\dist\resources\electron.asar\renderer\security-warnings.js:170 Electron Security Warning (Insecure Content-Security-Policy) This renderer process has either no Content Security
    Policy set or a policy with "unsafe-eval" enabled. This exposes users of
    this app to unnecessary security risks.
 
For more information and help, consult
https://electronjs.org/docs/tutorial/security.
 This warning will not show up
once the app is packaged.

โหนด

nvm list

    16.10.0
    14.21.3
    14.17.0
    12.4.0
  * 10.15.3 (Currently using 64-bit executable)
    10.8.0
    10.3.0
    9.11.2
    8.9.4

แก้ไข:

ฉันใช้ node 10.15.3 เพราะมันคือเวอร์ชันที่ chatgpt แนะนำให้ฉันตามรายการ dependencies .. และไฟล์ readme ระบุให้ใช้ node > 8 แต่ฉันไม่รู้ว่าควรใช้ตัวไหน หรือควรอัปเดต dependency ตัวไหนก่อนดี ฉันควรเริ่มจาก electron แล้วตามด้วย webpack & typescript หรืออาจจะเริ่มจาก dependency ที่มีคำเตือนเช่น fluent-ffmpeg, chokidar & fsevents ดี?

นอกจากนี้มีแหล่งอ้างอิงกลางเกี่ยวกับความเข้ากันได้ของการพึ่งพา JavaScript หรือไม่? หรือมีเครื่องมือใดที่จะช่วยฉันระบุความขัดแย้งและแก้ไขได้บ้าง?

แก้ไข 2:

ฉันไม่สามารถดึงเวอร์ชันของ Node จาก renderer.js โดยใช้ electron 5 & node 12.18 ได้ และตัวอย่างนั้นเป็นสำหรับ electron 24

yarn dev (คอนโซล)

renderer.js:2 Uncaught ReferenceError: versions is not defined

yarn start (คอนโซล)

.\node_modules\electron\dist\resources\electron.asar\renderer\init.js:177 Unable to load preload script: .\preload.js
(anonymous) @ .\node_modules\electron\dist\resources\electron.asar\renderer\init.js:177

.\node_modules\electron\dist\resources\electron.asar\renderer\init.js:178 TypeError: Cannot read property 'exposeInMainWorld' of undefined
(anonymous) @ .\node_modules\electron\dist\resources\electron.asar\renderer\init.js:178

renderer.js:2 Uncaught ReferenceError: versions is not defined
    at renderer.js:2

แก้ไข 3:

ฉันได้ทำความคืบหน้าบ้างแล้ว หลังจากอัปเดต electron เป็น v6 ฉันได้รับข้อผิดพลาดดังต่อไปนี้: Error: contextBridge API สามารถใช้ได้ก็ต่อเมื่อเปิดใช้งาน contextIsolation

ฉันพยายามเปิดใช้งานการแยกบริบทในหน้าต่างอีกครั้ง: contextIsolation: true, จากนั้นฉันก็ได้ผลลัพธ์ (เกือบ) ตามที่ต้องการ: แอปนี้ใช้ Chrome (v76.0.3809.146), Node.js (v12.4.0), และ Electron (v6.1.12) แต่ฉันใช้ Node v12.18 ตามที่เอกสารการปล่อยของ Electron แนะนำ

แล้วฉันพยายามโหลดชุดแอปกลับเข้าไปใน index.html อีกครั้ง โดยอ้างอิงที่ :

  • ./dist/bundle.js
  • http://localhost:8080/bundle.js

แต่ฉันก็ยังได้รับข้อผิดพลาดเดิม :

yarn start : bundle.js:1 ไม่สามารถโหลดทรัพยากรได้: net::ERR_CONNECTION_REFUSED

yarn dev : เกิดข้อผิดพลาด ReferenceError: require ไม่ถูกนิยาม

เป็นเพราะว่าฉันต้องย้ายและเปิดเผย IpcHandlers ทั้งหมดและไฟล์ทั้งหมดภายใต้ src/common/ ในไฟล์ preload.js โดยใช้ contextBridge และ ipcRenderer เหมือนกับ:

contextBridge.exposeInMainWorld('Constants', {
    IpcEvents: () => ipcRenderer.invoke('IpcEvents'),
    ping: () => ipcRenderer.invoke('ping')
})

หรือนี่เป็นปัญหาที่แตกต่างไปเลย เช่น เส้นทางบางส่วนหายไปหรือปัญหาเกี่ยวกับการตั้งค่า webpack ?

ฉันได้ทดสอบการเพิ่มตัวจัดการ ping ใน main.js แต่จากนั้นฉันก็ได้รับข้อผิดพลาด ipcMain.handle ไม่ใช่ฟังก์ชัน ฉันได้อ่านเกี่ยวกับรูปแบบ IPC แต่ก็มีมากจนเข้าใจทั้งหมดพร้อมกันได้ยาก โดยเฉพาะกับวิธีที่มันถูกทำในแอปนั้น..

นอกจากนี้ electron v6 การใช้ require() ของ node builtins ใน sandboxed renderers จะไม่โหลด remote เวอร์ชันโดยอัตโนมัติอีกต่อไป ฉันควรแทนที่ require ทั้งหมดด้วย require('electron').remote.require ในไฟล์ js และ ts/x หรือเฉพาะฝั่งลูกข่ายเท่านั้น ?

คำตอบ #1

เรามาไปทีละประเด็นกันเถอะ:

ฉันไม่สามารถหาคำตอบได้ว่าจะใช้เวอร์ชันของ Node ไหน และก็ไม่แน่ใจว่าจะต้องอัปเดตส่วนใดของการตั้งค่า/การพึ่งพา

คุณกำลังใช้ Electron 4 ซึ่งมาพร้อมกับ Node v10.11 ดังนั้นคุณสามารถใช้ Node 10 ในระหว่างนี้ได้

หากคุณต้องการอัปเกรดเป็นเวอร์ชัน Electron ที่ได้รับการสนับสนุนในปัจจุบัน (ตามที่คุณควรทำ) ลองดูที่ตารางเวอร์ชันที่ปล่อยออกมา การอัปเกรดเป็นเวอร์ชันล่าสุดจะต้องใช้ Node LTS เวอร์ชันล่าสุดด้วย (18 ณ เวลาที่เขียน) และขั้นตอนต่อไปของคุณควรนำไปสู่การเปลี่ยนแปลงที่ไม่เข้ากัน เพื่อให้คุณสามารถปรับตัวกับสิ่งที่เกี่ยวข้องและดำเนินการต่อจากนั้น

หนึ่งในเรื่องที่เกี่ยวข้องกับคุณคือ ตั้งแต่ Electron 5 เป็นต้นมา การใช้ Node API หรือการสื่อสารกับกระบวนการหลักในกระบวนการแสดงผลโดยตรงนั้นเป็นสิ่งที่ไม่แนะนำอย่างยิ่ง และควรใช้ contextBridge แทน

ซึ่งแน่นอนว่าจะต้องมีการปรับโครงสร้างโค้ดของคุณครั้งใหญ่ ดังนั้นคุณสามารถทำให้มันใช้งานได้ในช่วงเวลานี้ผ่าน:

 webPreferences: {
   nodeIntegration: true,
   contextIsolation: false
 }

ซึ่งเปิดเผย API ของ Node ให้กับกระบวนการเรนเดอเรอร์ และไม่ได้แยกมันออกจากบริบทของมาสเตอร์

yarn dev & Uncaught ReferenceError: require ยังไม่ได้กำหนด

เนื่องจากโค้ดฝั่งลูกค้าของคุณใช้ API ของทั้ง Electron และ Node อย่างหนัก มันจึงไม่สามารถรันในเบราว์เซอร์ได้ ซึ่งเป็นกรณีเมื่อคุณใช้ yarn dev แล้วไปที่ localhost:8080 เบราว์เซอร์ไม่สามารถเข้าถึง Node API เช่น require() และทำให้เกิดข้อผิดพลาดตามที่กล่าวมาข้างต้น

นั่นคือเหตุผลที่การรัน yarn start ทำงานได้ (พอสมควร) ดี เพราะมันจะเริ่มต้น electron ซึ่งขอบคุณการตั้งค่าข้างต้นที่เปิดเผย API ของ Node ให้กับตัว renderer (ด้านฝั่งลูกค้า)

ถ้าคุณทำการรีแฟกเตอร์และใช้ contextBridge เช่น ทำความสะอาดโค้ดฝั่งไคลเอนต์ของคุณจากการอ้างอิงทั้งหมดของ electron และ Node คุณจะอยู่ในสภาพที่ดีที่สุดในการรันโค้ดฝั่งไคลเอนต์ในเบราว์เซอร์ (พร้อมกับการจำลอง API บางส่วน)

ฉันควรเริ่มต้นด้วย Electron แล้วค่อย Webpack และ TypeScript หรือว่าควรดูที่การพึ่งพาที่มีคำเตือนอย่าง Fluent-ffmpeg, Chokidar และ fsevents ดี

ฉันจะไม่สนใจคำเตือน เพราะมีโอกาสมากที่มันจะหายไปเมื่อคุณอัปเกรดอิเล็กตรอน

การอัปเกรด TypeScript ขึ้นอยู่กับคุณจริง ๆ ว่าคุณต้องการใช้ประโยชน์จากฟีเจอร์ใหม่ที่มันมีให้หรือไม่ และมันเป็นเรื่องทางเลือกทั้งหมด

คุณก็ไม่จำเป็นต้องอัปเกรด Webpack ด้วยเช่นกัน (คุณมีเวอร์ชัน 3 ตอนนี้ - เก่าแต่ใช้งานได้) แต่คุณอาจพบว่าง่ายกว่าถ้าใช้บางสิ่งที่ทันสมัยกว่าในอนาคต ไม่ว่าจะเป็นเวอร์ชันที่สูงขึ้นหรือบางอย่างที่เร็วกว่าอย่าง Vite แต่ไม่ใช่ข้อกำหนด

นอกจากนี้มีแหล่งอ้างอิงแบบรวมศูนย์สำหรับความเข้ากันได้ของการพึ่งพา JavaScript ไหม?

เฉพาะตามที่ผู้เขียนไลบรารีระบุเท่านั้น ซึ่งจะถูกตรวจสอบโดยตัวจัดการแพ็กเกจเช่น NPM ในขณะติดตั้ง

คำตอบ #2

querystring เป็นโมดูลที่มีมาในตัวสำหรับ node.js คุณจำเป็นต้องตรวจสอบแพ็กเกจที่ขึ้นอยู่ของคุณ สำหรับเว็บให้พิจารณาใช้ query-string แทน

บทความที่เกี่ยวข้อง