Клієнт у вузлі: 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.