Подтвердить что ты не робот

Как минимизировать js файлы в порядке через grunt-contrib-uglify?

У меня есть каталог, как показано ниже:

/folder/b.js
/folder/jQuery.js
/folder/a.js
/folder/sub/c.js

Я хочу минимизировать все эти js файлы в одном файле js в порядке:

jQuery.js → a.js → b.js → c.js

Q:
1.Как я могу сделать это через grunt-contrib-uglify? (На самом деле, есть много файлов, нецелесообразно указывать все исходные файлы файлы в отдельности)

2.btw, как я могу получить unminified файлы при отладке и получить минимальный один файл при выпуске и не нужно менять тег script в html (и как писать тег script)?

4b9b3361

Ответ 1

Хорошие вопросы!

1) Uglify будет изменять порядок функций в целевом файле, чтобы определения функций находились сверху и выполнялись в нижней части, но, похоже, он сохранит порядок выполнения функций.

Это означает, что функция jQuery выполняется для определения ее глобальных функций, прежде всего, если вы убедитесь, что jQuery упоминается сначала в конфигурации Uglify в файле Grunt.

Я использую эту конфигурацию:

uglify: {
    options: {
        sourceMap: true
    },
    build: {
        files: {
            'public/all.min.js': ['public/js/vendor/jquery-1.10.2.min.js', 'public/js/*.js'],
        }
    }
}

2) Я не думаю, что есть один определенный способ сделать это. Это зависит от того, какие веб-рамки, рамки шаблонов и какие у вас есть требования. Я использую express + jade, и в моем основном дизайне нефрита я:

if process.env.NODE_ENV === 'production'
  script(src='/all.min.js')
else
  script(src='/js/vendor/jquery-1.10.2.min.js')
  script(src='/js/someScript.js')
  script(src='/js/otherScript.js')

В моем пакете .json у меня есть:

"scripts": {
  "postinstall": "grunt"
},

Это означает, что когда я запускаю npm install при развертывании (на Heroku), grunt запускается для minify/concat файлов, а когда приложение запускается с NODE_ENV=production, используется javascript с миниатюрной клиентской стороной. Локально я получаю исходные javascripts на стороне клиента для легкой отладки.

Двумя минутами являются:

  • Мне нужно синхронизировать два списка файлов script (в файле Gruntfile и в layout.js). Я решаю это, используя *.js в файле Grunt, но это может не соответствовать всем. Вы можете поместить список javascripts в Gruntfile и создать из него jade-шаблон, но для большинства проектов это кажется излишним.
  • Если вы не доверяете своей конфигурации Grunt, вам в основном нужно протестировать запуск приложения с помощью NODE_ENV=production локально, чтобы убедиться, что минимизация работает так, как вы планировали.

Ответ 2

Это можно сделать, используя следующие задачи Grunt:

ИЗМЕНИТЬ

Я обычно запускаю все свои файлы с помощью задачи конкатенации Grunt, используя grunt-contrib-concat. Тогда у меня есть еще одна задача - обрезать конкатенированный файл с помощью grunt-contrib-uglify.

Ответ 3

Вам, вероятно, не понравится это, но лучший способ - определить исходные файлы js как модули AMD и использовать Requirejs для управления порядком, в котором они загружаются. Задача grunt-contrib-requirejs рекурсирует ваше дерево зависимостей и объединит файлы js в необходимом порядке в один большой файл js. Затем вы будете использовать uglify (на самом деле r.js имеет встроенный встроенный), чтобы минимизировать большой файл.

https://github.com/danheberden/yeoman-generator-requirejs имеет хороший пример файлов gruntfile и js файлов шаблонов для работы.

ИЗМЕНИТЬ

Недавно я начал использовать модули CommonJS вместо AMD, так как он намного ближе к спецификации модуля ES6. Вы можете добиться тех же результатов (1 большой файл с согласованным + конкатенированным js), запустив модули commonjs через Browserify. Существуют плагины для grunt и gulp для управления этой задачей.

ИЗМЕНИТЬ

Я хотел бы добавить, что если ваш сайт написан с использованием ES6, Rollup является лучшим новым конкатенирующим пакетом. Помимо связывания ваших файлов, он также будет выполнять дрожание дерева, удаляя части библиотек, которые вы используете, если они включены в оператор import. Это уменьшает вашу кодовую базу до того, что вам нужно без раздувания кода, который вы никогда не будете использовать.

Ответ 4

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

Возможный рабочий процесс будет сначала конкатенировать (grunt-contrib-concat) файлы по порядку в один файл и поместить этот конкатенированный файл через uglify. Вы можете либо определить порядок concat в своем файле Grunt, либо использовать эти плагины:

