ไคลเอ็นต์บนโหนด: Uncaught ReferenceError: require ไม่ได้ถูกกำหนดไว้


321

ดังนั้นฉันกำลังเขียนแอปพลิเคชันที่มีโหนด / express + jade combo

ฉันมีclient.jsซึ่งโหลดบนไคลเอนต์ ในไฟล์นั้นฉันมีรหัสที่เรียกใช้ฟังก์ชันจากไฟล์ JavaScript อื่น ๆ ความพยายามของฉันคือการใช้

var m = require('./messages');

เพื่อที่จะโหลดเนื้อหาของmessages.js(เช่นเดียวกับที่ฉันทำในฝั่งเซิร์ฟเวอร์) และต่อมาในฟังก์ชั่นการโทรจากไฟล์นั้น แต่ไม่ได้กำหนดไว้ในฝั่งไคลเอ็นต์และมันจะพ่นข้อผิดพลาดของแบบฟอร์มrequireUncaught ReferenceError: require is not defined

ไฟล์ JS อื่น ๆ เหล่านี้ยังโหลดในรันไทม์ที่ไคลเอนต์เพราะฉันวางลิงค์ที่ส่วนหัวของหน้าเว็บ ดังนั้นไคลเอนต์จึงรู้ถึงฟังก์ชั่นทั้งหมดที่ส่งออกจากไฟล์อื่นเหล่านี้

ฉันจะเรียกใช้ฟังก์ชันเหล่านี้จากไฟล์ JS อื่น ๆ เหล่านี้ (เช่นmessages.js) ในclient.jsไฟล์หลักที่เปิดซ็อกเก็ตไปยังเซิร์ฟเวอร์ได้อย่างไร


4
ทำไมคุณไม่<script src="messages.js"></script>โทรหาพวกเขาหลังจากนั้น?
Sterling Archer

1
บางทีนี่อาจเป็นวิธีแก้ปัญหา แต่มีอีกสิ่งหนึ่งที่เกี่ยวข้องกับฉัน ฉันยังมีไฟล์ชื่อ "Represent.js" สำหรับสรุปการแสดงที่เป็นเรื่องธรรมดาสำหรับลูกค้าและเซิร์ฟเวอร์ ในไฟล์นั้นฉันยังต้องมีคำสั่งและในฝั่งเซิร์ฟเวอร์ก็ควรจะเป็นเพราะฉันกำลังใช้โหนด อย่างไรก็ตามในด้านลูกค้านี่จะเป็นปัญหา คุณคิดอย่างไร?
MightyMouse

2
สำหรับมือใหม่อย่างฉัน (ที่ไม่สามารถสะกดคำว่า "npm" ได้ในสัปดาห์ที่ผ่านมา! :-) การเข้าใจ--requireตัวเลือกของเบราว์เซอร์จะทำให้เกิดrequire()การกำหนดทางฝั่งไคลเอ็นต์ ดู: lincolnloop.com/blog/speedy-browserifying-multiple-bundles
Hephaestus

2
@Sterling Archer ... หากมีไฟล์ดังกล่าว 100 ไฟล์ ... เราไม่สามารถโหลดต่อไปได้ใน HTML ใช่มั้ย .........
Baradwaj Aryasomayajula

คำตอบ:


436

นี่เป็นเพราะrequire()ไม่มีอยู่ในเบราว์เซอร์ / JavaScript ฝั่งไคลเอ็นต์

ตอนนี้คุณต้องเลือกเกี่ยวกับการจัดการสคริปต์ JavaScript ฝั่งไคลเอ็นต์ของคุณ

คุณมีสามตัวเลือก:

  1. ใช้<script>แท็ก
  2. ใช้CommonJSการดำเนินงาน การพึ่งพาแบบซิงโครนัสเช่น Node.js
  3. ใช้การติดตั้งAMD

การใช้งานฝั่งไคลเอ็นต์CommonJSรวมถึง:

