Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix for hashing issue with multiple SASS or CoffeeScript files. Fixes #107, #98, #99 #110

Merged
merged 2 commits into from

4 participants

@STRML

A quick fix to the hashing strategy in the preprocessors - use contents of all files of like type, append current file contents.

This ensures that each root file is recompiled if it or its dependencies change, but each root file has a unique hash. This prevents the hash collisions that caused #107 and #98.

The hashing strategy could be faster for .coffee files (no includes, so this should be simple to fix). It could be smarter for SASS/LESS if we traced down the @import paths but that is considerably more work to save a half a second or two in development.

@stefanoverna

Thanks @STRML, great idea, but I'd rather keep the modification times and append just the file name at the end. As explained on #99, this way we can preserve faster compilation times on development, fix #98 and #107, without supporting the idea that asset caching should work in production :) Could you make these changes?

@STRML

Ah I missed your recent comment on that. I can revert it back to date parsing and append the filename instead of the file contents.

What is the current production strategy, then? I have been using wordless compile but I have to manually delete the compiled files in my development environment as they are not overwritten when the source changes.

@stefanoverna

Yeah, I know. I usually do a simple deploy.sh script which is something like this:

wordless compile
wordmove push
rm public/stylesheets/application.css
rm public/javascripts/application.js

The same could be easily done ie. with capistrano.

@stefanoverna stefanoverna merged commit dd48f89 into welaika:master
@STRML

I see. I've been using a simple couple of git hooks:

pre-commit

#!/bin/sh
#
# Compiles SASS & CoffeeScript before commit.
# Requires Wordless, Sprockets, and Compass.
# To get these, 'sudo gem install wordless sprockets compass'
#
WORDLESS=/usr/bin/wordless

$WORDLESS compile
git add ./wp-content/themes/themeName/assets/stylesheets
git add ./wp-content/themes/themeName/assets/javascripts

post-commit

#!/bin/sh
#
# Removes compiled Wordless files so they don't get in the way of development.
#

rm ./wp-content/themes/themeName/assets/stylesheets/screen.css
rm ./wp-content/themes/themeName/assets/javascripts/application.js
rm ./wp-content/themes/themeName/assets/javascripts/social.js
rm ./wp-content/themes/themeName/assets/javascripts/newsletter.js
rm ./wp-content/themes/themeName/assets/javascripts/single.js

Unfortunately this doesn't really 'scale' as you have to maintain these lists manually. But it's at least a little bit of optimization.

@endorama

This could be solved with a little change in the wordless directory structure. My proposal is to add a assets/vendor folder in which you can add vendor javascripts and stylesheets, so that you can safely remove everything inside assets/stylesheets and assets/javascripts.

New directory structure:

theme/
  assets/
    stylesheets/
    javascripts/
    vendor/
      stylesheets/
      javascripts/

Could be a valid solution? Also I think that separating vendor files from theme ones leads to a better organization...

@Arkham
Owner

I think this problem can be solved by the latest versions of the wordless gem (https://github.com/etienne/wordless_gem), since it supports wordpress compile and wordpress clean; moreover, it also supports a wordless deploy command which can execute a custom deploy command. The cherry on top of the cake is the refresh option: wordless deploy -r, will compile your static assets, launch the custom deploy command and then clean those assets to clean the development environment.

Here's an example of the Wordfile:

wordless_repo: 'git://github.com/welaika/wordless.git'
static_css:
  - 'wp-content/themes/mytheme/assets/stylesheets/screen.css'
  - 'wp-content/themes/mytheme/assets/stylesheets/print.css'
static_js:
  - 'wp-content/themes/mytheme/assets/javascripts/application.js'
  - 'wp-content/themes/mytheme/assets/javascripts/mobile.js'
deploy_command: 'wordmove push -du'

Note that since Wordless is opinionated, you don't actually need to specify the assets if you are just using screen.css and application.js ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
2  wordless/preprocessors/compass_preprocessor.php
@@ -44,6 +44,8 @@ protected function asset_hash($file_path) {
foreach ($files as $file) {
$hash_seed[] = $file . date("%U", filemtime($file));
}
+ // Concat original file onto hash seed for uniqueness so each file is unique
+ $hash_seed[] = $file_path;
return md5(join($hash_seed));
}
View
2  wordless/preprocessors/less_preprocessor.php
@@ -39,6 +39,8 @@ protected function asset_hash($file_path) {
foreach ($files as $file) {
$hash_seed[] = $file . date("%U", filemtime($file));
}
+ // Concat original file onto hash seed for uniqueness so each file is unique
+ $hash_seed[] = $file_path;
return md5(join($hash_seed));
}
View
2  wordless/preprocessors/sprockets_preprocessor.php
@@ -40,6 +40,8 @@ protected function asset_hash($file_path) {
foreach ($files as $file) {
$hash_seed[] = $file . date("%U", filemtime($file));
}
+ // Concat original file onto hash seed for uniqueness so each file is unique
+ $hash_seed[] = $file_path;
return md5(join($hash_seed));
}
View
4 wordless/preprocessors/wordless_preprocessor.php
@@ -92,12 +92,12 @@ protected function comment_line($line) {
*
*/
protected function asset_hash($file_path) {
- // First we get the file content
+ // First we get the file's modified date
$hash_seed = date("%U", filemtime($file_path));
// Then we attach the preferences
foreach ($this->preferences_defaults as $pref => $value) {
- $hash_seed .= $pref . '=' . $this->preference($pref) . ';';
+ $hash_seed .= $pref . '=' . (is_array($this->preference($pref)) ? implode(" ", $this->preference($pref)) : $this->preference($pref)) . ';';
}
return md5($hash_seed);
Something went wrong with that request. Please try again.