Жизнь слишком коротка, я использую шаблоны ES6

Node.js внешний интерфейс JavaScript регулярное выражение HTML
Жизнь слишком коротка, я использую шаблоны ES6

ES6 (ES2015) Для JavaScript представляет множество новых функций, новую функцию, связанную со строевой обработкой - буквальные шаблоны, обеспечивает возможность многострочных строк, строковых шаблонов, я считаю, что многие люди уже используются. Основным шаблоном буквальным использованием очень простых, но большинство разработчиков, все еще рассматривают его как синтаксическое соединение строки сахара для использования, на самом деле это намного сильнее способность, чем это о. Преувеличение, чтобы сказать, что это может быть ES6 так много характеристик, наиболее легко недооценивать характеристики. Вот почему.

Основные характеристики

Литералы шаблонов называются в спецификации ES2015Template Literals, вызываемый в более ранних версиях документа спецификацииTemplate Strings, так много китайских документов, которые мы видели, также пишут это какстрока шаблона, которые для удобства иногда неофициально называют шаблонами ES6.

В JavaScript до ES6 в качестве базовых типов использовались строки, и их представление в коде было только путем заключения строк в кавычки (одинарные кавычки 'или двойные кавычки'), и литералы шаблонов ES6 (далее шаблоны ES6 ) используемые обратные кавычки (`) переносятся как строковая запись.

Обычные строки между двумя обратными кавычками оставляются как есть, например:

`hello world` === "hello world"  // --> true
`hello "world"` === 'hello "world"' // --> true
`hello 'world'` === "hello 'world'" // --> true
`\`` // --> "`" // --> true

Новая строка — это тоже всего лишь один символ, поэтому литералы шаблонов также естественным образом поддерживают многострочные символы:

console.log(`TODO LIST:
    * one
    * two
`)
// TODO LIST:
//     * one
//     * two

между двумя обратными кавычками${expression}Формат содержит любое выражение JavaScript, значение которого преобразуется в строку, объединенную со строками до и после выражения. Когда выражение расширяется до строки, оно используетexpression.toString()функция.

const name = "Alice"
const a = 1
const b = 2
const fruits = ['apple', 'orange', 'banana']
const now = new Date()
console.log(`Hello ${name}`)
console.log(`1 + 2 = ${a + b}`)
console.log(`INFO: ${now}`)
console.log(`Remember to bring: ${ fruits.join(', ') }.`)
console.log(`1 < 2 ${ 1 < 2 ? '✔︎' : '✘'}`)
// Hello Alice
// 1 + 2 = 3
// INFO: Sun May 13 2018 22:28:26 GMT+0800 (中国标准时间)
// Remember to bring: apple, orange, banana.
// 1 < 2 ✔︎

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

const fruits = ['apple', 'orange', 'banana']
const quantities = [4, 5, 6]
console.log(`I got ${
    fruits
        .map((fruit, index) => `${quantities[index]} ${fruit}s`)
        .join(', ')
}`)
// I got 4 apples, 5 oranges, 6 bananas

По сравнению с традиционными шаблонизаторами

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

Поэтому мы, естественно, подумали, что в сложнейшем сценарии склейки строк в практических приложениях — шаблоне HTML, если используется шаблон ES6, может ли он быть грамотным? Традиционно для этого мы используем специальный механизм шаблонов.Давайте сравним шаблоны ES6 с механизмами шаблонов. Мы выбралиlodashиз_.templateШаблонный движок, хотя этот движок не такой большой и полный, как усы и мопсы, но предоставляемые функции достаточно полны.Давайте возьмем некоторые из его основных функций и сценариев в качестве примеров для сравнения.

1-й, базовая интерполяция строк._.templateиспользовать<%= expression %>В качестве разделителя интерполяции шаблона значение выражения будет выводиться необработанным, как и в шаблонах ES6. Так что в этой фиче шаблоны ES6 вполне компетентны.

  • lodash

    const compiled = _.template('hello <%= user %>!')
    console.log(compiled({ user: 'fred' }))
    // hello fred
    
  • Шаблоны ES6

    const greeting = data => `hello ${data.user}`
    console.log(greeting({ user: 'fred' }))
    // hello fred
    

Во-вторых, строковый escape-вывод, который является стандартной функцией механизма шаблонов HTML для предотвращения XSS.Принцип заключается в том, чтобы включить в значение интерполяционного выражения<,>Такие символы, которые могут использоваться для XSS-атак, экранируются как объекты HTML. Чтобы lodash выводил экранированное интерполяционное выражение, используйте<%- expression %>Синтаксиса достаточно, если вы хотите использовать шаблонную схему ES6, вам нужно реализовать отдельный вызов функции самостоятельно. В следующем примере кода определена простая функция escapeHTML, которая вызывается в строке шаблона для экранирования строки.

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

  • lodash

    const compiled = _.template('<b><%- value %></b>')
    
  • Шаблоны ES6

    const entityMap = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;',
        '/': '&#x2F;',
        '`': '&#x60;',
        '=': '&#x3D;'
    }
    const escapeHTML = string => String(string).replace(/[&<>"'`=\/]/g, (s) => entityMap[s]);
    const greeting = data => `hello ${escapeHTML(data.user)}`
    console.log(greeting({ user: '<script>alert(0)</script>'}));
    // hello &lt;script&gt;alert(0)&lt;&#x2F;script&gt;
    

В-третьих, в шаблон встроены операторы JavaScript, то есть механизм шаблонов поддерживает генерацию HTML путем выполнения операторов JavaScript в шаблоне. Грубо говоря, принцип тот же, что и у php, лучшего языка в мире. В шаблоне lodash используйте<% statement %>Вы можете выполнять операторы JS.Один из наиболее типичных сценариев использования — использование цикла for для перебора содержимого массива в шаблоне.

Но заполнители в шаблонах ES6${}Поддерживаются только выражения вставки, поэтому прямо в них нельзя выполнять операторы JavaScript, такие как циклы for. Но это не имеет значения, мы можем получить тот же результат с помощью некоторых простых приемов, таких как работа с массивами, нам просто нужно правильно использовать возможности массива.map,reduce,filter, чтобы результат выражения соответствовал нашим потребностям.

  • lodash

    /* 使用 for 循环语句,迭代数组内容并输出 */
    const compiled = _.template('<ul><% for (var i = 0; i < users.length; i++) { %><li><%= list[i] %></li><% } %></ul>')
    console.log(compiled({ users: ['fred', 'barney'] }))
    // <ul><li>fred</li><li>barney</li></ul>
    
  • Шаблоны ES6

    const listRenderer = data => `<ul>${data.users.map(user => `<li>${user}</li>`).join('')}</ul>`
    console.log(listRenderer({ users: ['fred', 'barney']}))
    // <ul><li>fred</li><li>barney</li></ul>
    

В приведенных выше трех примерах сценариев мы обнаружили, что шаблоны ES6 могут делать то же, что и шаблоны lodash, поэтому можем ли мы отказаться от механизма шаблонов?

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

Но если мы используем большой и всеобъемлющий механизм шаблонов, такой как pug, artTemplate и Handlebars, не обязательно использовать замену шаблона ES6. В частности, функции этих механизмов шаблонов в сценариях на стороне сервера, такие как кэширование шаблонов, конвейерный вывод и модульное управление файлами шаблонов, недоступны в самих шаблонах ES6. И механизм шаблонов — это независимая библиотека, а инкапсуляция и расширяемость API лучше, чем у шаблонов ES6, которые могут только вставлять выражения.

Переходим на новый уровень — шаблоны тегов

С представленными функциями мы можем видеть этот факт из приведенного выше кода для двух примеров экранирования строки шаблона HTML и вывода итерации массива:

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

К счастью, помимо поиска способов вызова различных функций преобразования строк в выражениях интерполяции шаблонов, ES6 также предоставляет более элегантное и простое в повторном использовании решение — тегированные литералы шаблонов (tagged template literals), далее именуемые шаблоном меток).

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

const message = l10n`I bought a ${brand} watch on ${date}, it cost me ${price}.`

В этом примереl10nэто имя тега, содержимое между обратными кавычками является содержимым шаблона, эта строка оператора присваивает значение выражения шаблона дляmessage, конкретный процесс обработки:

  1. Механизм JS сначала разделит содержимое шаблона с помощью заполнителей и сохранит разделенные строки в массиве.stringsСредний (следующий код используется только для демонстрации принципа)

    const strings = "I bought a ${brand} watch on ${date}, it cost me ${price}".split(/\$\{[^}]+\}/)
    // ["I bought a ", " watch on ", ", it cost me ", "."]
    
  2. Затем поместите заполнителей в контент шаблонавыражениеВынь, там другой массив на очередиrestсередина

    const rest = [brand, date, price]
    
  3. воплощать в жизньi18n(strings, ...rest)функция, которая вызываетl10n, и передать две части параметров, первая частьstringsКак первый параметр, вторая часть будетrestРаскройте остальные параметры.

    const message = l10n(strings, ...rest) 
    