(ส่วนใหญ่ต้องการขั้นตอนการสร้างก่อนที่คุณจะปรับใช้)

  1. Browserify - คุณสามารถใช้โมดูล Node.js ส่วนใหญ่ในเบราว์เซอร์ นี่คือรายการโปรดส่วนตัวของฉัน
  2. Webpack - ทำทุกอย่าง (รวม JS, CSS และอื่น ๆ ) ได้รับความนิยมจากกระแส React.js ฉาวโฉ่สำหรับโค้งการเรียนรู้ที่ยากลำบาก
  3. Rollup - คู่แข่งใหม่ ยกระดับโมดูล ES6 รวมถึงความสามารถในการเขย่าต้นไม้ (ลบรหัสที่ไม่ได้ใช้)

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการเปรียบเทียบของฉันBrowserify VS (เลิก) ตัวแทน

การใช้งานของAMDรวมถึง:

  1. RequireJS - เป็นที่นิยมมากในหมู่นักพัฒนา JavaScript ฝั่งไคลเอ็นต์ ไม่ใช่ความชอบของฉันเพราะธรรมชาติแบบอะซิงโครนัส

หมายเหตุในการเลือกที่หนึ่งที่จะไปกับการค้นหาของคุณคุณจะอ่านเกี่ยวกับซุ้ม Bower ใช้สำหรับการขึ้นต่อแพ็กเกจเท่านั้นและไม่ได้ถูกกำหนดในข้อกำหนดโมดูลเช่น CommonJS และ AMD

หวังว่านี่จะช่วยได้บ้าง


1
ขอบคุณมาก. ฉันทำการทดสอบแบบแยกกันนี่คือเหตุผลว่าทำไมจึงใช้เวลาสักครู่หนึ่งในการตอบสนอง ฉันอาจกลับมาพร้อมคำถามในเวลาไม่กี่นาทีเพื่อให้แน่ใจว่าฉันเข้าใจว่าเวทมนต์นี้ทำงานอย่างไร ฉันแค่ต้องการรวมทุกอย่างเข้าด้วยกัน ขอบคุณอีกครั้ง. Browserify ดูเหมือนจะสั่นคลอน! :)
MightyMouse

6
ฉันคิดว่าควรเพิ่ม JSPM ในรายการ
Martijn

19
ฉันขอตัวอย่างของการใช้<script>แท็กเพื่ออิมพอร์ตคลาส React โดยไม่ใช้ node manager แพ็คเกจหรือไม่?
Louie Bertoncin

2
SystemJS และ JSPM มีการละเว้นที่โดดเด่นมาก
Aluan Haddad

4
ใช่. ตอนนี้เลิกใช้ส่วนประกอบแล้วgithub.com/componentjs/component
i_emmanuel

43

ฉันมาจากสภาพแวดล้อมของอิเล็กตรอนที่ฉันต้องการการสื่อสาร IPC ระหว่างกระบวนการตัวแสดงภาพและกระบวนการหลัก กระบวนการ renderer อยู่ในไฟล์ HTML ระหว่างแท็กสคริปต์และสร้างข้อผิดพลาดเดียวกัน เส้น

const {ipcRenderer} = require('electron')

โยนUncaught ReferenceError: require ไม่ได้ถูกกำหนดไว้

ฉันสามารถแก้ไขได้โดยระบุการรวมโหนดเป็นจริงเมื่อหน้าต่างเบราว์เซอร์ (ที่ไฟล์ HTML นี้ฝัง) ถูกสร้างขึ้นในขั้นตอนหลัก

function createAddItemWindow() {
//Create new window
addItemWindown = new BrowserWindow({
    width: 300,
    height: 200,
    title: 'Add Item',

    //The lines below solved the issue
    webPreferences: {
        nodeIntegration: true
    }
})}

นั่นแก้ไขปัญหาสำหรับฉัน วิธีการแก้ปัญหาที่ถูกเสนอที่นี่ ความหวังนี้ช่วยคนอื่น ไชโย


