Máy khách trên nút: Uncaught ReferenceError: Yêu cầu không được xác định


322

Vì vậy, tôi đang viết một ứng dụng với combo nút / express + jade.

Tôi có client.js, được tải trên máy khách. Trong tệp đó tôi có mã gọi các hàm từ các tệp JavaScript khác. Nỗ lực của tôi là sử dụng

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

để tải nội dung của messages.js(giống như tôi làm ở phía máy chủ) và sau đó là các chức năng gọi từ tệp đó. Tuy nhiên, requirekhông được xác định ở phía máy khách và nó sẽ xuất hiện lỗi của biểu mẫu Uncaught ReferenceError: require is not defined.

Các tệp JS khác cũng được tải trong thời gian chạy tại máy khách vì tôi đặt các liên kết ở phần đầu của trang web. Vì vậy, khách hàng biết tất cả các chức năng được xuất từ ​​các tệp khác.

Làm cách nào để tôi gọi các hàm này từ các tệp JS khác (chẳng hạn như messages.js) trong client.jstệp chính mở ổ cắm cho máy chủ?


4
Tại sao bạn không chỉ <script src="messages.js"></script>và gọi cho họ sau đó?
Sterling Archer

1
Có lẽ đây có thể là một giải pháp, nhưng có một điều khác liên quan đến tôi. Tôi cũng có một tệp gọi là "đại diện.js" để trừu tượng hóa đại diện phổ biến cho máy khách và máy chủ. Trong tập tin đó tôi cũng có yêu cầu và về phía máy chủ, nó sẽ ổn vì tôi đang chạy nút. Tuy nhiên, về phía khách hàng đây sẽ là một vấn đề. Bạn nghĩ sao?
MightyMouse

2
Đối với những người mới như tôi (người thậm chí không thể đánh vần "npm" một tuần trước! :-), có thể hữu ích để hiểu rằng --requiretùy chọn trình duyệt gây ra require()được xác định ở phía máy khách. Xem: lincolnloop.com/blog/speedy-browserifying-multipl-bundles
Hephaestus

2
@Sterling Archer ... Nếu có 100 tệp như vậy ... chúng ta không thể tiếp tục tải, bằng HTML ngay .........
Baradwaj Aryasomayajula

Câu trả lời:


436

Điều này là do require()không tồn tại trong JavaScript phía trình duyệt / máy khách.

Bây giờ bạn sẽ phải thực hiện một số lựa chọn về quản lý tập lệnh JavaScript phía máy khách của mình.

Bạn có ba lựa chọn:

  1. Sử dụng <script>thẻ.
  2. Sử dụng triển khai CommonJS . Các phụ thuộc đồng bộ như Node.js
  3. Sử dụng triển khai AMD .

Triển khai phía máy khách CommonJS bao gồm:

(hầu hết trong số họ yêu cầu một bước xây dựng trước khi bạn triển khai)

  1. Browserify - Bạn có thể sử dụng hầu hết các mô-đun Node.js trong trình duyệt. Đây là yêu thích cá nhân của tôi.
  2. Webpack - Thực hiện mọi thứ (gói JS, CSS, v.v.). Được phổ biến bởi sự đột biến của React.js. Nổi tiếng với đường cong học tập khó khăn của nó.
  3. Rollup - Ứng cử viên mới. Tận dụng các mô-đun ES6. Bao gồm các khả năng rung cây (loại bỏ mã không sử dụng).

Bạn có thể đọc thêm về so sánh của tôi về Thành phần Browserify so với (không dùng nữa) .

Triển khai AMD bao gồm:

  1. RequireJS - Rất phổ biến trong số các nhà phát triển JavaScript phía máy khách. Không phải sở thích của tôi vì bản chất không đồng bộ của nó.

Lưu ý, trong tìm kiếm của bạn để chọn cái nào sẽ đi cùng, bạn sẽ đọc về Bower . Bower chỉ dành cho các phụ thuộc gói và không được chú ý đến các định nghĩa mô-đun như CommonJS và AMD.

Hy vọng điều này sẽ giúp một số.


1
Cảm ơn rât nhiều. Tôi đã thực hiện một thử nghiệm nhỏ riêng biệt, đây là lý do tại sao tôi phải mất một thời gian để trả lời. Tôi có thể quay lại với một số câu hỏi trong vài phút chỉ để đảm bảo rằng tôi hiểu cách thức hoạt động của phép thuật này. Tôi chỉ muốn đặt mọi thứ lại với nhau. Cảm ơn một lần nữa. Browserify dường như đá! :)
MightyMouse

