]>
Commit | Line | Data |
---|---|---|
c194f84c | 1 | module PursLoader.Loader |
1983893b | 2 | ( Effects() |
c194f84c | 3 | , loader |
4 | , loaderFn | |
5 | ) where | |
6 | ||
87145c4d | 7 | import Prelude (Unit(), ($), (>>=), (<$>), (<*>), (++), (<<<), bind, const, id, pure, unit) |
03b840cb | 8 | |
46039343 | 9 | import Control.Apply ((*>)) |
17f22f86 | 10 | import Control.Alt ((<|>)) |
63d6a244 | 11 | import Control.Bind (join) |
46039343 | 12 | import Control.Monad.Eff (Eff(), foreachE) |
63d6a244 | 13 | import Control.Monad.Eff.Exception (Error(), error) |
c194f84c | 14 | |
63d6a244 | 15 | import Data.Array ((!!)) |
46039343 | 16 | import Data.Either (Either(..), either) |
c194f84c | 17 | import Data.Function (Fn2(), mkFn2) |
63d6a244 | 18 | import Data.Maybe (Maybe(..), maybe) |
46039343 | 19 | import Data.Nullable (toMaybe) |
63d6a244 | 20 | import Data.String.Regex (Regex(), match, noFlags, regex) |
21 | ||
22 | import Unsafe.Coerce (unsafeCoerce) | |
23 | ||
24 | import 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 | 35 | import PursLoader.Debug (debug) |
87145c4d | 36 | import PursLoader.Path (dirname, joinPath, relative) |
46039343 | 37 | import PursLoader.Plugin as Plugin |
c194f84c | 38 | |
63d6a244 | 39 | type Effects eff = (loader :: Loader | eff) |
c194f84c | 40 | |
63d6a244 | 41 | loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit |
42 | loader 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 | 115 | loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit) |
c194f84c | 116 | loaderFn = mkFn2 loader |