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