Skip to content

Commit 5c9095a

Browse files
committed
feat: support --esm
1 parent 7f978bc commit 5c9095a

File tree

8 files changed

+66
-3
lines changed

8 files changed

+66
-3
lines changed

builder/src/Generate.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ debug root details (Build.Artifacts pkg ifaces roots modules) =
6060
let graph_ = objectsToGlobalGraph objects
6161
graph <- Task.io $ Lamdera.AppConfig.injectConfig graph_
6262
let mains = gatherMains pkg objects roots
63+
esmEnabled <- Task.io $ Lamdera.useEsm
6364
return $ JS.generate mode graph mains
65+
& Lamdera.alternativeImplementationWhen esmEnabled
66+
(JS.generateEsm mode graph mains)
6467

6568

6669
dev :: FilePath -> Details.Details -> Build.Artifacts -> Task B.Builder
@@ -70,7 +73,10 @@ dev root details (Build.Artifacts pkg _ roots modules) =
7073
let graph_ = objectsToGlobalGraph objects
7174
graph <- Task.io $ Lamdera.AppConfig.injectConfig graph_
7275
let mains = gatherMains pkg objects roots
76+
esmEnabled <- Task.io $ Lamdera.useEsm
7377
return $ JS.generate mode graph mains
78+
& Lamdera.alternativeImplementationWhen esmEnabled
79+
(JS.generateEsm mode graph mains)
7480

7581

7682
prod :: FilePath -> Details.Details -> Build.Artifacts -> Task B.Builder
@@ -84,7 +90,10 @@ prod root details (Build.Artifacts pkg _ roots modules) =
8490
& Lamdera.alternativeImplementationWhen longNamesEnabled
8591
(Mode.Prod (Mode.legibleFieldNames graph))
8692
let mains = gatherMains pkg objects roots
93+
esmEnabled <- Task.io $ Lamdera.useEsm
8794
return $ JS.generate mode graph mains
95+
& Lamdera.alternativeImplementationWhen esmEnabled
96+
(JS.generateEsm mode graph mains)
8897

8998

9099
repl :: FilePath -> Details.Details -> Bool -> Build.ReplArtifacts -> N.Name -> Task B.Builder

compiler/src/Generate/JavaScript.hs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{-# LANGUAGE OverloadedStrings #-}
22
module Generate.JavaScript
33
( generate
4+
, generateEsm
45
, generateForRepl
56
, generateForReplEndpoint
67
)
@@ -58,6 +59,19 @@ generate mode (Opt.GlobalGraph graph_ _) mains =
5859
<> "}(this));"
5960
<> "\n" <> Lamdera.Injection.elmPkgJs mode mains <> "\n"
6061

62+
generateEsm :: Mode.Mode -> Opt.GlobalGraph -> Mains -> B.Builder
63+
generateEsm mode (Opt.GlobalGraph graph_ _) mains =
64+
let
65+
graph = Lamdera.Injection.graphModifications mode mains graph_
66+
state = Map.foldrWithKey (addMain mode graph) emptyState mains
67+
in
68+
Functions.functions
69+
-- <> perfNote mode -- @NOTE given user never manages JS generation in Lamdera, hide the perf note
70+
<> stateToBuilder state
71+
<> toMainEsmExports mode mains
72+
-- <> Lamdera.Injection.source mode mains -- shadowing not allowed in esm
73+
<> "\n" <> Lamdera.Injection.elmPkgJs mode mains <> "\n"
74+
6175
addMain :: Mode.Mode -> Graph -> ModuleName.Canonical -> Opt.Main -> State -> State
6276
addMain mode graph home _ state =
6377
addGlobal mode graph state (Opt.Global home "main")
@@ -547,6 +561,13 @@ toMainExports mode mains =
547561
in
548562
JsName.toBuilder export <> "(" <> exports <> ");"
549563

564+
toMainEsmExports :: Mode.Mode -> Mains -> B.Builder
565+
toMainEsmExports mode mains =
566+
let
567+
exports = generateExports mode (Map.foldrWithKey addToTrie emptyTrie mains)
568+
in
569+
"export const Elm = " <> exports <> ";"
570+
550571

551572
generateExports :: Mode.Mode -> Trie -> B.Builder
552573
generateExports mode (Trie maybeMain subs) =

extra/Lamdera.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ module Lamdera
4545
, useLongNames_
4646
, enableLongNames
4747
, useLongNames
48+
, useEsm_
49+
, enableEsm
50+
, useEsm
4851
, isTest
4952
, isLiveMode
5053
, setLiveMode
@@ -460,6 +463,19 @@ enableLongNames = do
460463
debug $ "🗜️ enableLongNames"
461464
modifyMVar_ useLongNames_ (\_ -> pure True)
462465

466+
{-# NOINLINE useEsm_ #-}
467+
useEsm_ :: MVar Bool
468+
useEsm_ = unsafePerformIO $ newMVar False
469+
470+
{-# NOINLINE useEsm #-}
471+
useEsm :: IO Bool
472+
useEsm = do
473+
readMVar useEsm_
474+
475+
enableEsm :: IO ()
476+
enableEsm = do
477+
debug $ "🗜️ enableEsm"
478+
modifyMVar_ useEsm_ (\_ -> pure True)
463479

464480
isTest :: IO Bool
465481
isTest = do

extra/Lamdera/CLI/Check.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ buildProductionJsFiles root inProduction_ versionInfo = do
599599
, _docs = Nothing
600600
, _noWire = False
601601
, _optimizeLegible = True
602+
, _esm = False
602603
}
603604

604605
Make.run ["src" </> "LFR.elm"] $
@@ -610,6 +611,7 @@ buildProductionJsFiles root inProduction_ versionInfo = do
610611
, _docs = Nothing
611612
, _noWire = False
612613
, _optimizeLegible = False
614+
, _esm = False
613615
}
614616

615617
Lamdera.AppConfig.writeUsage
@@ -713,6 +715,7 @@ migrationCheck root nextVersion changedTypes = do
713715
, _docs = Nothing
714716
, _noWire = False
715717
, _optimizeLegible = False
718+
, _esm = False
716719
}
717720

