Статьи

Исходные карты 101

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

Именно здесь вступают в игру исходные карты, указывая точное соответствие в нашем производственном коде исходному авторскому коду. В этом вводном уроке мы возьмем простой проект и запустим его через различные компиляторы JavaScript для игры с исходными картами в браузере.


Исходные карты предлагают не зависящий от языка способ отображения производственного кода на исходный код, который был создан.

Исходные карты предлагают независимый от языка способ сопоставления производственного кода с исходным кодом, созданным в вашей среде разработки. Когда мы в конечном итоге смотрим на кодовую базу, сгенерированную и подготовленную для производства, становится очень сложно определить, где именно находится линейное сопоставление с нашим оригинальным авторским кодом. Однако во время компиляции исходная карта хранит эту информацию, поэтому, когда мы запрашиваем участок строки, он возвращает нам точное местоположение в исходном файле! Это дает огромное преимущество для разработчика, так как код становится читабельным и даже отлаживаемым!

В этом руководстве мы рассмотрим очень простой код JavaScript и SASS , проведем их через различные компиляторы, а затем просмотрим наши оригинальные файлы в браузере с помощью исходных карт. Загрузите демонстрационные файлы и начните!


Обратите внимание, что при написании этой статьи Chrome (версия 23) поддерживает исходные карты JavaScript и даже исходные карты SASS . Firefox также должен получить поддержку в ближайшем будущем, так как в настоящее время он находится на активной стадии разработки. С этим предостережением, давайте теперь посмотрим, как мы можем использовать исходные карты в браузере!

Во-первых, мы должны включить поддержку в Chrome, выполнив следующие простые шаги:

  • Откройте Инструменты разработчика Chrome: Просмотр -> Разработчик -> Инструменты разработчика
  • Нажмите на кнопку «Настройки» в правом нижнем углу.
  • Выберите «Общие» и выберите «Включить исходные карты»

Если вы хотите работать с этим учебником, скачайте демо-версию и откройте каталог «start». Структура файлов и каталогов довольно проста, с некоторым простым JavaScript в scripts/script.js . Вы должны иметь возможность открыть index.html и даже добавить некоторые имена цветов CSS или шестнадцатеричные значения, чтобы изменить цвет фона.

01
02
03
04
05
06
07
08
09
10
11
$ tree
.
├── index.html
├── scripts
│  ├── jquery.d.ts
│  ├── script.coffee.coffee
│  ├── script.js
│  └── script.typescript.ts
└── styles
    ├── style.css
    └── style.sass

Посмотрите простые файлы сценариев на простом JavaScript, TypeScript или CoffeeScript. Используя различные компиляторы JavaScript, мы создадим готовую к работе версию, а также сгенерируем соответствующие исходные карты.

В следующих разделах мы будем использовать пять различных способов создания скомпилированного и минимизированного script.js вместе со связанной исходной картой. Вы можете либо протестировать все опции, либо просто пойти с компилятором, с которым вы уже знакомы. Эти параметры включают в себя:

  1. Закрытие Компилятор
  2. GruntJS с JSMin
  3. Углифы 2
  4. CoffeeScript и Redux
  5. Машинопись

Closure Compiler от Google — это инструмент для оптимизации JavaScript. Это делается путем анализа вашего кода, удаления ненужных битов, а затем минимизации остального. Кроме того, он также может генерировать исходные карты .

Давайте используем следующие шаги для создания оптимизированной версии script.js с использованием компилятора Closure:

  1. Загрузите последний компилятор Closure.
  2. Перенесите файл compiler.jar в каталог scripts .
  3. Перейдите в каталог, scripts , из командной строки и выполните следующее, чтобы был создан оптимизированный, готовый к script.closure.js файл script.closure.js :
    1
    java -jar compiler.jar —js script.js —js_output_file script.closure.js
  4. Убедитесь, что index.html теперь связан с вновь созданным файлом scripts/script.closure.js , раскомментировав опцию A.

Когда мы открываем index.html в браузере и переходим к панели источников в инструментах разработчика, упоминается только оптимизированная версия script.closure.js ; у нас нет никакого способа вернуть отношение к нашему оригиналу с должным отступом. Давайте теперь создадим исходный файл карты, выполнив следующую команду в каталоге scripts :

1
java -jar compiler.jar —js script.js —create_source_map script.closure.js.map —source_map_format=V3 —js_output_file script.closure.js

Обратите внимание, что Closure Compiler использует две опции, --create_source_map и --source_map_format , для создания файла карты источника, script.closure.js.map , с версией карты источника 3. Затем добавьте URL-адрес сопоставления источника в конец файл скомпилированного скрипта script.closure.js , так что оптимизированный файл содержит информацию о местоположении исходной карты:

