Клієнт у вузлі: Uncaught ReferenceError: вимагати не визначено


320

Отже, я пишу заявку за допомогою комбінації вузла / express + нефрит.

У мене є client.js, що завантажується на клієнта. У цьому файлі я маю код, який викликає функції з інших файлів JavaScript. Моя спроба полягала у використанні

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

для того, щоб завантажити вміст messages.js(так само, як я роблю на стороні сервера), а потім і функції виклику з цього файлу. Однак, requireне визначено на стороні клієнта, і це кидає помилку форми Uncaught ReferenceError: require is not defined.

Ці інші JS-файли також завантажуються під час виконання клієнта, оскільки я розміщую посилання в заголовку веб-сторінки. Таким чином, клієнт знає всі функції, які експортуються з цих інших файлів.

Як мені викликати ці функції з цих інших файлів JS (таких як messages.js) у головному client.jsфайлі, що відкриває сокет на сервері?


4
Чому б ти просто не <script src="messages.js"></script>подзвонив їм після цього?
Стерлінг Арчер

1
Можливо, це може бути рішенням, але є ще одна річ, яка мене стосується. У мене також є файл під назвою "Reprezenta.js" для абстрагування представництва, спільного для клієнта та сервера. У цьому файлі у мене також є заяви заяви і на стороні сервера це повинно бути нормально, оскільки я запускаю вузол. Однак з боку клієнта це буде проблемою. Як ти гадаєш?
MightyMouse

2
Для новачків, таких як я (які тиждень тому навіть не могли написати «npm»!) :-), може бути корисним зрозуміти, що --requireпараметр браузера require()визначає на стороні клієнта. Дивіться: lincolnloop.com/blog/speedy-browserifying-multiple-bundles
Гефест

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. Вебпак - робить все (в комплекті JS, CSS тощо). Популярний завдяки сплеску React.js. Відомий своєю важкою кривою навчання.
  3. Збірник - новий претендент. Використовує модулі ES6. Включає здібності струшування дерева (видаляє невикористаний код).

Ви можете прочитати більше про моє порівняння компонента Browrify vs (застарілого) .

Реалізація AMD включає:

  1. RequireJS - Дуже популярний серед розробників JavaScript на стороні клієнта. Не мій смак через його асинхронність.

Зауважте, у вашому пошуку вибору, з ким іти, ви прочитаєте про Bower . Bower призначений лише для залежностей від пакета і не підтримує визначення модулів, такі як CommonJS та AMD.

Сподіваюся, що це допомагає деяким.


1
Дуже дякую. Я зробив міні-тест окремо, тому мені знадобився певний час. Я можу за кілька хвилин повернутися з деякими питаннями, щоб переконатися, що я зрозумів, як ця магія спрацювала. Я просто хочу все скласти разом. Знову дякую. Browrify, здається, гойдається! :)
MightyMouse

6
Я думаю, що JSPM слід додати до списку.
Martijn

19
Чи можу я отримати приклад використання <script>тегу для імпорту класу React без використання менеджера пакунків nodeJs?
Луї Бертонцин

2
SystemJS та JSPM - це дуже помітні упущення.
Алуан Хаддад

4
Так. Компонент тепер застарілий github.com/componentjs/component
i_emmanuel

43

Я приходжу з електронного середовища, де мені потрібен IPC-зв’язок між процесом візуалізації та основним процесом. Процес візуалізації сидить у файлі HTML між тегами сценарію та створює ту саму помилку. Лінія

const {ipcRenderer} = require('electron')

кидає Uncaught ReferenceError: вимагати не визначено

Мені вдалося обійти це завдання, вказавши інтеграцію вузлів як істинну, коли вікно браузера (куди вбудований цей 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
    }
})}

Це вирішило для мене питання. Рішення було запропоновано тут . Сподіваємось, що це допомагає комусь іншому. Ура.


Дуже дякую. Я здогадуюсь того ж відео з програми YouTube для списку покупок від YouTube хахаха
Луїскрік

Блискуче - приємно знайти такі відповіді замість того, щоб покладатися на початківці, щоб магічно скласти все це за вас.
GhostBytes

Відмінна відповідь для користувачів Electron!
thoni56

дивовижний. працює досить добре для мене. також я
надходжу із

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 написано «Модуль створює простір для конфліктів імен уникнути.» Ви можете "вручну" поставити valоб'єкт вікна window.val = val. Ось планкер: Plunker: plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - це рішення працює
Kamil Kiełczewski

1

У моєму випадку я використовував інше рішення.

Оскільки проект не вимагає CommonJs, і він повинен мати сумісність ES3 (модулі не підтримуються), все, що вам потрібно, це просто видалити всі заяви про експорт та імпорт з вашого коду , оскільки ваш tsconfig не містить

"module": "commonjs"

Але використовуйте заяви про імпорт та експорт у файлах, на які посилаєтесь

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

Кінцево згенерований код завжди матиме (принаймні, для typecript 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')
    const {ipcRenderer} = вимагати (['електрон'])
    Не: const {ipcRenderer} = вимагати ('електрон')

3
Ніколи, ніколи не рекомендую "натиснути тут" ніколи. У кращому випадку це RickRoll, але ми не маємо уявлення, що б нас чекало наприкінці цього посилання.
ggdx
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.