718721
-- @TODO this is because the migrationCheck does weird terminal stuff that mangles the display... how to fix this?

extra/Lamdera/Compile.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ makeOptimizedWithCleanup cleanup root path = do
4242
, _docs = Nothing
4343
, _noWire = False
4444
, _optimizeLegible = False
45+
, _esm = False
4546
}
4647
wait r
4748
remove tmp
@@ -69,6 +70,7 @@ make_ root = do
6970
, _docs = Nothing
7071
, _noWire = False
7172
, _optimizeLegible = True
73+
, _esm = False
7274
}
7375
wait r
7476
-- The compilation process ends by printing to terminal in a way that overwrites
@@ -98,6 +100,7 @@ makeDev root paths = do
98100
, _docs = Nothing
99101
, _noWire = False
100102
, _optimizeLegible = False
103+
, _esm = False
101104
}
102105
wait r
103106
-- The compilation process ends by printing to terminal in a way that overwrites
@@ -127,6 +130,7 @@ makeDevHtml root paths = do
127130
, _docs = Nothing
128131
, _noWire = False
129132
, _optimizeLegible = False
133+
, _esm = False
130134
}
131135
wait r
132136
-- The compilation process ends by printing to terminal in a way that overwrites
@@ -158,6 +162,7 @@ makeHarnessDevJs root = do
158162
, _docs = Nothing
159163
, _noWire = False
160164
, _optimizeLegible = False
165+
, _esm = False
161166
}
162167
wait r
163168
remove tmp

terminal/src/Main.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ make =
214214
|-- flag "docs" Make.docsFile "Generate a JSON file of documentation for a package. Eventually it will be possible to preview docs with `reactor` because it is quite hard to deal with these JSON files directly."
215215
|-- onOff "no-wire" "Explicitly disable Lamdera's wire codegen."
216216
|-- onOff "optimize-legible" "Same as --optimize but without identifier shortening, handy for debugging optimised code or for when identifiers are more useful than smaller JS compilations."
217+
|-- onOff "esm" "Emit an ECMAScript module instead of an IIFE."
217218
in
218219
Terminal.Command "make" Uncommon details example (zeroOrMore elmFile) makeFlags Make.run
219220