1
//@ sourceMappingURL=script.closure.js.map

Теперь, когда мы просматриваем проект в браузере, в каталоге «scripts» в панели источников инструментов разработчика будут отображаться как исходный файл, так и оптимизированная версия script.closure.js . Хотя браузер, конечно, использует оптимизированный файл, на который мы изначально ссылались в index.html , исходные карты позволяют нам создать соединение с исходным файлом.

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


Если вы уже используете Grunt.js для процессов сборки, тогда плагин Grunt для исходных карт JSMin пригодится. Он не только оптимизирует ваш код, но и создаст исходную карту!

Следующие шаги продемонстрируют, как создать оптимизированную версию script.js с плагином Grunt JSMin:

  1. установите Grunt.js и запустите gruntfile , grunt.js , в корне каталога «start»:
    1
    2
    3
    4
    5
    6
    $ npm install -g grunt
    $ npm view grunt version
    npm http GET https://registry.npmjs.org/grunt
    npm http 200 https://registry.npmjs.org/grunt
    0.3.17
    $ grunt init:gruntfile
  2. Установите плагин Grunt grunt-jsmin-sourcemap ; когда вы это сделаете, будет создан каталог с именем node_modules/grunt-jsmin-sourcemap :
    1
    $ npm install grunt-jsmin-sourcemap
  3. Отредактируйте вновь созданный файл grunt.js чтобы он содержал только задачу jsmin-sourcemap — чтобы все было как можно проще.
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    module.exports = function(grunt) {
      grunt.loadNpmTasks(‘grunt-jsmin-sourcemap’);
      grunt.initConfig({
        ‘jsmin-sourcemap’: {
          all: {
            src: [‘scripts/script.js’],
            dest: ‘scripts/script.jsmin-grunt.js’,
            destMap: ‘scripts/script.jsmin-grunt.js.map’
          }
        }
      });
      grunt.registerTask(‘default’, ‘jsmin-sourcemap’);
    };
  4. Вернитесь в командную строку и запустите grunt ; это выполнит задачу jsmin-sourcemap, поскольку задача по умолчанию указана как таковая в файле grunt.js:
    1
    2
    3
    4
    $ grunt
    Running «jsmin-sourcemap:all» (jsmin-sourcemap) task
     
    Done, without errors.
  5. В недавно созданном файле карты источника, script.grunt-jsmin.js.map , убедитесь, что источником является "sources":["script.js"].
  6. Раскомментируйте параметр B, чтобы связать его с вновь созданным файлом script.grunt-jsmin.js в index.html и открыть в браузере.

С Grunt и плагином jsmin-sourcemap в процессе сборки были созданы два файла: файл оптимизированного сценария с URL-адресом сопоставления источника в нижней части, а также карта источника. Вам нужно будет оба из них, чтобы просмотреть все из них в браузере.


UglifyJS2 — это еще один синтаксический анализатор, minfier и компрессор JavaScript. Подобно двум вышеупомянутым альтернативам, UglifyJS2 создаст оптимизированный файл сценария с добавлением URL-адреса сопоставления источника, а также файла сопоставления источника, который будет содержать сопоставление с исходным файлом. Чтобы использовать UglifyJS, выполните в командной строке каталога «start» следующее:

  1. Установите модуль NPM, uglify-js , локально; каталог, названный nocde_module/uglify-js , будет создан.
    1
    2
    3
    4
    $ npm install uglify-js
    $ npm view uglify-js version
    2.2.3
    $ cd scripts/
  2. В каталоге «scripts» мы выполним команду для создания оптимизированной версии, а также исходный файл с параметрами, --source-map и --output , для присвоения имени выходному файлу.
    1
    uglifyjs —source-map script.uglify.js.map —output script.uglify.js script.js
  3. Наконец, убедитесь, что index.html правильно связан со сценарием script.uglify.js

Для предыдущих трех вариантов нам потребовалась только одношаговая оптимизация, от исходного кода до оптимизированного JavaScript. Однако для таких языков, как CoffeeScript , нам нужен двухэтапный процесс: CoffeeScript> JavaScript> оптимизированный JavaScript. В этом разделе мы рассмотрим, как создавать многоуровневые исходные карты с помощью CoffeeScript и компилятора CoffeeScript Redux.

