Client on node: Uncaught ReferenceError: need tidak didefinisikan

322

Jadi, saya menulis aplikasi dengan node / express + jade combo.

Saya punya client.js, yang dimuat pada klien. Dalam file itu saya memiliki kode yang memanggil fungsi dari file JavaScript lainnya. Upaya saya adalah menggunakan

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

untuk memuat konten messages.js(seperti yang saya lakukan di sisi server) dan kemudian pada fungsi panggilan dari file itu. Namun, requiretidak didefinisikan di sisi klien, dan itu melempar kesalahan formulir Uncaught ReferenceError: require is not defined.

File-file JS lainnya juga dimuat saat runtime di klien karena saya menempatkan tautan di header halaman web. Jadi klien mengetahui semua fungsi yang diekspor dari file-file lain ini.

Bagaimana cara saya memanggil fungsi-fungsi ini dari file JS lainnya (seperti messages.js) di client.jsfile utama yang membuka soket ke server?

MightyMouse
sumber
4
Mengapa Anda tidak hanya <script src="messages.js"></script>menelepon mereka setelah itu?
Sterling Archer
1
Mungkin ini bisa menjadi solusi, tetapi ada hal lain yang menjadi perhatian saya. Saya juga memiliki file yang disebut "representative.js" untuk abstrak representasi yang umum untuk klien dan server. Dalam file itu saya juga memerlukan pernyataan dan di sisi server itu harus ok karena saya menjalankan node. Namun, di sisi klien ini akan menjadi masalah. Bagaimana menurut anda?
MightyMouse
2
Untuk pemula seperti saya (yang bahkan tidak bisa mengeja "npm" seminggu yang lalu! :-), mungkin akan membantu untuk memahami bahwa --requireopsi peramban menyebabkan require()ditentukan pada sisi klien. Lihat: lincolnloop.com/blog/speedy-browserifying-multiple-bundles
Hephaestus
2
@Sterling Archer ... Jika ada 100 file seperti itu ... kita tidak dapat terus memuatnya, dalam HTML kanan .........
Baradwaj Aryasomayajula

Jawaban:

436

Ini karena require()tidak ada di browser / sisi klien JavaScript.

Sekarang Anda harus membuat beberapa pilihan tentang manajemen skrip JavaScript sisi klien Anda.

Anda memiliki tiga opsi:

  1. Gunakan <script>tag.
  2. Gunakan implementasi CommonJS . Ketergantungan sinkron seperti Node.js
  3. Gunakan implementasi AMD .

Implementasi sisi klien CommonJS meliputi:

(kebanyakan dari mereka memerlukan langkah pembangunan sebelum Anda menyebarkan)

  1. Browserify - Anda dapat menggunakan sebagian besar modul Node.js di browser. Ini adalah favorit pribadi saya.
  2. Webpack - Melakukan segalanya (bundel JS, CSS, dll). Dipopulerkan oleh gelombang React.js. Terkenal karena kurva belajarnya yang sulit.
  3. Rollup - Pesaing baru. Memanfaatkan modul ES6. Termasuk kemampuan mengguncang pohon (menghapus kode yang tidak digunakan).

Anda dapat membaca lebih lanjut tentang perbandingan Komponen Browserify vs (usang) saya .

Implementasi AMD meliputi:

  1. RequireJS - Sangat populer di kalangan pengembang JavaScript sisi klien. Bukan seleraku karena sifatnya yang tidak sinkron.

Catatan, dalam pencarian Anda untuk memilih yang mana untuk pergi, Anda akan membaca tentang Bower . Bower hanya untuk dependensi paket dan tidak terbuka tentang definisi modul seperti CommonJS dan AMD.

Semoga ini bisa membantu.

