All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
- ElixirScript now has an FFI layer for interoperability with JavaScript. For more details, see documentation at
ElixirScript.FFI ElixirScript.JS.mutate/3ElixirScript.JS.map_to_object/1
- Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+
JSmodule renamed toElixirScript.JS
remove-unusedoption that will remove all unused modules from output- reimplemented structs to avoid creating JavaScript classes
superdefoverridableIO.inspect\1,IO.puts\1,IO.puts\2,IO.warn\1Elixir.loadfor loading generated JavaScript modules in bundled output. UnlikeElixir.start, this will only call__loadon the module and return the functions on it
const exports = Elixir.load(Elixir.MyApp);
exports.hello();-exalias is now-e- A filename can be specified for output
- To access global JavaScript functions, modules, and properties, use the
JSmodule
JS.length # translates to 'length'
JS.alert() # translates to 'alert()'
JS.String.raw("hi") # translate to String.raw('hi')
JS.console.log("hi") # translates to console.log('hi')- Make sure mix compiler works in umbrella apps
- Fixed
fortranslation - Updated documentation
-
Multiple
whenclauses in guards -
Kernel.defdelegate/2
-
js_modulesconfiguration option has been added. This is a list of JavaScript modules that will be used.js_modules: [ {React, "react"}, {ReactDOM, "react-dom"} ] -
js-moduleflag has been added to the CLI in order to pass js modules.
elixirscript "app/elixirscript" -o dist --js-module React:react --js-module ReactDOM:react-dom
@on_js_loadhas been removed in favor of having astart/2function defined. More info belowJS.importhas been removed in favor of defining JavaScript modules used in configuration
-
Now bundles all output, including the boostrap code. The exported object has Elixir modules in JavaScript namespaces that are lazily loaded when called.
To start your application import the bundle according to whichever module format was selected and then call start giving it the module and the initial args
//ES module example import Elixir from './Elixir.App' Elixir.start(Elixir.App, [])
The
startfunction will look for astart/2function there. This is analogous to a Application module callback
-
Updated elixir_script mix compiler to support compiling elixir_script paths in dependencies if dependency has mix compiler defined as well
-
Add
Collectableprotocol implementations -
Updated
forimplementation to useCollectable -
formatoption. Can now specify the module format of output. Choices are: *:es(default) for ES Modules *:umdfor UMD *:commonfor CommonJS -
Default input, output and format for elixirscript mix compiler. In a mix project by default the elixirscript compiler will look in
lib/elixirscriptand input and place output inpriv/elixirscript. The default format is:es
receiveProcessmodule
- JS module functions not translated properly when imported
- Update fs dependency to 2.12
- Incorrect handling of function heads with guards
- Support for
sigil_r Regexmodule- Better JavaScript formatting
- CLI now allows a comma-separated or space-separated list of paths
- Struct not properly referenced
- Tail call optimization
@load_only: lets the compiler know to load in the module, but not to compile it
- Agent not functioning properly. Now uses internal store instead of making a process and using that to put data in store
- Protocol incorrectly handling strings
defgenanddefgenpfunctions not being recognized by Elixir compiler.
- Incorrectly sending standard lib when using compile or compile_path by default
withnow supportselse- Implement
contextoption onquote - New compiler pipeline
@on_js_load. Expects a 0 arity function. This function will be called when the compiled module is loaded in JavaScriptJS.import\3. Just likeJS.import\2but expects options to decide if the import should be a default one or a namespace on. Only option allowed isdefault. Set totrueby default# translates to "import A from 'a'" JS.import A, "a" #translates to "import * as A from 'a'" JS.import A, "a", default: false
- The form of
JS.importthat accepted a list of atoms as the first arg. UsedJS.import\3withdefault: falseinstead to create a namespace import envandrootare no longer options forElixirScript's compile functions and cli- Syntax once supported by Elixirscript
JQuery.("#element"), is no longer supported
- Changed CHANGELOG.md to adhere the format from Keep a Changelog
defmacronow supported. No longer have to separate macros from functions in separate files.defmacropstill unsupported- To use anything in the
JSmodule, you mustrequiretheJSmodule first - Elixirscript files must now contain valid Elixir syntax.
- Now compiles
exjsandexfiles within the path can be compiled all the same. Dependencies from hex are still unsupported so these files must not rely on any code outside of the path. What this does mean is that it is now possible to share code between Elixir and Elixirscript as long as the Elixir files functionality fall within what Elixirscript currently supports. defgen,defgenp,yield,yield_to, andobjectare now in theJSmodule- To access functions in the global JavaScript scope, either use
JS.global\0or use the erlang module call syntaxCalling JavaScript modules in the global scope works without using the above methods#calling alert JS.global().alert("hi") #calling alert :window.alert("hi")
#calls window.Date.now() Date.now()
defgenanddefgenpfor defining public and private generatorsyield/0,yield/1, andyield_to\1toKernel
- Updated output folder structure. stdlib code will now go in an
elxiirfolder under the output paths while generated app code will go into anappfolder under the output path - All process macros and functions now expect to receive and/or work using generators as entry points. Using functions defined with
defordefpwill not work correctly with them
- Correctly returning list if list is only item in body
- This is the first release with early support for processes in elixirscript. Creating a process only works currently using
spawn/1,spawn_link/1, andspawn_monitor/1. Inside of a process, you can use functions such assendandreceive, along with some defined in theProcessmodule. From outside of a process, you can send messages to a process, but you cannot receive a message from a process. Eventually all code will run inside processes and this restriction will naturally lift. - The
Processmodule has been implemented with the following functions:alive?/1delete/1demonitor/1exit/2flag/2flag/3get/0get_keys/0get_keys/1link/1list/0monitor/1put/2register/2registered/0send/3sleep/1unlink/1unregister/1whereis/1
- The
receivespecial form has been implemented with the above caveat - The following have been implemented on
Kernel:spawn/1spawn_link/1spawn_monitor/1send/2make_ref/0
- Scoping on
fnanddef
ElixirScript.Watchermodule andelixirscript.watchmix task- logging MatchError exceptions to better show terms that don't match
- elixir_script mix compiler
Html,View, andVDommodules have been removed
- Better support for macros. Macros should be defined in .ex or .exs files. ElixirScript code should be in .exjs files
NOTE: The above functionality will cause either compiler errors or no output. Please change extensions of ElixirScript code to .exjs
Html,View, andVDommodules will be removed in the next version as they can now be replicated using macros
outputas an option for compiler functions. This controls whether output is returned as a list of tuples, send to stdout, or saved to a file path:full_buildas an option for compiler functions and--full-buildoption to CLI. These force the compiler to perform a full build--versionoption to CLI. Outputs current version of elixirscript--std-liboption to CLI. Takes a path and adds the stdlib to that path
- Renamed
copy_core_to_destinationtocopy_stdlib_to_destination - Incremental Compilation: ElixirScript will now only build files and modules that have changed since the last build
--coreoption from CLI and:corecompiler option.
- Bitstring pattern matching
- Bitstrings in for comprehensions
- Functions with catch, after, else clauses
withspecial form- Pin operator in map keys and function clauses
- Added
Kernel.object/1function to make it more natural to create a JavaScript object with string keys. Elixirscript, by default turns the following,%{a:"b"}into{[Symbol.for("a")]: "b"}in JavaScript. In order to get string keys, one would have to do%{"a" => "b"}which turns into{a: "b"}in JavaScript. WithKernel.object, you can create string keyed maps conveniently,object(a: "b")which turns into{a: "b"}.
NOTE: when updating the created by, you still have to use the string form %{ my_map | "a" => "c" }
JS.update(object, property, value)has been removed and replaced withJS.update(object, map). This allows you to update multiple values on a javascript object at once.
- Optional parameters should now work as expected
- Support for variables as map keys
- Protocol implementations for Integer and Float which where not recognized
- Calling properties on non-objects
- Removed
catchas a javascript keyword to filter
- Fixed View module so that an element can have multiple elements within
- struct implementation so that lists of atoms for fields are compiled correctly
- head-tail pattern match to allow for more complicated scenarios
- ModuleCollector to properly alias inner modules
- Raise translation to properly translate when string messages are given
__ENV__and__CALLER__are now supportedJS.import/1,JS.typeof/1,JS.instanceof/1, andJS.global/1- Support for multi alias/require/imports statements
alias,require, andimportnow work inside lexical scopes- Some of the standard library originally written in JavaScript has been rewritten in Elixir.
- Generated JavaScript export statements are now default exports
- When output is sent to standard out, there are now markers to specify where each module begins as well as what the file name would be. For the end of a file,
//:ENDFILEis used. For the file name,//<file>:ENDFILENAMEis used where<file>is the name of the file compile,compile_path, andcompile_quotedopts parameter now expects a map- The
stdlibcompiler option is nowcore. Thestdlib_pathcompiler options is nowcore_path
- .DS_Store and LICENSE from output
- Can now implement protocols using JavaScript types
defimpl MyProtocol, for: HTMLElement
- virtual-dom JavaScript library
- ElixirScript.Html module for defining a virtual-dom tree
- ElixirScript.VDom module for manipulating the virtual-dom tree created using the ElixirScript.Html module
- Added ElixirScript.View module for handling view state and rendering virtual-dom
- Added
stdlib_pathcompiler option to specify the es6 path to the standard library. If used, elixir.js will not be exported with the compiled modules
- Renamed
ex2jstoelixirscript. This effects the escript as well as the mix task - Structs are now translated into classes
- Structs and Tuples now match on their types
- Can now match on JavaScript classes. Works just like matching on structs:
def my_func(%HTMLElement{id: "myId"})
- Moved non-elixir JavaScript code into
corees6 module. This will hopefully make it so ElixirScript Standard Library modules can be defined in Elixir soon.
Basemodule with function: encode64, decode64, and decode64!StringmoduleBitwisemoduleMapmoduleMapSetmoduleSetmodule- Protocol support
- Added
Collectable,Enumerable,Inspect,List.Chars, andString.Charsprotocols. The only one currently being used in the Standard Library, however, is String.Chars
- Added PostOffice. Only thing that current uses it is Agent
- Updated tuple implementation. It's now a class.
- Replaced pattern matching library with custom one
- Moved data types to Kernel.SpecialForms
elsenow works for try expressions- for now works with
intofor lists
- Removed erlang.js.
- Added
JSmodule withnew,mutate,importmacros - Added
Keywordmodule with functions,has_key?andget - Added
Agentmodule with functions,start,get,update, andget_and_update
- Map keys are now correctly turned into their atom counterparts if atom keys are used
importworks with all optionsMutable.updatehas been replaced byJS.updatetranspile,transpile_quoted, andtranspile_pathare nowcompile,compile_quoted, andcompile_path- All Standard libraries are rolled up into one elixir.js file and imported from that
- Modules no longer export a default object
aliasnow translates to a namespace import unlessdefaultoption is given
- Added
envoption forElixirScript.transpileadding macros for compilation - Added
Loggerthat translates Logger functions to console
- Updated
Kernelmodule to translate some functions to it's JavaScript equivalent
- Fixed
caseimplementation to addthisto call
- an implementation for quote. Currently ignores
:locationand:contextoptions - an implementation for unquote and unquote_splicing
- Can now support catch blocks in try expressions
- Added receive
- Updated pattern matching implementation
- Wrapped try's in function closure to make sure they return a value;
- Can now support rescue and after blocks in try expressions
- Now using the JS code generator from elixir-estree for code generation, improving speed of transpilation
- the parse functions in the ElixirScript module have been renamed to transpile
- Added iterators for Range and BitString
- Now replacing characters that can't be used in variable and function names in JavaScript with something that it (i.e.
match?->match__qmark__) - Implemented Integer module
- Made the Tuple, Range and BitString data structures more immutable
- Atom now translates to an ES6 Symbol
- List now translates to a frozen JS Array
- Updated the pattern match binding to use ES6 destructuring for lists and tuples
- Inner modules are now split out into their own files
- Standard lib is now exported with file output from cli
- Standard lib modules are now automatically imported
- No longer have to define modules via aliases ahead of time. They will be automatically be resolved and made into JavaScript import statements
- added
fromclause toimport,alias, andrequireso that the import path can be overridden
- For statements now work with pattern matching tuples
- Improved function chaining
aliasnow acts likerequirein that it is translated into an import default statement- modules now export a default object with def functions added as properties on it.
- for function closures, now calling by using
.call(this)so thatthisis available inside of it
- bitstrings
- Better Pattern Matching (Does not support bitstrings yet)
- Capture Operator
- Added more functions from the list standard library
- Updated variable implementation to match Elixir's (i.e. Reusing the same variable name creates a new one in the background)
- Fixed multi arity implementation
- function and case guards
- function and case pattern matching
- Can now use ^ on a variable during assignment
- Renamed project to ElixirScript
- Reduced escript file size
- Pipe operator
- String interpolation
- Adding more functions to the Kernel module
- Fully implemented Tuple module
- Fully implemented Atom module
- Fully implemented Range module
- Now checking to see if a function is a Kernel function and prepending Kernel to it
- Now turning Atoms into an Atom javascript object instead of a Symbol
- Now turning tuples into a Tuple javascript object
- Can now call properties and zero parameter functions correctly
- case, cond, and if are now turned into if statements wrapped in function closures
- Anonymous functions are now turned into anonymous functions in javascript insteed of arrow functions
- From standard library implemented:
- Enum.map
- Kernel.tl
- Kernel.hd
- Logger
- Implemented language features:
- All primitives except bitstrings
- defmodule
- import, alias, and require
- case, cond, if
- def, defp
- defstruct, defexception
- raise
- multiple arity functions
- basic binary operations
- for without into