Статьи

Введение в ClojureScript

Эта статья была рецензирована Томасом Греко и Джереми Хелайн . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Уже через несколько месяцев все больше и больше разработчиков придерживаются философии «всегда делайте ставки на JavaScript». Тем не менее, количество языков, которые компилируются в JavaScript, растет. Некоторыми примерами таких языков являются Dart, TypeScript, CoffeeScript и ClojureScript.

В этой статье мы обсудим ClojureScript, новый компилятор для Clojure , предназначенный для JavaScript. Мы рассмотрим преимущества работы с ClojureScript и как вы можете быстро настроить его для использования npm и ваших любимых библиотек Node.js.

Почему ClojureScript?

В Интернете есть много статей, объясняющих преимущества ClojureScript. Некоторые агрегированные точки высокого уровня:

  • Простота . Что касается синтаксиса, ClojureScript — это язык на основе Lisp, который дает ему минимальный синтаксис. Это настолько минимально, что мы сможем рассказать об этом в этой статье. В дополнение к простому синтаксису ClojureScript также предлагает инструменты, которые помогают упростить асинхронный код.
  • Безопасность : это означает меньше ошибок! ClojureScript и другие функциональные языки программирования имеют много свойств, которые помогают уменьшить и уменьшить распространенные ошибки.
  • Производительность : ClojureScript использует Google Closure Compiler . Это позволяет ClojureScript использовать удаление мертвого кода и другие функции.
  • Живое кодирование : экосистема ClojureScript предоставляет множество инструментов для «живого кодирования». Это означает, что после изменения кода он сразу же отражается в вашем живом проекте. В этой статье мы рассмотрим Figwheel, чтобы вы могли лучше понять концепцию.
  • Повторное использование кода : ClojureScript может выполняться универсально или, как говорят многие, «изоморфно». Это означает, что вы можете запускать один и тот же код на своем клиенте и сервере. Это стало популярным паттерном в экосистеме Node.js. Кроме того, ClojureScript может импортировать библиотеки из экосистем Node.js и Java.

Настройка цепочки инструментов Clojure (Script)

В этой статье мы будем устанавливать цепочку инструментов в среде Mac OSX. В вики ClojureScript есть руководства по установке в других средах, если они вам нужны. Нам понадобится несколько системных зависимостей, чтобы начать. Одним из них является Homebrew , популярный менеджер пакетов OSX.

Установка последней версии Java

Для ClojureScript требуется последняя версия Java (версия 8 на момент написания этой статьи). Если в любое время во время этих упражнений вы встретите ошибку при запуске lein которая выглядит следующим образом:

 Exception in thread "main" java.util.regex.PatternSyntaxException: Unknown inline modifier near index 2 (?U)^[\p{Alpha}_$]^, compiling:(cljs/util.clj:158:33) 

Тогда вам нужна последняя версия Java.

Для запуска выполните следующие команды в интерфейсе командной строки:

 brew tap caskroom/cask brew install brew-cask 

Если вы получили ошибку «уже установлена», следуйте инструкциям, чтобы отсоединить ее, которая появится в вашем скрипте. После этого установите его снова. Это можно сделать с помощью следующих команд:

 brew unlink brew-cask brew install brew-cask 

На этом этапе выполните последнюю команду, которая нам нужна:

 brew cask install java 

Установка Лейнингена

Leiningen — это инструмент для сборки проектов Clojure. Мы будем использовать его для запуска кода ClojureScript и установки зависимостей. Этот шаг предполагает, что Homebrew установлен, давая нам команду brew .

 brew install leiningen 

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

Использование Repl

Теперь, когда у нас установлен Leningen, мы можем начать знакомство с синтаксисом ClojureScript.

lein repl команду lein repl , вы должны получить похожий вывод:

 $ lein repl nREPL server started on port 58371 on host 127.0.0.1 - nrepl://127.0.0.1:58371 REPL-y 0.3.7, nREPL 0.2.10 Clojure 1.7.0 Java HotSpot(TM) 64-Bit Server VM 1.6.0_65-b14-466.1-11M4716 Docs: (doc function-name-here) (find-doc "part-of-name-here") Source: (source function-name-here) Javadoc: (javadoc java-object-or-class-here) Exit: Control+D or (exit) or (quit) Results: Stored in vars *1, *2, *3, an exception in *e user=> 

Мы сейчас в Repl ClojureScript. Это позволяет нам быстро выполнить ClojureScript и просмотреть результат. Чтобы выйти из реплея вы можете нажать Control+D

Выполнив этот шаг, мы теперь готовы углубиться в синтаксис ClojureScript и повеселиться!

Синтаксис ClojureScript

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

Примитивы

ClojureScript имеет следующие примитивные типы:

  • номер
     user=> 1.23 1.23 
  • строка
     user=> "foo" "foo" 
  • Вектор (массив)
     user=> [:bar 3.14 "hello"] [:bar 3.14 "hello"] 
  • Карта (ассоциативные массивы)
     user=> {:msg "hello" :pi 3.14 :primes [2 3 5 7 11 13]} {:msg "hello", :pi 3.14, :primes [2 3 5 7 11 13]} 
  • Ключевое слово (используется для доступа к картам)
     user=> :foo :foo 
  • Set (отдельный массив)
     user=> #{:bar 3.14 "hello"} #{"hello" 3.14 :bar} 

Функции полностью вниз

Функции являются строительными блоками ClojureScript. Вы даже определяете свои собственные функции, используя встроенную функцию defn .

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

 user=> (defn myfunction [argument1] argment1) 