terminal/src/Make.hs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ data Flags =
4848
, _docs :: Maybe FilePath
4949
, _noWire :: Bool -- @LAMDERA
5050
, _optimizeLegible :: Bool -- @LAMDERA
51+
, _esm :: Bool -- @LAMDERA
5152
}
5253

5354

@@ -69,19 +70,20 @@ type Task a = Task.Task Exit.Make a
6970

7071

7172
run :: [FilePath] -> Flags -> IO ()
72-
run paths flags@(Flags _ _ _ report _ noWire optimizeLegible) =
73+
run paths flags@(Flags _ _ _ report _ noWire optimizeLegible esm) =
7374
do style <- getStyle report
7475
maybeRoot <- Stuff.findRoot
7576
Lamdera.onlyWhen noWire Lamdera.disableWire
7677
Lamdera.onlyWhen optimizeLegible Lamdera.enableLongNames
78+
Lamdera.onlyWhen esm Lamdera.enableEsm
7779
Reporting.attemptWithStyle style Exit.makeToReport $
7880
case maybeRoot of
7981
Just root -> runHelp root paths style flags
8082
Nothing -> return $ Left $ Exit.MakeNoOutline
8183

8284

8385
runHelp :: FilePath -> [FilePath] -> Reporting.Style -> Flags -> IO (Either Exit.Make ())
84-
runHelp root paths style (Flags debug optimize maybeOutput _ maybeDocs _ optimizeLegible) =
86+
runHelp root paths style (Flags debug optimize maybeOutput _ maybeDocs _ optimizeLegible _) =
8587
BW.withScope $ \scope ->
8688
Stuff.withRootLock root $ Task.run $
8789
do desiredMode <- getMode debug (optimize || optimizeLegible)
@@ -304,6 +306,7 @@ parseOutput name
304306
| isDevNull name = Just DevNull
305307
| hasExt ".html" name = Just (Html name)
306308
| hasExt ".js" name = Just (JS name)
309+
| hasExt ".mjs" name = Just (JS name) -- @LAMDERA
307310
| otherwise = Nothing
308311

309312

@@ -334,11 +337,12 @@ isDevNull name =
334337

335338
-- Clone of run that uses attemptWithStyle_cleanup
336339
run_cleanup :: IO () -> [FilePath] -> Flags -> IO ()
337-
run_cleanup cleanup paths flags@(Flags _ _ _ report _ noWire optimizeLegible) =
340+
run_cleanup cleanup paths flags@(Flags _ _ _ report _ noWire optimizeLegible esm) =
338341
do style <- getStyle report
339342
maybeRoot <- Stuff.findRoot
340343
Lamdera.onlyWhen noWire Lamdera.disableWire
341344
Lamdera.onlyWhen optimizeLegible Lamdera.enableLongNames
345+
Lamdera.onlyWhen esm Lamdera.enableEsm
342346
Reporting.attemptWithStyle_cleanup cleanup style Exit.makeToReport $
343347
case maybeRoot of
344348
Just root -> runHelp root paths style flags

test/Test/JsOutput.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ suite =
3636
, _docs = Nothing
3737
, _noWire = True
3838
, _optimizeLegible = False
39+
, _esm = False
3940
}
4041

4142
fileContents <- readUtf8Text $ elmStuff ++ "/tmp.js"
@@ -74,6 +75,7 @@ suite =
7475
, _docs = Nothing
7576
, _noWire = True
7677
, _optimizeLegible = False
78+
, _esm = False
7779
}
7880

7981
fileContents <- readUtf8Text $ elmStuff ++ "/tmp.js"
@@ -123,6 +125,7 @@ suite =
123125
, _docs = Nothing
124126
, _noWire = True
125127
, _optimizeLegible = False
128+
, _esm = False
126129
}
127130

128131
fileContents <- readUtf8Text $ elmStuff ++ "/tmp.js"
@@ -174,6 +177,7 @@ suite =
174177
, _docs = Nothing
175178
, _noWire = True
176179
, _optimizeLegible = False
180+
, _esm = False
177181
}
178182

179183
fileContents <- readUtf8Text $ elmStuff ++ "/tmp.js"

0 commit comments

Comments
 (0)