ขอบคุณมาก. ฉันเดาว่าฉันมาจากวิดีโอแอป Shopping List เดียวกันจาก YouTube hahaha
Luiscri

ยอดเยี่ยม - ยินดีที่ได้พบคำตอบเช่นนี้แทนการพึ่งสตาร์ตเตอร์เพื่อรวบรวมทั้งหมดไว้ให้คุณ
GhostBytes

คำตอบที่ยอดเยี่ยมสำหรับผู้ใช้อิเล็กตรอน!
thoni56

น่าอัศจรรย์ ทำงานได้ดีสำหรับฉัน นอกจากนี้ฉันยังมาจากวิดีโอแอป Shopping List ด้วย o /
adahox_

26

ES6:ใน html รวมไฟล์ js หลักโดยใช้คุณลักษณะtype="module"( การสนับสนุนเบราว์เซอร์ ):

<script type="module" src="script.js"></script>

และในscript.jsไฟล์รวมถึงไฟล์อื่นเช่น:

import { hello } from './module.js';
...
// alert(hello());

ไฟล์ที่อยู่ข้างใน ( module.js) คุณต้องส่งออกฟังก์ชั่น / คลาสที่คุณจะนำเข้า

export function hello() {
    return "Hello World";
}

การทำงานตัวอย่างเช่นที่นี่


1
@Curse ที่นี่stackoverflow.com/a/44591205/860099ถูกเขียน "โมดูลสร้างขอบเขตเพื่อหลีกเลี่ยงการชนชื่อ" SOU คุณสามารถ "ด้วยตนเอง" ใส่ ไปยังวัตถุที่หน้าต่างval window.val = valนี่คือเสียงแตก: เสียงแตก: plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - วิธีนี้ใช้งานได้
Kamil Kiełczewski

1

ในกรณีของฉันฉันใช้วิธีอื่น

เนื่องจากโครงการไม่ต้องการ CommonJs และจะต้องมีความเข้ากันได้กับ ES3 (โมดูลที่ไม่รองรับ) สิ่งที่คุณต้องการเพียงแค่ลบคำสั่งส่งออกและนำเข้าทั้งหมดออกจากรหัสของคุณเนื่องจากtsconfigของคุณไม่มี

"module": "commonjs"

แต่ใช้คำสั่งนำเข้าและส่งออกในไฟล์อ้างอิงของคุณ

import { Utils } from "./utils"
export interface Actions {}

รหัสสุดท้ายที่สร้างขึ้นจะมี (อย่างน้อยสำหรับ typescript 3.0) บรรทัดดังกล่าว

"use strict";
exports.__esModule = true;
var utils_1 = require("./utils");
....
utils_1.Utils.doSomething();

1

แม้การใช้สิ่งนี้จะไม่ได้ผลฉันคิดว่าทางออกที่ดีที่สุดคือเบราเซอร์

module.exports = {
  func1: function () {
   console.log("I am function 1");
  },
  func2: function () {
    console.log("I am function 2");
  }
};

-getFunc1.js-
var common = require('./common');
common.func1();

0

สิ่งนี้ได้ผลสำหรับฉัน

  1. บันทึกไฟล์นี้https://requirejs.org/docs/release/2.3.5/minified/require.js
  2. โหลดลงใน HTML ของคุณเช่นนี้
    <script data-main="your-Scrpt.js" src="require.js"></script>
    !
    ใช้: -> ต้องการ (['moudle-name']) ใน "your-script.js"
    ไม่ต้องการ ('moudle-name')
    const {ipcRenderer} = ต้องการ (['อิเล็กตรอน'])
    ไม่: const {ipcRenderer} = ต้องการ ('อิเล็กตรอน')

3
ไม่เคยแนะนำ "คลิกที่นี่" ตลอดไป กรณีที่ดีที่สุดก็คือ RickRoll แต่เราไม่รู้ว่าอะไรกำลังรอเราอยู่ที่ส่วนท้ายของลิงก์
ggdx
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.