Итак, если вы объедините приведенные выше одношаговые разложения вместе, это будет эквивалентная форма:

const message = l10n(["I bought a ", " watch on ", ", it cost me ", "."], brand, date, price)

То есть, когда мы добавляем к шаблонуl10nКогда этот ярлык на самом деле называетсяl10nфункцию и передать параметры вызова указанным выше способом.l10nФункция может быть предоставлена ​​нам для настройки, чтобы приведенная выше строка кода 👆 выдавала нужную нам строку. Например, если мы хотим, чтобы дата и цена отображались в виде локальной строки, мы можем сделать это:

const l10n = (strings, ...rest) => {
    return strings.reduce((total, current, idx) => {
        const arg = rest[idx]
        let insertValue = ''
        if (typeof arg === 'number') {
            insertValue = `¥${arg}`
        } else if (arg instanceof Date) {
            insertValue = arg.toLocaleDateString('zh-CN')
        } else if (arg !== undefined) {
            insertValue = arg
        }
        return total + current + insertValue
    }, '');
}
const brand = 'G-Shock'
const date = new Date()
const price = 1000

l10n`I bought a ${brand} watch on ${date}, it cost me ${price}.`
// I bought a G-Shock watch on 2018/5/16, it cost me ¥1000.

здесьl10nЭто простой и дурацкий тег шаблона локализации, который поддерживает число в содержимом шаблона в виде суммы плюс символ юаня и преобразует дату вzh-CNрегиональный формат2018/5/16нить.

