Это интервью было проведено Олегом Подсечиным с Райаном Далом (Ryan Dahl) 8 июля 2010 г., вскоре после чтений Райана в Кельне. Олег — энтузиаст JavaScript, который управляет Ionsquare Ltd, специализирующейся в области ИТ-консалтинга.
О.П.: Первый вопрос на самом деле вводный. Как вы пришли к Node.JS? Был ли у вас раньше опыт работы с JavaScript? Когда вы начали работать с использованием JavaScript? А также с событийно-управляемым программным обеспечением?
РД: Я работал по контракту, и делал различные маленькие проекты на C, как правило, серверное событийно-управляемое программное обеспечение, и я понял, что пишу один и тот же код снова и снова. С — великолепный язык для работы, но я хотел что-то, позволяющее писать скрипты в том же стиле, в котором я обычно программирую серверное ПО.
О. П.: Делали ли что-нибудь для клиентской стороны с использованием JavaScript?
RD: Немного. Я много работал с Ruby on Rails — так что я часто имел дело с фронтэндом. Тогда я написал небольшой веб-сервер на Ruby под названием Ebb, который должен был быть быстрее Mongrel. Этот код стал отправной точкой для Node.
О.П.: Ebb в основном написан на C? Таким образом, вы сперва написали его на Ruby, потом переписали на C, и теперь вы, в конечном итоге, переписали его на JavaScript?
РД: Верно. Так что изначально был Ruby, затем С. Какое-то время я игрался с идеей иметь небольшую C-библиотеку для создания web-серверов, — но на языке C трудно выполнить что-нибудь такое. В один прекрасный день на меня снизошло прозрение: «JavaScript, — это именно тот язык, который подходит для этого применения». Это произошло вскоре после того, как был выпущен V8.
О.П.: Вы сказали, что есть два языка, которые всегда будут вокруг нас: С и JavaScript. Итак, что вы думаете о JavaScript, как языке программирования общего предназначения?
РД: JavaScript имеет определённые характеристики, которые делают его весьма отличным от других динамических языков, а именно, что он понятия не имеет о потоках выполнения (threads). Его модель параллелизма полностью основана на событиях. Это делает его несколько иным, чем иные динамические языки программирования общего назначения, такие, как Ruby и Python. По крайней мере для определенных классов задач я обнаружил, что на JavaScript гораздо легче программировать, например, при написании IRC-сервера.
О. П.: Каким Вы видите будущее JavaScript? Считаете ли вы, что JavaScript становится все более распространенным, и не только на серверах, но и на настольных компьютерах?
РД: JavaScript уже делает громадную работу, формируя графические интерфейсы. Я думаю, при наличии знакомого браузер-подобного API, JavaScript также может стать хорошим языком для настольных приложений.
О. П.: JavaScript слабо структурирован, так что люди просто копируют и вставляют код JavaScript…
РД: Да, отсутствие инфраструктуры модулей мешает. JavaScript действительно заставляет людей держать всё в глобальных переменных. Это настоящая беда для JavaScript, но, в конце концов, лучшие практики позволяют преодолеть такого рода проблемы.
О.П.: Да, вы наблюдаете за дискуссией относительно ECMAScript 4 и ECMAScript 5?
РД: Я солидарен с мнением Крокфорда, что язык должен быть простым. Одно из лучших качеств в JavaScript, — его простота. Он определяет не так много концепций о том, как делать те или иные вещи, — в частности, касательно ввода/вывода. Хотя спецификация ECMAScript 4 не определяет никакие API ввода/вывода, она определяет многое другое. Она определила множество важнейших изменений. Тем не менее, я хотел бы, чтобы ECMAScript 5 имел еще несколько возможностей.
О. П.: Какие именно возможности вы имеете ввиду?
RD: Как это называется? Разрушительное присвоение? Если у вас есть массив справа и список переменных слева, и они могут быть определены таким образом. Это было бы хорошо.
О.П.: Это включено в Rhino, но не в V8.
О. П.: Так, давайте перейдем к Node. Какое архитектурное решением стало самым сложным из тех, что вы сделали по отношению к проекту?
РД: То, что оказалось самым тяжелым для меня… Моя первоначальная идея заключалась в том, что это будет чисто неблокирующая система, и мне пришлось отказался от неё во многом, в системе модулей и в некоторых других областях. В браузерах загрузка JavaScript через тег script является неблокирующей операцией. Вы действительно не знаете, когда скрипты полностью выполнены, до тех пор, пока не будет вызван OnLoad. Первоначально Node работал аналогично. Вы могли загрузить кучу файлов модулей, и вы не знали, что они уже полностью интерпретированы, пока не было сгенерировано событие loaded. Это сделало все немного сложнее. Вы не могли просто выполнить «require» и начать использовать тот код прямо после этой операции, нужно было ждать обратного вызова, прежде чем начать использовать загруженный код.
О.П.: Приложение «Привет, мир!» имело еще один отступ.
РД: Верно.
О.П.: Но это забавно, потому что люди говорят, что одним из преимуществ, предлагаемых JavaScript, является то, что вы можете использовать его везде также, как в браузере. Вы можете использовать ту же логику валидации данных, что на сервере, что в браузере, но спецификация модулей CommonJS не работает в браузере, так что существуют попытки создать библиотеки с асинхронной загрузкой модулей.
РД: Да, поэтому с точки зрения сложности выбора архитектурных решений, я хотел, чтобы Node был похож на среду браузера. Может быть, он не использует те же методы, но те же структуры легко могут быть портированы, если создать методы с аналогичными именами. Первоначально Node добился того, что был совершенно браузер-подобным. В первых версиях он даже определял объект «window». С течением времени я удалил этот API, так как выяснилось, что не нужно, чтобы серверное окружение было точно таким же, как браузерное. Так что я выбрал систему модулей CommonJS, которая является весьма разумной; Ребята из группы CommonJS много внимания уделили системе модулей, и я действительно не хотел уделять слишком много времени на продумывание своего варианта. Так что да, require является блокирующей операцией, и есть некоторые другие мелкие операции, которые используют блокировку в Node. Вообще этот прагматический подход, — выполнять неблокирующие операции 99% времени, но позволять несколько синхронных операций, работает хорошо. То, что Вы загружаете модули синхронно, вероятно, не имеет значения для серверной программы.
О.П.: Первый вопрос на самом деле вводный. Как вы пришли к Node.JS? Был ли у вас раньше опыт работы с JavaScript? Когда вы начали работать с использованием JavaScript? А также с событийно-управляемым программным обеспечением?
РД: Я работал по контракту, и делал различные маленькие проекты на C, как правило, серверное событийно-управляемое программное обеспечение, и я понял, что пишу один и тот же код снова и снова. С — великолепный язык для работы, но я хотел что-то, позволяющее писать скрипты в том же стиле, в котором я обычно программирую серверное ПО.
О. П.: Делали ли что-нибудь для клиентской стороны с использованием JavaScript?
RD: Немного. Я много работал с Ruby on Rails — так что я часто имел дело с фронтэндом. Тогда я написал небольшой веб-сервер на Ruby под названием Ebb, который должен был быть быстрее Mongrel. Этот код стал отправной точкой для Node.
О.П.: Ebb в основном написан на C? Таким образом, вы сперва написали его на Ruby, потом переписали на C, и теперь вы, в конечном итоге, переписали его на JavaScript?
РД: Верно. Так что изначально был Ruby, затем С. Какое-то время я игрался с идеей иметь небольшую C-библиотеку для создания web-серверов, — но на языке C трудно выполнить что-нибудь такое. В один прекрасный день на меня снизошло прозрение: «JavaScript, — это именно тот язык, который подходит для этого применения». Это произошло вскоре после того, как был выпущен V8.
О.П.: Вы сказали, что есть два языка, которые всегда будут вокруг нас: С и JavaScript. Итак, что вы думаете о JavaScript, как языке программирования общего предназначения?
РД: JavaScript имеет определённые характеристики, которые делают его весьма отличным от других динамических языков, а именно, что он понятия не имеет о потоках выполнения (threads). Его модель параллелизма полностью основана на событиях. Это делает его несколько иным, чем иные динамические языки программирования общего назначения, такие, как Ruby и Python. По крайней мере для определенных классов задач я обнаружил, что на JavaScript гораздо легче программировать, например, при написании IRC-сервера.
О. П.: Каким Вы видите будущее JavaScript? Считаете ли вы, что JavaScript становится все более распространенным, и не только на серверах, но и на настольных компьютерах?
РД: JavaScript уже делает громадную работу, формируя графические интерфейсы. Я думаю, при наличии знакомого браузер-подобного API, JavaScript также может стать хорошим языком для настольных приложений.
О. П.: JavaScript слабо структурирован, так что люди просто копируют и вставляют код JavaScript…
РД: Да, отсутствие инфраструктуры модулей мешает. JavaScript действительно заставляет людей держать всё в глобальных переменных. Это настоящая беда для JavaScript, но, в конце концов, лучшие практики позволяют преодолеть такого рода проблемы.
О.П.: Да, вы наблюдаете за дискуссией относительно ECMAScript 4 и ECMAScript 5?
РД: Я солидарен с мнением Крокфорда, что язык должен быть простым. Одно из лучших качеств в JavaScript, — его простота. Он определяет не так много концепций о том, как делать те или иные вещи, — в частности, касательно ввода/вывода. Хотя спецификация ECMAScript 4 не определяет никакие API ввода/вывода, она определяет многое другое. Она определила множество важнейших изменений. Тем не менее, я хотел бы, чтобы ECMAScript 5 имел еще несколько возможностей.
О. П.: Какие именно возможности вы имеете ввиду?
RD: Как это называется? Разрушительное присвоение? Если у вас есть массив справа и список переменных слева, и они могут быть определены таким образом. Это было бы хорошо.
О.П.: Это включено в Rhino, но не в V8.
О. П.: Так, давайте перейдем к Node. Какое архитектурное решением стало самым сложным из тех, что вы сделали по отношению к проекту?
РД: То, что оказалось самым тяжелым для меня… Моя первоначальная идея заключалась в том, что это будет чисто неблокирующая система, и мне пришлось отказался от неё во многом, в системе модулей и в некоторых других областях. В браузерах загрузка JavaScript через тег script является неблокирующей операцией. Вы действительно не знаете, когда скрипты полностью выполнены, до тех пор, пока не будет вызван OnLoad. Первоначально Node работал аналогично. Вы могли загрузить кучу файлов модулей, и вы не знали, что они уже полностью интерпретированы, пока не было сгенерировано событие loaded. Это сделало все немного сложнее. Вы не могли просто выполнить «require» и начать использовать тот код прямо после этой операции, нужно было ждать обратного вызова, прежде чем начать использовать загруженный код.
О.П.: Приложение «Привет, мир!» имело еще один отступ.
РД: Верно.
О.П.: Но это забавно, потому что люди говорят, что одним из преимуществ, предлагаемых JavaScript, является то, что вы можете использовать его везде также, как в браузере. Вы можете использовать ту же логику валидации данных, что на сервере, что в браузере, но спецификация модулей CommonJS не работает в браузере, так что существуют попытки создать библиотеки с асинхронной загрузкой модулей.
РД: Да, поэтому с точки зрения сложности выбора архитектурных решений, я хотел, чтобы Node был похож на среду браузера. Может быть, он не использует те же методы, но те же структуры легко могут быть портированы, если создать методы с аналогичными именами. Первоначально Node добился того, что был совершенно браузер-подобным. В первых версиях он даже определял объект «window». С течением времени я удалил этот API, так как выяснилось, что не нужно, чтобы серверное окружение было точно таким же, как браузерное. Так что я выбрал систему модулей CommonJS, которая является весьма разумной; Ребята из группы CommonJS много внимания уделили системе модулей, и я действительно не хотел уделять слишком много времени на продумывание своего варианта. Так что да, require является блокирующей операцией, и есть некоторые другие мелкие операции, которые используют блокировку в Node. Вообще этот прагматический подход, — выполнять неблокирующие операции 99% времени, но позволять несколько синхронных операций, работает хорошо. То, что Вы загружаете модули синхронно, вероятно, не имеет значения для серверной программы.