Как я могу легко ссылаться на отдельные файлы js / css для отладки при использовании gulp или grunt? - PullRequest
0 голосов
/ 17 июня 2020

Я разрабатываю устаревший проект ASP. NET MVC 5, который все еще использует ASP. NET Bundling и Minification. Я заинтересован в переходе на Gulp или Grunt, потому что мне нужно сохранить исходные карты для моих js файлов.

Кажется, легко сгенерировать пакет минифицированных скриптов с помощью Gulp или Grunt, но то, что я не делаю Поймите, что это рекомендуемая установка для загрузки одиночных js файлов при отладке и минифицированных пакетов в продакшене. Я предполагаю, что было бы довольно легко сгенерировать представление бритвы для включения скриптов как части моего процесса компиляции Grunt / Gulp, но это похоже на изобретение колеса заново.

Например, в ASP. NET MVC я могу написать что-то вроде этого:

@Scripts.Render("~/bundles/MyJSBundle")

, и он автоматически загрузит отдельные файлы js в разработке и единый пакет сценариев в производстве. Как проще всего добиться этого с помощью Gulp или Grunt?

1 Ответ

3 голосов
/ 25 июня 2020

Краткий ответ:

Обычно при использовании Grunt вы генерируете две сборки - одну для "dev" (разработка) и другую для "dist" (распространение / производство) . При этом для описанного вами сценария:

  • Обе сборки "dev" и "dist" генерируют единую объединенную / уменьшенную версию файла (например, bundle.min.js) получен из нескольких исходных .js файлов.
  • Однако только сборка "dev" генерирует дополнительные файлы исходной карты, содержащие информацию о вашем исходном .js для отладки в течение жизненного цикла разработки.

Плагины Grunt, такие как grunt-process html, позволяют обновлять любые ссылки на .js ресурсов в файле .html. Например, предположим, что ваш источник .html содержит эти две ссылки;

<script src="js/a.js"/>
<script src="js/b.js"/>

Их можно заменить во время "dist" и / или "dev" шаг сборки до следующего единственного элемента <script>:

<script src="dir/bundle.min.js"/> 

Пример демонстрации:

Следующий несколько надуманный пример демонстрирует, как вы можете выполнить свои требования с помощью Grunt.

  1. Допустим, наш исходный каталог проекта структурирован следующим образом:

    project
    ├── Gruntfile.js
    ├── node_modules
    │   └── ...
    ├── package.json
    └── src
        ├── index.html
        └── js
            ├── a.js
            └── b.js
    

    Обратите внимание, в каталоге src у нас есть один файл index.html и два файла .js в каталоге js.

  2. В показанном ниже содержимом index.html он содержит два элемента <script>, каждый из которых ссылается на файл .js.

    project / src / index. html

    <!DOCTYPE html>
    
    <html>
    
    <head>
      <meta charset="utf-8" />
      <title>demo</title>
    </head>
    
    <body>
    
      <!--build:js js/bundle.min.js-->
      <script src="js/a.js"></script>
      <script src="js/b.js"></script>
      <!--/build-->
    </body>
    
    </html>
    

    Обратите внимание, пользовательские комментарии HTML включают оба элемента <script>. Эти пользовательские HTML комментарии используются grunt-processhtml. Часть, которая читает; js/bundle.min.js в комментарии по существу определяет новое имя пути, которое будет использоваться.

  3. Рассмотрим следующую конфигурацию Gruntfile.js:

    Gruntfile. js

    module.exports = function (grunt) {
    
      grunt.loadNpmTasks('grunt-contrib-concat');
      grunt.loadNpmTasks('grunt-contrib-uglify');
      grunt.loadNpmTasks('grunt-processhtml');
    
      grunt.initConfig({
    
        // 1. Concatenate .js files.
        concat: {
          dist: {
            src: [
              'src/js/a.js',
              'src/js/b.js'
            ],
            dest: './dist/js/bundle.min.js'
          },
          dev: {
            options: {
              sourceMap: true
            },
            src: [
              'src/js/a.js',
              'src/js/b.js'
            ],
            dest: './dev/js/bundle.min.js'
          }
        },
    
        // 2. Minify .js files.
        uglify: {
          dist: {
            files: {
              './dist/js/bundle.min.js': './dist/js/bundle.min.js' // dest : src
            }
          },
          dev: {
            options: {
              mangle: false,
              sourceMap: true,
              sourceMapIn: './dev/js/bundle.min.js.map'
            },
            files: {
              './dev/js/bundle.min.js': './dev/js/bundle.min.js' // dest : src
            }
          }
        },
    
        // 2. Process .html file.
        processhtml: {
          dist: {
            files: {
              './dist/index.html': './src/index.html' // dest : src
            }
          },
          dev: {
            files: {
              './dev/index.html': './src/index.html' // dest : src
            }
          }
        }
    
      });
    
    
      grunt.registerTask('default', ['dist', 'dev']);
    
      grunt.registerTask('dist', [
        'concat:dist',
        'uglify:dist',
        'processhtml:dist'
      ]);
    
      grunt.registerTask('dev', [
        'concat:dev',
        'uglify:dev',
        'processhtml:dev'
      ]);
    
    };
    

    Пояснение к Gruntfile. js:

    • В дополнение к ранее упомянутому grunt-processhtml плагину следующие два также используются в этом примере:

      • grunt-contrib-concat - для объединения двух файлов .js.

      • grunt-contrib-uglify - для минимизации файла .js.

        Примечание: Для этих типов задач доступны другие плагины. . Я выбрал эти два дополнительных плагина для этой демонстрации.

    • Каждый из трех Задач (concat , uglify и processhtml) содержат две отдельные цели с именами dist и dev. Основными отличиями в каждой Target являются:

      • Различные dest (целевые) пути для созданного .js файла (ов) в результате.
      • Для concat:dev и uglify:dev Targets его объект options определяет конфигурацию для результирующего файла исходной карты.
    • В конце Gruntfile.js были определены три разных grunt.registerTask(). Каждый из них определяет taskList , который по существу определяет, какие Task и Target запускать в указанном порядке.

      Например, рассмотрим следующую зарегистрированную задачу с именем dist:

      grunt.registerTask('dist', [
        'concat:dist',
        'uglify:dist',
        'processhtml:dist'
      ]);
      

      При запуске grunt dist через командную строку Grunt по существу вызывает эту Task , которая впоследствии выполняет следующее в следующем порядке:

      1. Сначала запускается dist Target , определенный в concat Task .
      2. Затем запускается dist Target определено в uglify Task .
      3. Наконец, запускает dist Target , определенный в processhtml Task .
  4. Запуск Gruntfile. js (см. Выше) и его вывод

    1. Запуск следующая команда через командную строку:

      grunt dev
      

      выводит следующие дополнительные ресурсы в каталог проекта:

      project
      ├── ...
      ├── dev
      │   ├── index.html
      │   └── js
      │       ├── bundle.min.js
      │       └── bundle.min.js.map
      └── ...
      

      Как видите:

      • Создана новая папка dev в root директории проекта.

      • Два элемента <script>, изначально определенные в project/src/index.html, были заменены во вновь созданном project/dev/index.html одним тегом <script> следующим образом:

        <script src="js/bundle.min.js"></script>
        
      • Оба файла; project/src/js/a.js и project/src/js/b.js были объединены и уменьшены в результирующем project/dev/js/bundle.min.js.

      • Создан следующий файл исходной карты; project/dev/js/bundle.min.js.map. Этот файл по сути соответствует исходным файлам project/src/js/a.js и project/src/js/b.js.

    2. Выполнение следующей команды через командную строку:

      grunt dist
      

      выводит следующие дополнительные ресурсы в каталог проекта:

      project
      ├── ...
      ├── dist
      │   ├── index.html
      │   └── js
      │       └── bundle.min.js
      └── ...
      

      Как вы можете видеть на этот раз;

      • Создана папка dist в root каталога проекта.

      • Опять же, два элемента <script>, изначально определенные в project/src/index.html, были заменены во вновь созданном project/dist/index.html одним <script> тег (согласно вышеупомянутому dev Task ).

      • Опять же, оба файла; project/src/js/a.js и project/src/js/b.js были объединены и уменьшены в результирующем project/dist/js/bundle.min.js.

      • Однако главное заметное отличие состоит в том, что НЕТ файла исходной карты не был создан .

    3. Выполнение следующей команды через командную строку:

      grunt
      

      даст оба результата, определенные на предыдущих шагах 1 и 2.

...