JP Richardson
sumber
1
Terima kasih banyak. Saya membuat tes mini secara terpisah, inilah mengapa saya butuh waktu untuk merespons. Saya mungkin kembali dengan beberapa pertanyaan dalam beberapa menit hanya untuk memastikan bahwa saya mengerti bagaimana sihir ini bekerja. Saya hanya ingin menyatukan semuanya. Terima kasih lagi. Browserify tampaknya mengguncang! :)
MightyMouse
6
Saya pikir JSPM harus ditambahkan ke daftar.
Martijn
19
Bisakah saya mendapatkan contoh menggunakan <script>tag untuk mengimpor kelas Bereaksi tanpa menggunakan manajer paket nodeJs?
Louie Bertoncin
2
SystemJS dan JSPM adalah kelalaian yang sangat terkenal.
Aluan Haddad
4
Ya. Komponen sekarang sudah usang github.com/componentjs/component
i_emmanuel
43

Saya berasal dari lingkungan elektron, di mana saya membutuhkan komunikasi IPC antara proses renderer dan proses utama. Proses renderer duduk di file HTML antara tag skrip dan menghasilkan kesalahan yang sama. Garis

const {ipcRenderer} = require('electron')

melempar UnEught ReferenceError: memerlukan tidak didefinisikan

Saya dapat mengatasinya dengan menetapkan integrasi simpul sebagai benar ketika jendela browser (tempat file HTML ini disematkan) pada awalnya dibuat dalam proses utama.

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

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

Itu memecahkan masalah bagi saya. Solusinya diusulkan di sini . Semoga ini bisa membantu orang lain. Bersulang.

Kibonge Murphy
sumber
Terima kasih banyak. Saya kira saya berasal dari video aplikasi Daftar Belanja yang sama dari YouTube hahaha
Luiscri
Cemerlang - senang menemukan jawaban seperti ini alih-alih mengandalkan permulaan untuk secara ajaib menyatukan semuanya untuk Anda.
GhostBytes
Jawaban sempurna untuk pengguna Electron!
thoni56
luar biasa. bekerja cukup baik untuk saya. juga, saya berasal dari video aplikasi Daftar Belanja juga o /
adahox_
26

ES6: Dalam html sertakan file js utama menggunakan atribut type="module"( dukungan browser ):

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

Dan dalam script.jsfile termasuk file lain seperti itu:

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

Di dalam file yang disertakan ( module.js) Anda harus mengekspor fungsi / kelas yang akan Anda impor

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

Contoh kerja di sini .

Kamil Kiełczewski
sumber
1
@Curse Here stackoverflow.com/a/44591205/860099 ditulis "Modul menciptakan ruang lingkup untuk menghindari tabrakan nama." Anda dapat "secara manual" meletakkan valobjek jendela window.val = val. Inilah plunker: Plunker: plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - solusi ini berfungsi
Kamil Kiełczewski
1

Dalam kasus saya, saya menggunakan solusi lain.

Karena proyek tidak memerlukan CommonJs dan itu harus memiliki kompatibilitas ES3 (modul tidak didukung) yang Anda butuhkan hanyalah menghapus semua pernyataan ekspor dan impor dari kode Anda , karena tsconfig Anda tidak mengandung

"module": "commonjs"

Tetapi gunakan pernyataan impor dan ekspor dalam file referensi Anda

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

Kode akhir yang dihasilkan akan selalu memiliki (setidaknya untuk naskah skrip 3.0)

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

Meskipun menggunakan ini tidak akan berfungsi, saya pikir solusi terbaik adalah browserify:

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();
Wael Chorfan
sumber
0

Ini Berhasil Bagi Saya

  1. simpan file ini https://requirejs.org/docs/release/2.3.5/minified/require.js
  2. muat ke HTML Anda seperti
    <script data-main="your-Scrpt.js" src="require.js"></script>
    Catatan ini !
    gunakan: -> memerlukan (['moudle-name']) di "your-script.js"
    tidak memerlukan ('nama moudle')
    const {ipcRenderer} = membutuhkan (['elektron'])
    Tidak: const {ipcRenderer} = butuhkan ('elektron')
enak
sumber
3
Jangan pernah merekomendasikan "klik di sini", selamanya. Kasus terbaik, ini adalah RickRoll, tetapi kami tidak tahu apa pun yang menunggu kami di akhir tautan itu.
ggdx