How can Shake FilePatterns be used to minify JS and CSS files?


Tags: javascript,css,haskell,minify,shake-build-system

Problem :

Common practice with .js and .css file minification is to create .min.js and .min.css files. The problem is Shake FilePatterns will match both minified and non-minified files with this scheme with a pattern like //*.js. The docs seem to recommend making unique extensions for each like reg.js and min.js but I'm not sure this is a path I want to take. How can this be worked around in Shake?

Edit: The problem is with using getDirectoryFiles:

js <- getDirectoryFiles "" ["//*.js"]
let jsMins = map (-<.> "min" <.> "js") js
need jsMins

There's a target for "//*.min.js that works just fine but getDirectoryFiles "" ["//*.js"] starts picking up the generated .min.js files.



Solution :

I can think of two alternative approaches:

Post process getDirectoryContents

Call getDirectoryContents then filter out the values you don't care about. Something like:

xs <- getDirectoryFiles "" ["//*.js"]
need [x -<.> "min.js" | x <- xs, takeExtensions x == ".js"]

If you are running this code outside of a rule, e.g. in an action, then it is 100% correct. If you are running the code in a rule then the rule will run once, new files will appear, and then the rule will run again (which is also a lint violation, and not great build hygine). I suspect you are running outside of a rule, so this approach is probably a good one.

Write an Oracle

If you are inside a rule, you can define an Oracle which is like getDirectoryFiles, but skips the min files.

newtype JsFiles = JsFiles () deriving (Show,Typeable,Eq,Hashable,Binary,NFData)
addOracle $ \(JsFiles _) -> fmap (\x -> takeExtensions x == ".js") $ getDirectoryFiles "" ["//*.js"]

Now you can use askOracle $ JsFiles () in your rule, and it will only change when new non-min files are added.


    CSS Howto..

    How to achive certain overlapping layout when there is not enough space in parent container?

    How to add styling to active input's previous sibling using CSS only [duplicate]

    How to add scrollbar in this CSS javascript pop up window?

    How to glue the text of multiple divs together?

    How to center a text which is placed on an image

    How to customized select element through css?

    How to use Javascript in a innerHTML inline css scenario?

    How to select lowest level ul in nested ul in Javascript/ css

    How to Get Fixed Children to Play Nicely with their Parents

    Rails 4: How to style navigation for current page using jQuery

    How do I override inline CSS with Class CSS? [duplicate]

    CSS: how to apply margin to a container with floats?

    Creating a javascript notification plugin: How to align absolutely positioned divs on top of each other

    How to prevent randomly positioned images from overlapping using Angular

    Tumblr: How to control CSS with post tagging (UPDATE: Working Method without JQuery!)

    CSS + Show Animated GIF while Loads

    How to theorize about this phenomenon about
    tag

    How to fix maximum width of a div? If contents of that div's exceeds than maximum width, we get scroller?

    How can I resize a background-image to fit my element (without set width) in CSS 2?

    How to CSS pairs of DIV text left/right of center

    How to replace a Font Awesome icon within link text with a different icon on link click?

    How to make a HTML5 font lighter when fontWeight doesn't work? [closed]

    How to position a div differently for a specific page?

    Flex - understanding how to properly reference an image in a library project css file

    How to run CSS text animation in a sequence. (one line of text after another)

    How can I mix vertically-centered elements with different font sizes and retain consistent line height?

    How to modify programmatically with javascript the css ::before and ::after [duplicate]

    Does Modernizr.js help in showing css 3 and html 5 on older browsers and how?

    How can I make images stack on top of each other as web page scales down?

    How to get my navbar to fluidly contain the largest element?