Dark_Knight
@Dark_Knight
Game Dev

Как написать свой метод require?

Здравствуйте, подскажите пожалуйста.
Задача в следующем: хочу написать свой метод - require, который должен загружать js-файлы.
То есть, выглядеть должно примерно так:
// file2.js
require('file1.js');

// и дальше используем св-ва и методы из file1.js

Другие библиотеки и фреймворки не подходят, так как само приложение относительно небольшое и грузить в него, к примеру, тот же require.js очень не желательно, так же все что мне нужно так это написать только один метод - загрузка файлов по требованию.
Как вариант:
function require(src) {
    // динамически создаем тег скрип, в который будем передавать src файла
}

Имеет ли такой код на жизнь? И если нет то почему?
Так же отдельное спасибо тем, кто подскажет, как работает метод requre в require.js? Я что-то так и не понял, ведь в него мы не передаем никакой путь к файлу, а только название объекта, а библиотека его сама находит или я ошибаюсь?
Спасибо за помощь и ваше время.
  • Вопрос задан
  • 2520 просмотров
Решения вопроса 1
k12th
@k12th
console.log(`You're pulling my leg, right?`);
Да, вполне себе можно создавать тэг script динамически и т.д. (RequireJS так и делает). Но будут подводные камни, особенно если надо поддерживать старые браузеры. Плюс остается вопрос сборки -- раз вас беспокоит размер, значит, вы не будете выкладывать на прод кучу отдельных файликов, а будете их склеивать, а как определять порядок?

само приложение относительно небольшое

Для RequireJS есть almond, на проде оверхед составит всего 1 кб -- не так уж много, а?
Еще вариант -- Browserify, оверхед -- вообще около 500 байт, куда меньше? Недостаток, конечно, что нужен этап сборки, но многие не против, попробуйте и вы.

не передаем никакой путь к файлу, а только название объекта, а библиотека его сама находит

не совсем название, это, скорее, виртуальный путь (require('../model/order', ... )), который резолвится в физический, исходя из корня проекта, пути к текущему модулю и алиасов и шимов, если они прописаны в конфиге.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@dtestyk
Можете попробовать промисы:
function load_script_promise(url){
	return new Promise(function(resolve, reject){
		var head = document.getElementsByTagName('head')[0]
		var script = document.createElement('script')
		script.type = 'text/javascript'
		script.addEventListener('load', function(){
			this.removeEventListener('load', arguments.callee)
			resolve(script)
		})
		script.src = url
		head.appendChild(script);
	})
}

Можно грузить параллельно:
Promise.all([
  load_script_promise("some1.js"),
  load_script_promise("some2.js")
]).then(alert)
Ответ написан
Комментировать
WhiteD
@WhiteD
Специалист широкого профиля
Есть два варианта. Первый: загружать содержимое скрипта через ajax и выполнять его через eval, функции и объекты будут доступны сразу после eval. Второй: как вы и написали, создавать элемент script. В этом случае бразуер будет подгружать этот скрипт асинхронно и вы не сможете сразу после создания элемента использовать функции и объекты из подгруженного скрипта.
Ответ написан
Keyten
@Keyten
var loaded = [];
function require(){
 for(var i = 0, l = arguments.length; i < l; i++){
  if(loaded.indexOf(arguments[i]) > 0) continue;
  var script = document.createElement('script');
  script.src = arguments[i];
  document.body.appendChild(script);
 }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы