Клиент на узле: Uncaught ReferenceError: требование не определено

322

Итак, я пишу приложение с комбо узла / экспресс + Джейд.

У меня есть client.js, что загружается на клиенте. В этом файле у меня есть код, который вызывает функции из других файлов JavaScript. Моя попытка была использовать

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

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

Эти другие файлы JS также загружаются во время выполнения на клиенте, потому что я размещаю ссылки в заголовке веб-страницы. Таким образом, клиент знает все функции, которые экспортируются из этих других файлов.

Как я вызываю эти функции из этих других файлов JS (таких как messages.js) в главном client.jsфайле, который открывает сокет для сервера?

MightyMouse
источник
4
Почему бы тебе просто не <script src="messages.js"></script>позвонить им после этого?
Стерлинг Арчер
1
Возможно, это может быть решением, но есть еще одна вещь, которая касается меня. У меня также есть файл с именем "presentation.js" для абстрагирования представления, общего для клиента и сервера. В этом файле у меня также есть операторы require и на стороне сервера все должно быть в порядке, потому что я использую узел. Однако на стороне клиента это будет проблемой. Что вы думаете?
MightyMouse
2
Для таких новичков, как я (которые даже неделю назад не могли произнести «npm»! :-), может быть полезно понять, что --requireопция browserify require()требует определения на стороне клиента. Смотрите: lincolnloop.com/blog/speedy-browserifying-multiple-bundles
Гефест
2
@ Стерлинг Арчер ... Если есть 100 таких файлов ... мы не можем продолжать загружать, в HTML правильно .........
Барадвай Арясомаяджула

Ответы:

436

Это потому, require()что не существует в браузере / клиентском JavaScript.

Теперь вам нужно будет сделать выбор в отношении управления сценариями JavaScript на стороне клиента.

У вас есть три варианта:

  1. Используйте <script>тег.
  2. Используйте реализацию CommonJS . Синхронные зависимости, такие как Node.js
  3. Используйте реализацию AMD .

CommonJS клиентская реализация включает в себя:

(большинству из них требуется шаг сборки перед развертыванием)

  1. Browserify - вы можете использовать большинство модулей Node.js в браузере. Это мой личный фаворит.
  2. Webpack - делает все (связывает JS, CSS и т. Д.). Сделано популярным благодаря React.js. Печально известен своей сложной кривой обучения.
  3. Свернуть - Новый соперник. Использует модули ES6. Включает возможности встряхивания дерева (удаляет неиспользуемый код).

Вы можете прочитать больше о моем сравнении компонента Browserify с устаревшим компонентом .

Реализации AMD включают в себя:

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

Обратите внимание, что в своем поиске выбора того, с кем вам следует пойти, вы узнаете о Bower . Bower предназначен только для зависимостей пакетов и не определен в определениях модулей, таких как CommonJS и AMD.

Надеюсь, это поможет некоторым.

JP Richardson
источник
1
Большое спасибо. Я сделал мини-тест отдельно, поэтому мне потребовалось некоторое время, чтобы ответить. Я могу вернуться с некоторыми вопросами через несколько минут, чтобы убедиться, что я понимаю, как работает это волшебство. Я просто хочу собрать все воедино. Еще раз спасибо. Browserify, кажется, качается! :)
MightyMouse
6
Я думаю, что JSPM должен быть добавлен в список.
Мартейн
19
Могу ли я получить пример использования <script>тега для импорта класса React без использования менеджера пакетов nodeJs?
Луи Бертончин
2
SystemJS и JSPM - очень заметные упущения.
Алуан Хаддад
4
Да. Компонент больше не
поддерживается
43

Я из электронной среды, где мне нужно IPC-соединение между процессом рендеринга и основным процессом. Процесс рендеринга располагается в файле HTML между тегами скрипта и генерирует ту же ошибку. Линия

const {ipcRenderer} = require('electron')

выдает Uncaught ReferenceError: требование не определено

Я смог обойти эту проблему, указав для интеграции узла значение true, когда окно браузера (в которое встроен этот 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, хахаха
Luiscri,
Блестящий - приятно найти ответы, подобные этим, вместо того, чтобы полагаться на начинающих, чтобы волшебным образом соединить все это для вас.
GhostBytes
Отличный ответ для пользователей Electron!
thoni56
удивительный. работает довольно хорошо для меня. Кроме того, я пришел из видео списка покупок слишком 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 написано «Модуль создает область видимости, чтобы избежать конфликтов имен». Таким образом, вы можете «вручную» положить valобъект окна window.val = val. Вот плункер: Плункер: plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - это решение работает
Камиль Килчевски
1

В моем случае я использовал другое решение.

Поскольку проект не требует CommonJs и должен иметь совместимость с ES3 (модули не поддерживаются), все, что вам нужно, это просто удалить все операторы экспорта и импорта из вашего кода , потому что ваш tsconfig не содержит

"module": "commonjs"

Но используйте операторы импорта и экспорта в ваших ссылочных файлах

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

Окончательно сгенерированный код всегда будет иметь (по крайней мере для машинописного текста 3.0) такие строки

"use strict";
exports.__esModule = true;
var utils_1 = require("./utils");
....
utils_1.Utils.doSomething();
ydanila
источник
1

Даже использование этого не будет работать, я думаю, что лучшее решение - 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

Это сработало для меня

  1. сохраните этот файл https://requirejs.org/docs/release/2.3.5/minified/require.js
  2. загрузить в свой HTML, как это
    <script data-main="your-Scrpt.js" src="require.js"></script>
    примечание!
    используйте: -> require (['moudle-name']) в "your-script.js"
    не требуется ('имя-имя')
    const {ipcRenderer} = требуется ([электрон)]
    Не: const {ipcRenderer} = требуется (электрон)
eaithy
источник
3
Никогда, никогда не рекомендую «кликнуть здесь», никогда. В лучшем случае это RickRoll, но мы понятия не имеем, что нас ждет в конце этой ссылки.
ggdx