]> git.immae.eu Git - github/fretlink/purs-loader.git/blame_incremental - src/PursLoader/Loader.purs
Merge branch 'master' into topic/stderr
[github/fretlink/purs-loader.git] / src / PursLoader / Loader.purs
... / ...
CommitLineData
1module PursLoader.Loader
2 ( Effects()
3 , Effects_()
4 , loader
5 , loaderFn
6 ) where
7
8import Prelude (Unit(), ($), (>>=), (<$>), (<*>), (++), (<<<), bind, const, id, pure, unit, void)
9
10import Control.Bind (join)
11import Control.Monad.Eff (Eff(), foreachE)
12import Control.Monad.Eff.Console (CONSOLE())
13import Control.Monad.Eff.Exception (EXCEPTION(), Error(), error, message)
14
15import Data.Array ((!!))
16import Data.Either (Either(..), either)
17import Data.Function (Fn2(), mkFn2)
18import Data.Maybe (maybe)
19import Data.Nullable (toMaybe)
20import Data.String.Regex (Regex(), match, noFlags, regex)
21
22import Node.Encoding (Encoding(UTF8))
23import Node.Process (stderr)
24import Node.Stream (writeString)
25
26import Unsafe.Coerce (unsafeCoerce)
27
28import PursLoader.LoaderRef
29 ( AsyncCallback()
30 , LoaderRef()
31 , Loader()
32 , async
33 , cacheable
34 , addDependency
35 , resourcePath
36 )
37
38import PursLoader.Debug (debug)
39import PursLoader.Path (dirname, joinPath, relative)
40import PursLoader.Plugin as Plugin
41
42type Effects eff = (console :: CONSOLE, err :: EXCEPTION | eff)
43
44type Effects_ eff = Effects (loader :: Loader | eff)
45
46loader :: forall eff. LoaderRef -> String -> Eff (Effects_ eff) Unit
47loader ref source = do
48 callback <- async ref
49
50 cacheable ref
51
52 debug "Invoke PureScript plugin compilation"
53
54 pluginContext.compile (compile callback)
55 where
56 pluginContext :: Plugin.Context (Effects_ eff)
57 pluginContext = (unsafeCoerce ref).purescriptWebpackPluginContext
58
59 compile :: AsyncCallback (Effects eff) -> Plugin.Compile (Effects_ eff)
60 compile callback error' graph output = do
61 either (const $ pure unit) (\a -> debug ("Adding PureScript dependency " ++ a)) name
62
63 addDependency ref (resourcePath ref)
64
65 void $ writeString stderr UTF8 output (pure unit)
66
67 maybe (pure unit) (\a -> void $ writeString stderr UTF8 (message a) (pure unit)) (toMaybe error')
68
69 either (const $ callback (pure fixedError) "") id
70 (handle <$> name <*> dependencies <*> exports)
71 where
72 fixedError :: Error
73 fixedError = error "PureScript compilation has failed."
74
75 handle :: String -> Array String -> String -> Eff (Effects_ eff) Unit
76 handle name' deps res = do
77 debug ("Adding PureScript dependencies for " ++ name')
78 foreachE deps (addDependency ref)
79 debug "Generated loader result"
80 debug res
81 callback (const fixedError <$> toMaybe error') res
82
83 exports :: Either Error String
84 exports =
85 if pluginContext.options.bundle
86 then bundleExport <$> name
87 else moduleExport <<< modulePath <$> name
88 where
89 bundleExport :: String -> String
90 bundleExport name' = "module.exports = require('" ++ path ++ "')['" ++ name' ++ "'];"
91 where
92 path :: String
93 path = relative resourceDir pluginContext.options.bundleOutput
94
95 moduleExport :: String -> String
96 moduleExport path = "module.exports = require('" ++ path ++ "');"
97
98 modulePath :: String -> String
99 modulePath = relative resourceDir <<< joinPath pluginContext.options.output
100
101 resourceDir :: String
102 resourceDir = dirname (resourcePath ref)
103
104 dependencies :: Either Error (Array String)
105 dependencies = Plugin.dependenciesOf graph (resourcePath 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
115loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects_ eff) Unit)
116loaderFn = mkFn2 loader