Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Google Summer of Code 2015

Maria Geller (Neise) edited this pageJul 24, 2015 ·3 revisions

Project information

Abstract

This Google Summer of Code Project will focus on improving the integrationof ClojureScript with the existing JavaScript ecosystem. The first part ofthis project will be to add CommonJS, AMD and ECMAScript 6 module support,meaning that JavaScript modules can be included and used in a ClojureScriptproject. An important part in solving this problem will be to get familiarwith the Google Closure Compiler as it provides the functionality to processJavaScript modules.The second part of this project will focus on generating extern files fornon-Closure compatible JavaScript libraries to simplify the use ofJavaScript libraries in a ClojureScript project.

Synopsis

This project can be split up into two parts: module support and extern generation.

Module support

Currently, it is not possible to directly include a CommonJS, AMD orECMAScript 6 JavaScript module into a ClojureScript project. To add supportfor JavaScript modules we can use functionality that is already provided bythe Google Closure Compiler. The Google Closure Compiler offers thefunctionality to transform CommonJS and ECMAScript 6 modules to GoogleClosure libraries and to transform AMD modules to CommonJS modules. Tochoose the right compilation settings, we can extend the ClojureScriptcompiler options. The ClojureScript compiler already provides the compileroption:foreign-libs to include non-Closure compatible JavaScriptlibraries:

:foreign-libs [{:file"hello.js":provides  ["my.hello"]}]

This option could be extended with an optional:module-type key which caneither have the value:commonjs,:amd or:es6:

:foreign-libs [{:file"hello.js":provides  ["my.hello"]:module-type:commonjs}]

Similar to other JavaScript libraries, a JavaScript module can be added to aClojureScript namespace by requiring it with the name that has been specifiedas the value under the :provides key:

(nshello.core    (:require [my.hello]))

Once a module has been transformed into a Closure library, it can be addedas a dependency withgoog.require() which is supplied by Closure Library'sdependency management system.

We also need to be able to map the namespace of the module, which will begenerated by the Google Closure Compiler, and the namespace the user isusing in the ClojureScript project. The following example shows how a simpleCommonJS module might be transformed by the Google Closure Compiler.

var my = {};my.hello = {    greet: function(name) {        return"Hello" + name;    }};exports.hello = my.hello;

converts to:

goog.provide("module$hello");varmodule$hello={};varmy$$module$hello={};my$$module$hello.hello={greet:function(name){return"Hello "+name;}};module$hello.hello=my$$module$hello.hello;

In this example we would need to mapmodule$hello tomy.hello. Fortunately,the Google Closure Compiler provides the methodtoModuleName in the classesProcessCommonJSModules andProcessEs6Modules which we can use to get amodule name for a JavaScript module:

(ProcessCommonJsModules/toModuleName"hello.js");; returns module$hello

Extern Generation

At the moment, to be able to use a non-Closure compatible JavaScript libraryin a ClojureScript project, we also need to provide an extern file if wewant to make use of the advanced compilation option which is provided by theGoogle Closure Compiler. This extern file includes the symbols that we arecalling from our ClojureScript code. Providing an extern file will stop theGoogle Closure Compiler from renaming calls to external symbols.In ClojureScript code, all calls to external JavaScript libraries have to beprefixed withjs/:

(.greet js/my.hello"World!")

This makes it possible to identify calls to external libraries. The previouscode can also be written as:

(defhello (.-hello js/my))(.greet hello"World!")

This means we need to track that hello is a JavaScript object and need to beable to infer that resulting calls to it are external calls. This can beachieved by annotating the AST during the analyze phase. Using this information we could then generate the extern files during the compilation phase.

Community benefits

Module support

Until ECMAScript 6 there was no built-in support for modules in JavaScript.CommonJS and AMD are both module specifications that have been created dueto the lack of a modules system in JavaScript. With Node.js and RequireJSthose module systems have become quite popular and there are many librariesthat target one of those or even both module specifications.Adding CommonJS, AMD and ECMAScript 6 support to ClojureScript would allowusers to reuse JavaScript libraries that have been written with a specificmodule system in mind.

Extern generation

Currently, there are different efforts to help with the generation of externfiles, such as lein-externs and CLJSJS. While those projects make it easier toinclude extern files for JavaScript libraries, it means that a user needs tobe aware that an extern file is needed and also requires the user to choosethe right tool for it. Adding the ability to the ClojureScript compiler togenerate those extern files would lower the barrier for including externalJavaScript libraries, especially for someone who is new to ClojureScript.

Deliverables

At the end of this project it should be possible to include CommonJS, AMDand ECMAScript 6 modules into a ClojureScript project. Furthermore, externfiles for all observed method invocations and property accesses on externalJavaScript libraries should be generated by the ClojureScript compiler.

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp