我目前正在测试将我们的构建系统从 make 移植到shake 并且遇到了障碍:
给定以下项目结构:
static/a.js
static/b.coffee
build/a.js
build/b.js
也就是说,不同的输入扩展映射到相同的输出扩展,所以一个简单的"build//*.js" %>
规则是行不通的。
如果可能,我想避免使用优先级,并编写一个临时构建规则来检查是否存在任何可能的输入感觉很笨重(特别是因为这种情况也发生在其他文件类型中),所以我写了以下内容:
data StaticFileMapping a = StaticFileMapping String String (FilePath -> FilePath -> Action a)
staticInputs :: FilePath -> StaticFileMapping a -> Action [FilePath]
staticInputs dir (StaticFileMapping iExt _ _) = (findFiles (dir </> "static") [iExt])
staticInputToOutput :: StaticFileMapping a -> FilePath -> FilePath
staticInputToOutput (StaticFileMapping _ oExt _) = (remapDir ["build"]) . (-<.> oExt)
staticTargets :: FilePath -> StaticFileMapping a -> Action [FilePath]
staticTargets dir sfm = (map $ staticInputToOutput sfm) <$> staticInputs dir sfm
rules :: FilePath -> StaticFileMapping a -> Rules ()
rules dir sfm@(StaticFileMapping _ _ process) = join $ mconcat . (map buildInputRule) <$> staticInputs dir sfm
where buildInputRule :: FilePath -> Rules ()
buildInputRule input = (staticInputToOutput sfm input) %> (process input)
这样,我可以为每种输入类型 ( .coffee -> .js
, .svg -> .png
) 等定义一个映射,只需少量代码实现每个输入类型的转换。它几乎可以工作。
但据我所知,如果不先将价值扔进客场,(Action a)
似乎Rules _
是不可能的。Action
是否有 type(Action a) -> (a -> Rules ()) -> Rules ()
或的函数(Action a) -> (Rules a)
?我可以自己实现一个,还是需要修改库的代码?
或者这整个方法是愚蠢的,我应该采取其他途径?