Как устранить повторяющиеся запросы, вызванные относительными путями?

При оптимизации моего проекта require.js с помощью задачи grunt-contrib-requirejs многие сценарии требуются несколько раз из-за относительных путей. Ниже приведен список зависимостей, выводимых во время сборки:

components/requirejs/require.js
.tmp/scripts/../../components/flight/lib/././utils.js
.tmp/scripts/../../components/flight/lib/./././utils.js
.tmp/scripts/../../components/flight/lib/././../tools/debug/../../lib/./utils.js
.tmp/scripts/../../components/flight/lib/././../tools/debug/../../lib/registry.js
.tmp/scripts/../../components/flight/lib/././../tools/debug/../../lib/utils.js
.tmp/scripts/../../components/flight/lib/././../tools/debug/debug.js
.tmp/scripts/../../components/flight/lib/././compose.js
.tmp/scripts/../../components/flight/lib/./advice.js
.tmp/scripts/../../components/flight/lib/./utils.js
.tmp/scripts/../../components/flight/lib/./../tools/debug/../../lib/./utils.js
.tmp/scripts/../../components/flight/lib/./../tools/debug/../../lib/registry.js
.tmp/scripts/../../components/flight/lib/./../tools/debug/../../lib/utils.js
.tmp/scripts/../../components/flight/lib/./../tools/debug/debug.js
.tmp/scripts/../../components/flight/lib/./compose.js
.tmp/scripts/../../components/flight/lib/./registry.js
.tmp/scripts/../../components/flight/lib/component.js

Обратите внимание, что utils.js включен 7 раз:

.tmp/scripts/../../components/flight/lib/./utils.js
.tmp/scripts/../../components/flight/lib/././utils.js
.tmp/scripts/../../components/flight/lib/./././utils.js
.tmp/scripts/../../components/flight/lib/./../tools/debug/../../lib/utils.js
.tmp/scripts/../../components/flight/lib/./../tools/debug/../../lib/./utils.js
.tmp/scripts/../../components/flight/lib/././../tools/debug/../../lib/utils.js
.tmp/scripts/../../components/flight/lib/././../tools/debug/../../lib/./utils.js

Flight требует utils.js в каждом script в своем lib с контуром ./util, а иногда требует другого которые затем требуют ./util снова.

grunt-contrib-requirejs передает свои параметры непосредственно requirejs который включает в себя функцию trimDots, которая должна "[обрезать]. и.. из массива сегментов пути".

Почему это не касается некоторых очевидных дубликатов?

Что я могу сделать, чтобы устранить другие дубликаты, где относительный путь соответствует одному и тому же абсолютному пути?

Если относительные пути нормализуются к абсолютным путям, все будет хорошо.

Update:

Так структурирован мой проект:

.tmp/scripts/ (where coffeescript is compiled)
app/scripts/ (coffeescript source)
components/ (bower components)
dist/ (where optimized code is output)
Gruntfile.coffee (requirejs config)

Вот моя конфигурация requirejs из моего файла Grunt:

requirejs:
  dist:
    options:
      baseUrl: '.tmp/scripts'
      # paths relative to baseUrl
      paths:
        requireLib: '../../components/requirejs/require'
      include: 'requireLib'
      optimize: 'uglify2'
      generateSourceMaps: true
      preserveLicenseComments: false
      useStrict: true
      wrap: true
      name: 'main'
      out: 'dist/main.js'
      mainConfigFile: '.tmp/scripts/main.js'

Вот что в app/scripts/main.coffee:

require.config
  paths:
    # required dependencies
    jquery: '../../components/jquery/jquery'
    es5shim: '../../components/es5-shim/es5-shim'
    es5sham: '../../components/es5-shim/es5-sham'
    # plugins
    text: '../../components/requirejs-text/text'
    pickadate: '../../components/pickadate/source/pickadate.legacy'
  map:
    '*':
      'flight/component': '../../components/flight/lib/component'
  shim:
    '../../components/flight/lib/index':
      deps: ['jquery', 'es5shim', 'es5sham']
    'app':
      deps: ['../../components/flight/lib/index']

require ['app'], (App) ->
  App.initialize()

Вот что в app/scripts/app.coffee:

define [
  'ui/apple',
  'ui/orange'
], (Apple, Orange) ->
  initialize = ->
    Apple.attachTo document
    Orange.attachTo document
    return

  initialize: initialize

Оба app/scripts/ui/apple.coffee и app/scripts/ui/orange.coffee просто:

"use strict"
define ['flight/component'], (defineComponent) ->
  apple = ->
    # stuff
  defineComponent apple

Ответ 1

Попробуйте установить baseUrl в параметрах grunt-contrib-requirejs:

requirejs: {
    compile: {
        options: {
            baseUrl: "path/to/base"
        }
    }
}

Документировано здесь.

Ответ 2

Я вижу пару вещей с вашим кодом, который вызывает вопрос. Я знаю, что этот вопрос был задан более трех лет назад, поэтому некоторые из этих проблем, возможно, не были применимы в то время. Но я вернулся назад вовремя и посмотрел код полета с 3 лет назад, прежде чем ответить.

  • Почему вы предоставляете requireLib плагину grunt? Вам не нужно это делать, поскольку плагин grunt должен загружать свой собственный. В результате потребуется две загрузки libs, что просто запутывает.

  • Конфигурации Shim предназначены для использования только с не-AMD-модулями, однако вы подгоняете как "приложение", так и полет "index", которые являются одновременно и модулями AMD. Я ожидал бы от этого странного поведения.

  • Чтобы исправить №2 и сделать ваш код проще, вы можете полностью удалить прокладку и просто сопоставить все связанные с полетом:

    # main.coffee
    require.config
      paths:
        # required dependencies
        jquery: '../../components/jquery/jquery'
        es5shim: '../../components/es5-shim/es5-shim'
        es5sham: '../../components/es5-shim/es5-sham'
        # plugins
        text: '../../components/requirejs-text/text'
        pickadate: '../../components/pickadate/source/pickadate.legacy'
      map
        '*':
          'flight': '../../components/flight/lib'
    
    require ['jquery', 'es5shim', 'es5sham'], (App) ->
      require ['app'], (App) ->
        App.initialize()
    
    # app.coffee
    define [
      'flight/index',
      'ui/apple',
      'ui/orange'
    ], (Apple, Orange) ->
      initialize = ->
        Apple.attachTo document
        Orange.attachTo document
        return
    
      initialize: initialize
    

Я не уверен, что это устранит ваши проблемы, поэтому, если вы можете загрузить небольшой zip файл с соответствующим кодом, который поможет много.