Клиент на узле: 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файле, который открывает сокет для сервера?


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.

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


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();

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} = требуется (электрон)

3
Никогда, никогда не рекомендую «кликнуть здесь», никогда. В лучшем случае это RickRoll, но мы понятия не имеем, что нас ждет в конце этой ссылки.
— ggdx
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.