Поначалу это не кажется чем-то особенным, но представьте, как такого же эффекта можно добиться с помощью немаркированного шаблона? Нам нужно вызвать соответствующую функцию преобразования для выражения даты и выражения числа цены внутри шаблона, т.е.${date.toLocaleDateString('zh-CN')}а также${ '¥' + price}.一次调用差别不大,两次、三次调用的情况下,带标签的模板明显胜出。不仅符合 DRY(Don't Repeat Yourself)原则,也可以让模板代码更加简洁易读。

Помимо строки шаблона

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

tag`template literals`

И в спецификации ES6 нет ничего, что можно было бы здесь использовать.tagфункция делает любое ограничение, то естьлюбая функцияможно добавить в начало шаблона как тег, что означает эту функцию:

  • Может быть немедленно возвращена функция синхронизации, она может быть асинхроннойasyncфункция (в рамках функции поддержкиawaitАсинхронный оператор и возврат Promise)
  • Может быть функцией, возвращающей строку, или функцией, возвращающей любое значение, например число, массив, объект и т. д.
  • Может быть чистой функцией или нечистой функцией с побочными эффектами

Итак, если вы хотите, A: вы можете поставитьПроизвольный оператор JavaScriptПоместите его в функцию метки; B: вы можете позволить функции метки вернутьсялюбое значениевывод в виде шаблона. С такими мощными возможностями расширения неудивительно, что имя спецификации шаблона в стандарте ES6 в началеTemplate Strings, а позднее официальное название было изменено наTemplate Literals, потому что его возможности вышли за рамки шаблонных строк, чтобы преследовать поэзию и дистанцию.

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

Вариант использования 1: ИспользованиеString.rawсохранить исходную строку

String.rawДобавлено в спецификацию ES2015.StringСтатический метод-член объекта обычно не вызывается напрямую как функция, а используется как литеральный тег шаблона, который поставляется со стандартом языка для сохранения исходного значения содержимого шаблона.

Его эффект такой же, как и в языке Python, добавление кавычек перед строковым выражением.rЭффект префикса аналогичен. JavaScript нуждается в этой функции, просто используетсяString.rawпонял это.

var a = String.raw`\n\n`
var b === '\n\n'
// a === b -> false
// a.length === 4 -> true
// b.length === 2 -> true

String.rawМетки могут избавить нас от утомительной работы в некоторых сценариях. Одним из типичных сценариев является то, что в реальной разработке мы часто сталкиваемся с ситуацией передачи данных протокола между разными языками программирования через текст JSON."(свойства JSON необходимо заключать в кавычки) текстовое содержимое, легко вызвать ошибки синтаксического анализа JSON из-за неправильной обработки деталей.

И я столкнулся с таким реальным случаем, то есть, когда Android-терминал передает JSON-данные в JavaScript, в данных есть никнейм пользователя, который содержит"персонаж. Текст строки JSON, полученный JavaScript:

{"nickname":"枪锅&[{锅}]\"锅\":锅","foo":"bar"}

Но вот если вы прямо назначите контент с кавычками наJSON.parse('{"nickname":"枪锅&[{锅}]\"锅\":锅","foo":"bar"}')столкнетсяSyntaxError: Unexpected token 锅 in JSON at position 22ошибка, потому что одинарная кавычка\используется как escape-символ, не зарезервированный вinputв значении. Чтобы получить правильный объект JSON, используйте String.raw для его обработки:

JSON.parse(String.raw`{"nickname":"枪锅&[{锅}]\"锅\":锅","foo":"bar"}`)
// { nickname: '枪锅&[{锅}]"锅":锅', foo: 'bar' }

Вариант использования 2: из шаблона тега в строку HTML

Говоря о сравнении шаблонов ES6 и механизмов шаблонов, я упомянул, что механизм шаблонов экранирует небезопасные символы, вручную экранируя шаблоны HTML. Теперь, когда мы понимаем шаблоны тегов, мы можем поместить внешнюю логику escapeHTML непосредственно в функцию тега, чтобы нам не нужно было вызывать функцию escapeHTML перед каждым выражением вставки в шаблон.

const safeHTML = (strings, ...rest) => {
    const entityMap = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;',
        '/': '&#x2F;',
        '`': '&#x60;',
        '=': '&#x3D;'
	}
    const escapeHTML = string => String(string).replace(/[&<>"'`=\/]/g, (s) => entityMap[s]);
    return strings.reduce((total, current, idx) => {
	    const value = rest[idx] || ''
		return total + current + escapeHTML(value)
    }, '');
}

const evilText = '<script>alert(document.cookie)</script>'
safeHTML`${evilText}`
// "&lt;script&gt;alert(document.cookie)&lt;&#x2F;script&gt;"

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

Как вы, должно быть, догадались, должна быть готовая библиотека npm для общих тегов шаблонов, таких как HTML-шаблоны. Вот так,common-tagsБиблиотека — это библиотека, которую мы хотим.common-tagsЭто небольшая, но сложная библиотека тегов шаблонов, на которую опираются многие крупные проекты, включая Angular, Slack, Ember и т. д. Он содержит более дюжины часто используемых функций для обработки строковых шаблонов, таких какhtml, safeHTmlПодождите, давайте поленимся и сделаем меньше колес.

const safeHtml = require('common-tags/lib/safeHtml')
const evilText = '<script>alert(document.cookie)</script>'
safeHtml`<div>${evilText}</div>`

common-tagsТакже предоставляется API расширения для создания тегов, упрощающих реализацию настроек.

Вариант использования 3: от тегов шаблона к элементам DOM

common-tagsКарри содержитhtmlа такжеsafeHtmТеги шаблона по-прежнему являются функциями, возвращающими строки. Это означает, что если мы используем его на стороне браузера, мы получаем значение шаблонаoutputСтрока, которую еще предстоит использоватьelement.innerHTML = outputТолько после этого содержимое шаблона может быть отображено в элементе DOM и отображено в интерфейсе.

Однако, поскольку функция метки литерала шаблона может возвращать любое значение, мы могли бы пойти дальше и прямоelement.innerHTML = outputОператор также помещается в функцию метки с элементом в качестве возвращаемого значения. Таким образом, мы можем напрямую использовать значение литерала шаблона в качестве реального элемента DOM и манипулировать его возвращаемым значением непосредственно с помощью DOM API.

Неудивительно, конечно, что некоторые люди уже думали об этой идее.@choojs/nanohtmlэто сделать это.choojsэто очень молодой интерфейсный фреймворк (опять же), но мы не будем его сегодня обсуждать, просто посмотрим, что он содержитnanohtml. Основная идея nanohtml может быть использована для демонстрации Hello World:

var nanohtml = require('nanohtml')
var element = nanohtml`<div>Hello World!</div>`
document.body.appendChild(element)

В дополнение к возврату элемента DOM, как показано в коде, nanohtml также поддерживает вставку любого стандартного элемента DOM в выражение интерполяции в шаблоне.Вставленный элемент будет отображаться в соответствии с разметкой шаблона как дочерний элемент элемента возвращаемого значения.

var nanohtml = require('nanohtml')
var h3 = document.createElement('h3')
h3.textContent = 'Hello World'
var element = nanohtml`<div>${h3}</div>`
document.body.appendChild(element)

Вариант использования 4: асинхронные операции

В сочетании с ES2017async awaitфункцию, мы также можем определить функцию метки типа async и вызвать асинхронные операции в функции для достижения.

Например, реализованный выше тип дуракаl10ntag, мы можем сделать его более глупым и перевести английское предложение, которое шаблон в итоге соединит, на местный язык, а затем вывести его. Процесс перевода может быть достигнут путем асинхронного вызова сторонних API перевода, таких как Google Translate API. Итак, у нас есть этот псевдокод:

const l10n = async (strings, ...rest) => {
    return strings.reduce((total, current, idx) => {
        const arg = rest[idx]
        let insertValue = ''
        if (typeof arg === 'number') {
            insertValue = `¥${arg}`
        } else if (arg instanceof Date) {
            insertValue = arg.toLocaleDateString('zh-CN')
        } else if (arg !== undefined) {
            insertValue = arg
        }
        const line = total + current + insertValue
        const language = navigator.language // "zh-CN"
        // 假装 TRANSLATE_SERVICE 是一个可用的翻译服务
        const translated = await TRANSLATE_SERVICE.translate(line, { language })
        return translated
    }, '')
}

l10n`I bought a ${'G-Shock'} watch on ${new Date()}, it cost me ${1000}`.then(console.log)
// "我在 2018/5/16 买了一个 G-Shock 手表,花了我 1000 元"

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

const tag = (strings, ...rest) => {
    return new Promise((resolve) => {
        setTimeout(resolve, 1000, 'Hello World')
    })
}

tag`Anything`.then(console.log)
// 1s 后 console 将输出:
// "Hello World"

Вариант использования 5: DSL

DSL (предметно-ориентированный язык) — очень блефовая концепция.Как следует из названия, так называемый DSL относится к языку, который не решает проблему в конкретной предметной области. В DSL есть правила, которые ограничены определенными условиями — грамматикой, поэтому его можно назвать языком. Обычно DSL используются в области программирования, а DSL обрабатываются компьютерными программами, а некоторые мощные языки DSL также считаются мини-языками программирования.

Типичные DSL:

  • регулярное выражение
  • Язык запросов к базе данных (SQL)
  • Правила селектора CSS также являются DSL
  • Швейцарский армейский нож обработки текста awk, sed также считается DSL из-за его сложных правил использования.

Разумное использование шаблонов тегов ES6 может упростить обработку встроенных DSL в JavaScript. Строго говоря, наш вариант использования 2 и вариант использования 3 выше парыhtmlТеги шаблона класса, даже в рамках DSL. Вот несколько типичных случаев:

Примечание. Следующие теги шаблона предназначены только для описания и должны быть реализованы самостоятельно.

Случай 1: селекторы DOM

Например, мы можем реализовать селектор DOM с такими тегами, как:

var elements = query`.${className}` // the new way

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

Случай 2: сценарий оболочки

В среде Node.js мы также можем реализоватьshМетки используются для описания вызовов сценариев оболочки:

var proc = sh`ps aux | grep ${pid}`

Когда мы увидим эту строку оператора, мы подсознательно подумаем, что API здесь вызовет команду, склеенную шаблоном выполнения оболочки, а proc должен быть результатом или выводом выполнения команды.

Случай 3: конструктор регулярных выражений

кreТег реализует конструктор динамических регулярных выражений. Регулярное выражение такого типа, сгенерированное во время выполнения, обычно требует определения собственной функции и вызова новой реализации RegExp.

var match = input.match(re`\d+${separator}\d+`)

Случай 4: интернационализация и локализация

можно добиться такогоi18nа такжеl10nТеги шаблона: интерполированные выражения в строках шаблона${expression}После этого с:typeФормат определяет формат отображения текста, ожидаемый выражением выражения для реализации пользовательской функции вывода шаблона.

var message = l10n`Hello ${name}; you are visitor number ${visitor}:n!
You have ${money}:c in your account!`;

здесьl10nТеги увеличены по сравнению с нашей жестко запрограммированной версией выше:typeУказывает тип идентификатора, например,:nпредставлять числа,:cпредставляет валюту. Правила для этих идентификаторов типов можно найти вl10nсоглашения в коде реализации. и этосоглашениеЭто означает что-то вроде самоопределяющегося DSL.

Общим для четырех вышеописанных случаев является то, что мы сначала согласовали интерфейсы API с похожими шаблонами, которые все представлены в виде шаблонов с тегами — имя шаблона, за которым следует содержимое шаблона.

Хотя мы, как разработчики, знаем, что на самом деле, когда вызывается шаблон тега, он по существу реструктурирует содержимое шаблона как(strings, ...rest)Затем форма передается в вызов функции метки. Но такой вызов API выглядит так, как будто есть только одна функция и один параметр, и люди могут с первого взгляда догадаться о назначении API.

Хороший API должен иметь хорошийописательный, инкапсулировать сложные детали реализации и попытатьсяСосредоточьтесь на том, чтобы хорошо делать одно дело. С этой точки зрения шаблоны ES6 с тегами очень подходят для работы со встроенным DSL JS и даже помогают нам реализовать мини-DSL в конкретной бизнес-логике.

больше для изучения

Вышеизложенное представляет собой введение в синтаксис шаблона ES6 и его практическую ценность. Когда дело доходит до практики, благодаря простоте ее принципов мы можем сразу же воспользоваться ее преимуществами. В среде Node.js мы, без сомнения, можем использовать его сразу же без колебаний; в среде браузера его можно преобразовать в совместимый код ES5 с помощью нашего старого друга Babel.

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

За исключением того, что мы кратко упомянули в предыдущем примереcommon-tagsа такжеnano-htmlДля этих двух библиотек также существует множество библиотек тегов, которые реализуют функции в определенных областях, таких как связанные с SQL, связанные с интернационализацией и локализацией.Вы можете найти колеса, сделанные другими, выполнив поиск в npm с ключевыми словами, помеченными литералами шаблонов.

Тем не менее, по сравнению с другими темами, исследование, которому сообщество уделяет наибольшее внимание, по-прежнему связано с комбинацией литералов шаблонов и шаблонов HTML. Виртуальный DOM.Быстрая схема рендеринга.

  • hyperHTMLРепозиторий, который призван стать альтернативой Virtual DOM. Это четко указано в официальной документации. Основная концепция заключается в использовании шаблонов ES6 в качестве альтернативы Virtual DOM.
  • lit-htmlБиблиотека от команды Google Polymer, похожая по концепции на hyperHTML, объединяющая шаблоны ES6 и HTML.<template>Преимущества элементов, обеспечивающих быструю визуализацию и обновление элементов DOM.
  • choojs – это современный фреймворк для разработки интерфейса, вес которого после minify+gzip составляет всего 4 КБ. В отличие от hyperHTML и lit-html, это более полнофункциональный фреймворк. В настоящее время (май 2018 г.) количество звездочек больше, чем у двух предыдущих.

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

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

Эта статья была опубликована одновременно вSegmentFaultа такжеличный блог