Сначала будет https://github.com/yeoman/grunt-usemin, где вы можете указать порядок в своем HTML файле, поместите некоторые комментарии вокруг своего блока script. Ребята из Google сделали это, и это довольно мило для использования.

Во-вторых, https://github.com/trek/grunt-neuter, где вы можете определить некоторые зависимости с требованием, но без основной суммы require.js. Это требует изменений в вашем JS-коде, поэтому может не понравиться. Я бы выбрал один вариант.

Ответ 5

Я столкнулся с той же проблемой. Быстрое исправление - это просто изменить имена файлов - я использовал 1.jquery.min.js, 2.bootstrap.min.js и т.д.

Ответ 6

Это может быть только отдаленно связано с вашим вопросом, но я хотел что-то подобное. Только мой заказ был важен следующим образом:

Я загружал все файлы поставщиков (angular, jquery и их соответствующие связанные плагины) с помощью подстановочного знака (['vendor/**/*.js']). Но некоторые плагины имели имена, которые заставляли их загружать до angular и jquery. Решение состоит в том, чтобы вручную загрузить их в первую очередь.

['vendor/angular.js', 'vendor/jquery.js', 'vendor/**/*.js]

К счастью, angular и дескриптор jquery загружаются дважды достаточно хорошо. Изменить: Хотя это не самая лучшая практика для загрузки таких больших библиотек дважды, что приводит к ненужному раздуванию вашего мини файла. (спасибо @Kano за указание этого!)

Еще одна проблема заключалась в том, что заказ-js был важным для того, чтобы он загружал основной файл приложения, после того как все его зависимости были загружены. Решение этого было исключить, а затем включить:

['app/**/*.js', '!app/app.js', 'app/app.js']

Это предотвращает загрузку app.js вместе со всеми другими файлами и только затем включает его в конце.

Ответ 7

Похоже, вторая часть вашего вопроса все еще остается без ответа. Но позвольте мне попробовать один за другим.

Во-первых, вы можете присоединить и убрать большое количество js файлов в один, как объяснялось ранее ответом concat. Также должно быть возможно использовать https://github.com/gruntjs/grunt-contrib-uglify, поскольку он, похоже, имеет подстановочные знаки. Возможно, вам придется экспериментировать с опцией "expand = true" и подстановочными знаками. Это позаботится о вашем первом вопросе.

Для второй части, скажем, вы присоединились и угадали в big-ugly.js

Теперь в вашем html вы можете добавить следующие директивы:

<!-- build:js:dist big-ugly.js -->
<script src="js1.js"></script>
<script src="js2.js"></script>
<!-- etc etc --> 
<script src="js100.js"></script>
<!-- /build -->

И затем передайте его через прерывный hunt-html-препроцессор в https://www.npmjs.com/package/grunt-processhtml как часть ваших заданий на grunt.

Этот препроцессор заменит весь блок на

<script src="big-ugly.js"></script>

Это означает, что html файл должен быть семантически эквивалентным - до и после заданий grunt; то есть, если страница работает правильно в нативной форме (для отладки) - тогда преобразованная страница должна работать правильно после grunt - без необходимости вручную изменять любые теги.

Ответ 8

Это был ответ @1469, но он не дал понять, почему это работает. Используйте concat, чтобы поместить все js файлы в один, этот модуль делает это в порядке имен файлов, поэтому я помещаю префикс в имена файлов по заказам. Я считаю, что у него даже есть другие варианты для заказа.

concat: {

        js: {
            options: {
                block: true,
                line: true,
                stripBanners: true
            },
            files: {
                'library/dist/js/scripts.js' : 'library/js/*.js',
            }
        }
    },

Затем используйте uglify для создания миниатюрной уродливой версии:

uglify: {
      dist: {
        files: {
          'library/dist/js/scripts.min.js': [
            'library/js/scripts.js'
          ]

        },
        options: {

        }
      }
    },

Ответ 9

Если ваша проблема заключалась в том, что у вас были поставщики, которые нужно было загрузить по порядку (скажем, jquery перед любыми плагинами jquery). Я решил это, поставив jquery в свою собственную папку под названием "! Jquery", эффективно помещая ее поверх стека. Тогда я просто использовал concat, как обычно:

concat: {
  options: {
    separator: ';',
  },
  build: {
    files: [
      {
        src: ['js/vendor/**/*.js', 'js/main.min.js'],
        dest: 'js/global.min.js'
      }
    ]
  }
},