В случае, если синтаксис выглядит немного странным для вас, это эквивалентно в Javascript:

 function myfunction(argument1){ return argument1; } 

Функции вызываются заключением их имени и аргументов в круглые скобки:

 user=> (myfunction "hello world") "hello world" 

В нефункциональных языках программирования есть специальные «операторы» или ключевые слова. В Javascript некоторые часто используемые операторы + - == if . В ClojureScript и других языках на основе Lisp специальных операторов нет. Это просто обычные функции.

Если операторы являются функциями:

 user=> (if true "do true stuff here" "do false stuff here") "do true stuff here" 

Математические операторы тоже являются функциями, как показано ниже:

 user=> (+ 2 3) 5 user=> (* 2 3) 6 

Чтобы увидеть больше примеров синонимов Javascript и ClojureScript, посетите этот веб-сайт .

Создание Node.js — ClojureScript Project

Начать проект ClojureScript очень просто. Leningen предлагает шаблоны проектов, которые помогут вам начать работу с типичным проектом.

Шаблоны — это отличный ресурс, с которым можно поиграться и увидеть другие варианты использования и конфигурации для проектов ClojureScript. Clojars.org имеет коллекцию шаблонов, и другие можно найти в Интернете. Для нашего проекта мы будем использовать шаблон проекта Nodejs Figwheel .

Для запуска выполните следующую команду в интерфейсе командной строки:

 $ lein new figwheel-node hello-world 

Это создает новый проект ClojureScript в каталоге ./hello-world . В оставшейся части статьи предполагается, что в качестве имени проекта был использован hello-world . Если вы хотите, вы можете использовать другое имя, но я бы посоветовал вам придерживаться его, чтобы вы могли следить за статьей, не опасаясь, что что-то пойдет не так.

После этого перейдите в созданный каталог и установите зависимости npm:

 $ cd hello-world $ npm install 

Точки интереса

Папка проекта содержит несколько файлов. В этом разделе я хочу выделить некоторые важные понятия о них:

  • package.json : это должно быть знакомо по проектам Node.js. Наши зависимости от npm будут добавлены здесь.
  • project.clj : Этот файл является файлом конфигурации проекта ClojureScript. Это версия package.json от ClojureScript, где мы настраиваем зависимости Clojure и цели компиляции. Этот файл также содержит детали проекта, такие как заголовок и описание.
  • figwheel.js : Этот файл относится только к проектам Figweel. Это файл начальной загрузки для нашего проекта. Он указывает Figwheel на наш исходный код, чтобы он мог следить за обновлениями. Мы node figwheel.js его с node figwheel.js .
  • ./src/hello-world/core.cljs : это исходный файл нашей точки входа. Здесь мы начнем проект. index.js что это похоже на файл index.js в проекте Node.js.

Файл core.cljs содержит следующее содержимое. Я добавил комментарии к нему, чтобы вы могли понять, что происходит:

 ;; This defines a namespace and necesscary dependencies for the current file (ns hello-world.core (:require [cljs.nodejs :as nodejs])) ;; This updates the default println method to write to Node.js stdout (nodejs/enable-util-print!) ;; The main function of the module ;; it prints "Hello World!" to stdout (defn -main [] (println "Hello world!")) ;; *main-cli-fn* is a semi-magic var that's used to set the entry ;; *point for a node app (set! *main-cli-fn* -main) 

Запуск проекта

Чтобы выполнить текущий проект, откройте окно терминала и перейдите в наш каталог проектов hello-world. Затем выполните следующее:

 lein figwheel 

Это запустит Figwheel в ожидании обновлений для сборки. Оставьте этот терминал включенным и откройте отдельный терминал. В этом новом терминале снова перейдите в каталог проекта и выполните команду:

 node figwheel.js 

Вы должны увидеть вывод «Hello world», как показано ниже:

 $ node figwheel.js Hello world! Figwheel: trying to open cljs reload socket Figwheel: socket connection established 

Использование Express.js для веб-сервера

Теперь, когда у нас есть основа настройки проекта ClojureScript, давайте начнем работать с некоторыми знакомыми библиотеками в новом терминале. В нашем hello_world выполните команду:

 npm install --save express 

Затем нам нужно обновить ./src/hello-world/core.cljs следующим образом:

 (ns hello-world.core (:require [cljs.nodejs :as nodejs] [clojure.string :as string])) (nodejs/enable-util-print!) (defonce express (nodejs/require "express")) (defonce http (nodejs/require "http")) (defonce server-port 3000) (def app (express)) (. app (get "/hello" (fn [req res] (. res (send "Hello world"))))) (def -main (fn [] (doto (.createServer http #(app %1 %2)) (.listen server-port)))) (.listen server)))) (println (string/join " " ["Server running on" server-port]) ) (set! *main-cli-fn* -main) 

Теперь, когда вы запустите на проекте node figwheel.js , вы должны увидеть вывод, который running on 3000 . Если вы посетите URL http: // localhost: 3000 / hello , вы должны увидеть результат экспресс-маршрута с надписью «Hello world».

Выводы

В этой статье мы обсудили, как настроить новый проект ClojureScript и установить в нем популярную зависимость Node. Это дает нам отличную базу для знакомства с ClojureScript как языком. Я также собрал исходный код для этого проекта, который вы можете найти на Github . Это выходит за рамки этой статьи и демонстрирует, как интегрировать рендеринг на стороне сервера React.