Объединение файлов с помощью requirejs и grunt

Я пытаюсь объединить файлы, используя плагин grunt для requirejs:

https://www.npmjs.org/package/grunt-contrib-requirejs

Вот конфигурация:

requirejs:
      compile:
        options:
          #appDir: './'
          baseUrl: "client"
          mainConfigFile: "client/test1.js"
          name: "test1"
          out: "build/test.js"
          onModuleBundleComplete: (data) ->
            outputFile = data.path
            fs.writeFileSync(outputFile, amdclean.clean(
              'filePath': outputFile
            ))
          wrap:
            start: ""
            end: ""

Вот входной и выходной javascript

Вход: test1.js

var x = console;
require(['test2'], function() {
  return console.log('Hello');
});

test2.js

x.log('this is test2');

test.js

var test2, test1;
x.log("this is test2"), null, test2 = undefined;
var x;
x = console, function () {
    return console.log("Hello")
}(), test1 = undefined;

Программа отлично работает при загрузке в браузере с помощью requirejs. Но после завершения сборки он не работает. Это связано с тем, что определение x=console предоставляется до загрузки кода в test2.js, когда модули загружаются с использованием requirejs.

Однако после сборки определение x=console появляется после загрузки кода из test2.js, что создает ошибку, потому что test2.js вызывает x, который является глобальной переменной между двумя файлами js.

Мне нужно убедиться, что requirejs строит проект в один файл .js, при этом гарантируя отсутствие кода amd (require/define) и выполнение кода в ТОЧНОМ порядке, как при загрузке requirejs в браузере.


person EternallyCurious    schedule 30.05.2014    source источник


Ответы (1)


Я думаю, вам может понадобиться лучшее понимание определения асинхронного модуля (AMD) Спецификация API. В любом случае я немного изменил ваш код, чтобы он лучше соответствовал синтаксису AMD, и создал третий файл для определения x следующим образом:

  1. test1.js

    // Require the 'test2' module (which is passing x; which is equal to console)
    require(['test2'], function(x){
      x.log('this is test1');
    });
    
  2. test2.js

    // Define the 'test2' module which depends on the 'x' module
    define(['x'], function(x){
      x.log('this is test2');
      return x; // Return x; which is equal to console
    });
    
  3. x.js

    // Define the 'x' module which has no dependencies
    define(function(){
      console.log('this is x');
      return console; // Return console
    });
    
person idbehold    schedule 30.05.2014
comment
Мне это точно нужно! Собственно, поэтому я и задал вопрос на кворе. quora.com/ .Я ценю вашу помощь. - person EternallyCurious; 30.05.2014
comment
Хотя я назначил консоль x, на самом деле x содержит экземпляр объекта, который я хочу сделать доступным в качестве глобальной переменной для всех моих файлов и модулей javascript. Таким образом, как вы его определили, новый экземпляр x будет создаваться каждый раз, когда он вызывается каким-либо javascript следующим образом: define(['x'], function(x){. Мне нужен один экземпляр в моем приложении. - person EternallyCurious; 31.05.2014
comment
Еще один момент! Настоящая проблема, которую я хочу решить, - это фактическая конфигурация grunt, которая должна построить проект таким образом, чтобы скомпилированный файл работал точно так же, как файлы, загружаемые по отдельности с помощью requirejs. Решение, которое вы дали, не обеспечивает этого. - person EternallyCurious; 31.05.2014
comment
@EternallyCurious, независимо от того, какой объект вы назначаете x, он всегда будет ссылаться на один и тот же экземпляр, независимо от того, где он вам нужен. Все непримитивные типы данных в javascript передаются по ссылке. В любом случае, если вам нужен глобальный объект, почему бы просто не сделать window.x = { … }? - person idbehold; 31.05.2014