]> git.immae.eu Git - github/fretlink/purs-loader.git/blame - src/PursLoader/Loader.purs
Handle optional bundling by the compiler
[github/fretlink/purs-loader.git] / src / PursLoader / Loader.purs
CommitLineData
c194f84c 1module PursLoader.Loader
1983893b 2 ( Effects()
c194f84c 3 , loader
4 , loaderFn
5 ) where
6
87145c4d 7import Prelude (Unit(), ($), (>>=), (<$>), (<*>), (++), (<<<), bind, const, id, pure, unit)
03b840cb 8
46039343 9import Control.Apply ((*>))
17f22f86 10import Control.Alt ((<|>))
63d6a244 11import Control.Bind (join)
46039343 12import Control.Monad.Eff (Eff(), foreachE)
63d6a244 13import Control.Monad.Eff.Exception (Error(), error)
c194f84c 14
63d6a244 15import Data.Array ((!!))
46039343 16import Data.Either (Either(..), either)
c194f84c 17import Data.Function (Fn2(), mkFn2)
63d6a244 18import Data.Maybe (Maybe(..), maybe)
46039343 19import Data.Nullable (toMaybe)
63d6a244 20import Data.String.Regex (Regex(), match, noFlags, regex)
21
22import Unsafe.Coerce (unsafeCoerce)
23
24import PursLoader.LoaderRef
46039343 25 ( AsyncCallback()
26 , LoaderRef()
63d6a244 27 , Loader()
28 , async
29 , cacheable
63d6a244 30 , clearDependencies
31 , addDependency
32 , resourcePath
33 )
c194f84c 34
3afbe2fd 35import PursLoader.Debug (debug)
87145c4d 36import PursLoader.Path (dirname, joinPath, relative)
46039343 37import PursLoader.Plugin as Plugin
c194f84c 38
63d6a244 39type Effects eff = (loader :: Loader | eff)
c194f84c 40
63d6a244 41loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
42loader ref source = do
43 callback <- async ref
3610dff1 44
63d6a244 45 cacheable ref
c194f84c 46
3afbe2fd 47 debug "Invoke PureScript plugin compilation"
48
46039343 49 pluginContext.compile (compile callback)
63d6a244 50 where
46039343 51 pluginContext :: Plugin.Context (Effects eff)
63d6a244 52 pluginContext = (unsafeCoerce ref).purescriptWebpackPluginContext
c194f84c 53
46039343 54 compile :: AsyncCallback eff -> Plugin.Compile (Effects eff)
55 compile callback error' { srcMap, ffiMap, graph } = do
56 clearDependencies ref
57
3afbe2fd 58 either (const $ pure unit) (\a -> debug ("Adding PureScript dependency " ++ a)) name
59
46039343 60 addDependency ref (resourcePath ref)
61
17f22f86 62 either (\err -> callback (toMaybe error' <|> Just err) "") id
46039343 63 (handle <$> name <*> dependencies <*> exports)
64 where
65 handle :: String -> Array String -> String -> Eff (Effects eff) Unit
66 handle name' deps res = do
3afbe2fd 67 debug ("Adding PureScript transitive dependencies for " ++ name')
46039343 68 addTransitive name'
69 foreachE deps addTransitive
b1b6e146 70 debug "Generated loader result"
71 debug res
46039343 72 callback (toMaybe error') res
73
74 exports :: Either Error String
87145c4d 75 exports =
76 if pluginContext.options.bundle
77 then bundleExport <$> name
78 else moduleExport <<< modulePath <$> name
79 where
80 bundleExport :: String -> String
81 bundleExport name' = "module.exports = require('" ++ path ++ "')['" ++ name' ++ "'];"
82 where
83 path :: String
84 path = relative resourceDir pluginContext.options.bundleOutput
85
86 moduleExport :: String -> String
87 moduleExport path = "module.exports = require('" ++ path ++ "');"
88
89 modulePath :: String -> String
90 modulePath = relative resourceDir <<< joinPath pluginContext.options.output
91
92 resourceDir :: String
93 resourceDir = dirname (resourcePath ref)
46039343 94
95 dependencies :: Either Error (Array String)
87145c4d 96 dependencies =
97 if pluginContext.options.bundle
98 then name >>= Plugin.dependenciesOf graph
99 else pure []
46039343 100
101 addTransitive :: String -> Eff (Effects eff) Unit
102 addTransitive dep = addDep (Plugin.get srcMap dep) *> addDep (Plugin.get ffiMap dep)
103 where
104 addDep :: Maybe String -> Eff (Effects eff) Unit
105 addDep = maybe (pure unit) (addDependency ref)
106
107 name :: Either Error String
108 name =
109 maybe (Left $ error "Failed to parse module name") Right
110 (join $ match re source >>= \as -> as !! 1)
111 where
112 re :: Regex
113 re = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
114
1983893b 115loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
c194f84c 116loaderFn = mkFn2 loader