Перейдите в каталог «Пуск» в командной строке. В следующих шагах мы отобразим оптимизированный файл сценария обратно на CoffeeScript:

  1. Установите CoffeeScript как глобальный пакет npm
  2. Скомпилируйте файл CoffeeScript, script.coffee.coffee , чтобы создать простую версию JavaScript, используя следующую команду:
    1
    $ coffee -c scripts/script.coffee.coffee
  3. Установите CoffeeScript Redux :
    1
    2
    3
    4
    5
    $ git clone https://github.com/michaelficarra/CoffeeScriptRedux.git coffee-redux
    $ cd coffee-redux
    $ npm install
    $ make -j test
    $ cd ..
  4. Затем мы создадим исходный файл карты, script.coffee.js.map , который будет хранить информацию о сопоставлении из сгенерированного JavaScript обратно в файл CoffeeScript:
    1
    $ coffee-redux/bin/coffee —source-map -i scripts/script.coffee.coffee > scripts/script.coffee.js.map
  5. Убедитесь, что сгенерированный файл JavaScript, script.coffee.js , имеет URL-адрес сопоставления источника в конце со следующей строкой:
    1
    //@ sourceMappingURL=script.coffee.js.map
  6. Убедитесь, что исходный файл карты, script.coffee.js.map , имеет правильный ссылочный файл как "file":"script.coffee.coffee" , а исходный файл как "sources":["script.coffee.coffee"]
  1. Наконец, мы снова будем использовать UglifyJS для минимизации сгенерированного JavaScript, а также для создания исходной карты. На этот раз потребуется исходная карта, чтобы мы могли вернуться к исходному файлу CoffeeScript. Выполните следующую команду в каталоге «scripts»:
    1
    2
    $ cd scripts/
    $ uglifyjs script.coffee.js -o script.coffee.min.js —source-map script.coffee.min.js.map —in-source-map script.coffee.js.map
  2. Наконец, убедитесь, что в файле исходной карты, script.coffee.min.js.map , script.coffee.min.js.map правильный файл ссылки "file":"script.coffee.min.js" , а правильные источники — "sources":["script.coffee.coffee"] .

TypeScript, как и CoffeeScript, также требует двухэтапного процесса: TypeScript> Простой JavaScript> Минимизированный JavaScript. Поскольку скрипт использует плагин jQuery, нам нужны два файла TypeScript, которые уже предоставлены: script.typescript.ts и jquery.d.ts .

Перейдите в каталог «scripts» из командной строки и выполните следующую команду:

1
$ tsc script.typescript.ts -sourcemap

Приведенная выше команда создаст новый файл JavaScript с именем script.typescript.js , с URL-адресом отображения источника внизу: //@ sourceMappingURL=script.typescript.js.map . С помощью этой единственной команды он также создаст файл карты script.typescript.js.map .

Как и в примере с CoffeeScript, следующим шагом будет использование UglifyJS.

1
$ uglifyjs script.typescript.js -o script.typescript.min.js —source-map script.typescript.min.js.map —in-source-map script.typescript.js.map

Наконец, убедитесь, что index.html ссылается на правильный файл scripts/script.typescript.min.js и откройте его в браузере!


Помимо JavaScript, в настоящее время Chrome также поддерживает исходные карты SASS или SCSS. Для отображения источника SASS давайте изменим несколько настроек в Chrome, а затем скомпилируем SASS в CSS с параметрами отладки:

  1. Прежде чем изменять какие-либо настройки, обратите внимание, что после проверки элемента из инструментов разработчика он покажет нам только ссылку на файл CSS. Это не слишком полезно.
  2. Перейдите в chrome: // flags / .
  3. Включить экспериментальные инструменты разработчика.
  4. Откройте «Инструменты разработчика»> «Настройки»> «Эксперименты»> «Проверка поддержки SASS».
  5. Скомпилируйте SASS со следующими параметрами отладки в каталоге «styles». Это добавит к каждому набору правил CSS @media -sass-debug-info которая будет содержать информацию о имени файла и номере строки.
    1
    2
    $ cd styles/
    $ sass —debug-info —watch style.sass:style.css
  6. Обязательно перезапустите инструменты разработчика и обновите страницу.
  7. Теперь, когда мы проверяем элемент, мы можем получить доступ к исходному файлу SASS!

Помимо простого просмотра файла SASS, если вы запускаете LiveReload в фоновом режиме и вносите изменения в файл SASS, страница также обновится, чтобы отразить изменения. Например, давайте откроем проект в Firefox и проверим страницу, используя расширение Firebug .


Если мы просмотрим любой из файлов *.map , он будет содержать информацию о сопоставлении из исходного файла в оптимизированный файл. Структура исходной карты обычно представлена ​​в формате JSON с использованием спецификаций версии 3 . Обычно он содержит следующие пять свойств:

  1. версия: номер версии исходной карты — обычно «3».
  2. file: имя оптимизированного файла.
  3. источники: имена исходных файлов.
  4. имена: символы, используемые для отображения.
  5. отображения: отображение данных.

Исходные карты все еще находятся в стадии активной разработки, но в Интернете уже есть несколько отличных ресурсов. Обязательно учтите следующее, если вы хотите узнать больше.


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