содержание
- Введение в Вавилон
- Как работает Бабель
- Разбор АСТ
- Трансформация АСТ
- Написать плагин Babel
Введение в Вавилон
Babel — это компилятор JavaScript, который может компилировать языки, которые не распознаются младшими браузерами, такими как es2015, и реагировать.
В коде слева на рисунке выше есть стрелочная функция, и Babel преобразует исходный код.Давайте посмотрим на принцип работы Babel.
Как работает Бабель
Три основных этапа обработки в Babel:
Разбирать, преобразовывать, генерировать.
Процесс декомпозиции описывается на языке следующим образом:
Разобрать
Используйте синтаксический анализатор babylon для анализа входной строки исходного кода и создания начального AST (File.prototype.parse)
Используйте независимый пакет babel-traverse для обхода AST, анализа пути всего дерева и считывания соответствующей метаинформации через смонтированный метаданныеVisitor.Этот шаг называется процессом установки AST.
конвертировать
Процесс преобразования: пройдитесь по дереву AST и примените каждый преобразователь (плагин) для создания преобразованного дерева AST.
Ядром babel является babel-core, который предоставляет интерфейс babel.transform.
let result = babel.transform(code, {
plugins: [
arrayPlugin
]
})
генерировать
Используйте Babel-генератор для вывода дерева AST в виде перекодированной строки кода.
Разбор АСТ
Синтаксический анализ AST будет выполнять обход дерева по полученной грамматике, а также изменять и преобразовывать каждый узел грамматики для создания новой строки кода.
узел
AST преобразует стрелочную функцию, упомянутую в начале, в дерево узлов в соответствии с узлом.
Стрелочные функции ES2015
codes.map(code=>{
return code.toUpperCase()
})
map+стрелочная функция+возврат буквы в верхнем регистре Кажется, что это очень простая функция, а соответствующее абстрактное синтаксическое дерево (AST) обычно более сложное, особенно для некоторых сложных программ. Вместо того, чтобы пытаться самостоятельно анализировать абстрактное синтаксическое дерево (AST), мы можем сделать это с помощьюastexplorer.netВы можете увидеть AST, полученный разными парсерами после разбора js-кода онлайн, сайт помогает нам завершить преобразование, он позволяет нам ввести код JavaScript слева, а справа появится доступное для просмотра абстрактное синтаксическое дерево (AST). Мы можем использовать этот инструмент. Помогите понять и поэкспериментировать с некоторым кодом.
JavaScript AST visualizerAST можно визуализировать онлайн.
Обход дерева AST преобразованной структуры
{
type:"ExpressionStatement",
expression:{
type:"CallExpression"
callee:{
type:"MemberExpression",
computed:false
object:{
type:"Identifier",
name:"codes"
}
property:{
type:"Identifier",
name:"map"
}
range:[]
}
arguments:{
{
type:"ArrowFunctionExpression",
id:null,
params:{
type:"Identifier",
name:"code",
range:[]
}
body:{
type:"BlockStatement"
body:{
type:"ReturnStatement",
argument:{
type:"CallExpression",
callee:{
type:"MemberExpression"
computed:false
object:{
type:"Identifier"
name:"code"
range:[]
}
property:{
type:"Identifier"
name:"toUpperCase"
}
range:[]
}
range:[]
}
}
range:[]
}
generator:false
expression:false
async:false
range:[]
}
}
}
}
Мы начинаем с ExpressionStatement и переходим к древовидной структуре и видим, что ее внутренние свойства имеют callee, тип, аргументы, поэтому мы по очереди посещаем каждое свойство и его дочерние узлы.
Итак, существует следующая последовательность
进入 ExpressionStatement
进入 CallExpression
进入 MemberExpression
进入 Identifier
离开 Identifier
进入 Identifier
离开 Identifier
离开 MemberExpression
进入 ArrowFunctionExpression
进入 Identifier
离开 Identifier
进入 BlockStatement
进入 ReturnStatement
进入 CallExpression
进入 MemberExpression
进入 Identifier
离开 Identifier
进入 Identifier
离开 Identifier
离开 MemberExpression
离开 CallExpression
离开 ReturnStatement
离开 BlockStatement
离开 ArrowFunctionExpression
离开 CallExpression
离开 ExpressionStatement
离开 Program
Все этапы преобразования Babel — это обходы, подобные этому. (что-то вроде луковой модели коа??)
Трансформация АСТ
После анализа древовидной структуры мы вручную преобразуем стрелочную функцию.
При сравнении двух изображений разница обнаруживается в arguments.type двух функций.
Разобрать код
//babel核心库,用来实现核心的转换引擎
let babel = require('babel-core');
//可以实现类型判断,生成AST节点
let types = require('babel-types');
let code = `codes.map(code=>{return code.toUpperCase()})`;//转换语句
//visitor可以对特定节点进行处理
let visitor = {
ArrowFunctionExpression(path) {//定义需要转换的节点,这里拦截箭头函数
let params = path.node.params
let blockStatement = path.node.body
//使用babel-types的functionExpression方法生成新节点
let func = types.functionExpression(null, params, blockStatement, false, false)
//替换节点
path.replaceWith(func) //
}
}
//将code转成ast
let result = babel.transform(code, {
plugins: [
{ visitor }
]
})
console.log(result.code)
Примечание: ArrowFunctionExpression() { ... } является сокращением от ArrowFunctionExpression: { enter() { ... } } .
Путь — это объект, представляющий соединение между двумя узлами.
шаг синтаксического анализа
- Определите узлы, которые необходимо преобразовать
ArrowFunctionExpression(path) {
......
}
- Создать узел для замены
types.functionExpression(null, params, blockStatement, false, false)
ссылка на документацию по типам babel
- Найдите необходимые параметры на узле узла
- заменить (заменить)
Написать плагин Babel
Начните с функции, которая принимает объект Babel в качестве параметра.
export default function(babel) {
// plugin contents
}
Затем он возвращает объект, свойство посетителя которого является основным посетителем узла для этого плагина.
export default function({ types: t }) {
return {
visitor: {
// visitor contents
}
};
};
Когда мы ежедневно внедряем зависимости, мы будем вводить весь пакет, что делает упакованный код слишком избыточным, добавляется много ненужных модулей, таких как index.js с тремя строками кода, а размер упакованного файла достигает 483 КиБ.
index.js
import { flatten, join } from "lodash";
let arr = [1, [2, 3], [4, [5]]];
let result = _.flatten(arr);
Итак, наша цель на этот раз состоит в том, чтобы
import { flatten, join } from "lodash";
Преобразовано так, что вводятся только два модуля lodash, что уменьшает размер упаковки.
import flatten from "lodash/flatten";
import join from "lodash/join";
Этапы реализации следующие:
- Создайте новую папку babel-plugin-extract в node_module под проектом
Примечание. Папка плагина babel определяется как имя плагина babel-plugin.
Мы можем добавить пользовательские плагины в плагин .babelrc или добавить пользовательские плагины в параметры загрузчика webpack.config.js.
- Создайте новый index.js в файле babel-plugin-extract.
module.exports = function ({types:t}) {
return {
// 对import转码
visitor:{
ImportDeclaration(path, _ref = { opts: {} }) {
const specifiers = path.node.specifiers;
const source = path.node.source;
// 只有libraryName满足才会转码
if (_ref.opts.library == source.value && (!t.isImportDefaultSpecifier(specifiers[0]))) { //_ref.opts是传进来的参数
var declarations = specifiers.map((specifier) => { //遍历 uniq extend flatten cloneDeep
return t.ImportDeclaration( //创建importImportDeclaration节点
[t.importDefaultSpecifier(specifier.local)],
t.StringLiteral(`${source.value}/${specifier.local.name}`)
)
})
path.replaceWithMultiple(declarations)
}
}
}
};
}
- Измените элемент конфигурации babel-loader в webpack.prod.config.js и добавьте собственное имя плагина в plugins.
rules: [{
test: /\.js$/,
loader: 'babel-loader',
options: {
presets: ["env",'stage-0'],
plugins: [
["extract", { "library":"lodash"}],
["transform-runtime", {}]
]
}
}]
Примечание. Плагины плагинов используются по порядку, а пресеты — в обратном порядке. Таким образом, приведенный выше метод выполнения: Extract>transform-runtime>stage-0>env.
- Запустите webpack.config.js с введенным пользовательским плагином.
Размер файла пакета теперь составляет 21,4 КБ, что значительно уменьшено, и пользовательский плагин работает успешно! ~
директория с файлами плагинов
YUAN-PLUGINS
|
| - node_modules
| |
| | - babel-plugins-extract
| |
| index.js
|
| - src
| | - index.js
|
| - webpack.config.js
Если вы думаете, что это весело, пожалуйста, обратите внимание ~ Добро пожаловать, чтобы собрать и написать комментарий ~~~
Объявление о вакансии
ByteDance набирает сотрудников!
Описание вакансии: Front-end development (senior) ToB направление - видео облако (База: Шанхай, Пекин)
1. Отвечает за производство мультимедийных услуг, таких как аудио и видео по запросу / прямая трансляция / общение в реальном времени и создание облачных платформ для бизнеса;
2. Отвечает за мультимедийную систему качества, эксплуатацию и техническое обслуживание, построение и развитие системы;
3. Хорошо разбирается в абстрактном дизайне, инженерном мышлении, фокусируется на взаимодействии и создает максимальный пользовательский опыт.
Профессиональные требования
1. Компьютеры, связь и электронная информатика и другие смежные специальности являются предпочтительными;
2. Владение различными фронтенд-технологиями, включая HTML/CSS/JavaScript/Node.js и т. д.;
3. Глубокое понимание языка JavaScript с использованием основных сред разработки, таких как React или Vue.js;
4. Приветствуется знание Node.js, понимание Express/KOA и других фреймворков, а также опыт разработки крупномасштабных серверных программ;
5. Иметь определенное представление о пользовательском опыте, интерактивной работе и анализе потребностей пользователей, а также иметь опыт разработки продуктов или интерфейсов;
6. Предпочтение отдается участникам со своими собственными техническими продуктами, работами с открытым исходным кодом или активным сообществом с открытым исходным кодом.
Основные моменты работы
Команда видеооблачных сервисов опирается на накопленные аудио- и видеотехнологии и базовые ресурсы Douyin, Xigua Video и других продуктов, чтобы предоставлять клиентам универсальные аудио- и видеомультимедийные услуги, включая аудио- и видеопо запросу, прямую трансляцию, реальную связь времени, обработка изображений и т. д. Внутренне, как центр видеотехнологий, он обслуживает внутренний бизнес; снаружи он создает готовые аудио- и видео-мультимедийные сервисные решения для обслуживания пользователей корпоративного уровня.
У команды есть стандартизированный процесс итерации проекта и идеальная конфигурация ролей проекта; сильная техническая атмосфера, охватывает сообщество открытого исходного кода и регулярно делится, так что каждый может быстро расти вместе с бизнесом и использовать технологии, чтобы изменить мир!
способ доставки
Резюме можно отправлять напрямую по адресу:yuanyuan.wallace@bytedance.com
Вы также можете отсканировать внутренний QR-код для доставки онлайн, с нетерпением жду вашего присоединения! ~