6
Tôi nghĩ rằng nên thêm JSPM vào danh sách.
Martijn

19
Tôi có thể lấy ví dụ về việc sử dụng <script>thẻ để nhập lớp React mà không cần sử dụng trình quản lý gói nodeJs không?
Louie Bertoncin

2
SystemJS và JSPM là những thiếu sót rất đáng chú ý.
Aluan Haddad

4
Vâng. Thành phần hiện không được chấp nhận github.com/componentjs/component
i_emmanuel

43

Tôi đến từ môi trường điện tử, nơi tôi cần giao tiếp IPC giữa quy trình kết xuất và quy trình chính. Quá trình kết xuất nằm trong một tệp HTML giữa các thẻ script và tạo ra cùng một lỗi. Dòng

const {ipcRenderer} = require('electron')

ném tham chiếu UncaughtError: yêu cầu không được xác định

Tôi đã có thể giải quyết vấn đề đó bằng cách chỉ định tích hợp nút là đúng khi cửa sổ trình duyệt (nơi tệp HTML này được nhúng) ban đầu được tạo trong quy trình chính.

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

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

Điều đó đã giải quyết vấn đề cho tôi. Giải pháp đã được đề xuất ở đây . Hy vọng điều này sẽ giúp người khác. Chúc mừng.


Cảm ơn rât nhiều. Tôi đoán tôi đến từ cùng một video ứng dụng Danh sách mua sắm từ YouTube hahaha
Luiscri

Rực rỡ - thật tuyệt khi tìm thấy câu trả lời như thế này thay vì dựa vào người mới bắt đầu để kết hợp tất cả với bạn một cách kỳ diệu.
GhostBytes

Câu trả lời tuyệt vời cho người dùng Electron!
thoni56

kinh ngạc. hoạt động khá tốt với tôi. Ngoài ra, tôi đến từ video ứng dụng Danh sách mua sắm quá o /
adahox_

26

ES6: Trong html bao gồm tệp js chính bằng thuộc tính type="module"( hỗ trợ trình duyệt ):

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

Và trong script.jstệp bao gồm một tệp khác như thế:

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

Bên trong tệp được bao gồm ( module.js) bạn phải xuất hàm / lớp mà bạn sẽ nhập

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

Ví dụ làm việc ở đây .


1
@Curse Tại đây stackoverflow.com/a/44591205/860099 được viết "Mô-đun tạo phạm vi để tránh va chạm tên." sou bạn có thể "thủ công" đưa valvào đối tượng cửa sổ window.val = val. Đây là plunker: Plunker: plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - giải pháp này hoạt động
Kamil Kiełczewski

1

Trong trường hợp của tôi, tôi đã sử dụng một giải pháp khác.

Vì dự án không yêu cầu CommonJ và nó phải có khả năng tương thích ES3 (các mô-đun không được hỗ trợ), tất cả những gì bạn cần chỉ là xóa tất cả các câu lệnh xuấtnhập khỏi mã của bạn , vì tsconfig của bạn không chứa

"module": "commonjs"

Nhưng sử dụng báo cáo nhập và xuất trong tệp được tham chiếu của bạn

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

Mã được tạo cuối cùng sẽ luôn có (ít nhất là cho bản thảo 3.0) các dòng như vậy

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

1

Ngay cả khi sử dụng điều này sẽ không hoạt động, tôi nghĩ giải pháp tốt nhất là 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();

0

Điều này làm việc cho tôi

  1. lưu tệp này https://requirejs.org/docs/release/2.3.5/minified/require.js
  2. tải vào HTML của bạn như thế này
    <script data-main="your-Scrpt.js" src="require.js"></script>
    Lưu ý!
    sử dụng: -> yêu cầu (['moudle-name']) trong "your-script.js"
    không yêu cầu ('moudle-name')
    const {ipcRenderer} = Yêu cầu (['electron'])
    Không phải: const {ipcRenderer} = Yêu cầu ('electron')

3
Không bao giờ, bao giờ đề nghị một "bấm vào đây", bao giờ. Trường hợp tốt nhất, đó là một RickRoll, nhưng chúng tôi không biết bất cứ điều gì đang chờ đợi chúng tôi ở cuối liên kết đó.
ggdx
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.