Speeding up compass sass compilation with sprockets-sass - css

I am working with really big projects which are using compass(compass sprites tools including) sass framework cli tool(compass watch, compass compile) to create app.css file. Sass of the project is using multiple #import statements to include dozens on sass partials.
Problem is that app.css file is compiling for more than 2 minutes(app.css is 70000 lines long) after each small change in any sass partial imported into app.scss file compiling all of them at once while I need only 1 line change.
I made an extensive research and found articles like this one http://blog.teamtreehouse.com/tale-front-end-sanity-beware-sass-import which is suggesting to use spockets instead of #import to include sass partials. I like the solution more than most but big refactor will be needed even to test if it will work also all global includes like mixins and variables will need to be included in each sass partial used in the project which is also not ideal.
After some more research I have found this https://github.com/petebrowne/sprockets-sass tool which should automatically transform #imports into spockets require statements for compiler and also preserve ability of global imports.
The problem is I don't know ruby and did not use anything ruby related else then "gem install" statement )))
Can someone who knows ruby help me by explaining step by step how to make compass compiler work with sprockets-sass ?
P.S Please do not suggest solutions like libsass and it's like I have tested it by excluding all compass sprite related stuff and libsass also take a bunch of time to compile 40000 lines that remained without sprites(I suspect that part of the problem is not in compilation speed but in time system needs to create 400000 line file after).

The only thing that you can do is to split the output top-level file (app.css) into multiple output top-level files, and at the end of the compass-compilation reconcat them with a sprockets task!
This optimizes the usage of sass cache and the final concat-task is efficient because is a simple concatenation!
By the way, at the moment, compass is replaced with the EyeGlass Project made by Chris Eppstein the author of Compass.
So Consider the idea of a whole refactoring using (grunt/gulp) with libsass (A sass compiler built in C/C++) and EyeGlass that adds all compass-like features to sass!
hope Helps!

Related

Project structure in Julia with clean separation

I am trying to correctly configure julia project.
The project had initially:
One module in its own directory
Another "kind of module" in another directory, but there was no module keyword and it was patched together with help of includes.
A few files in the root to execute it all by just running "julia run.jl" for example.
No packages, no Project.toml no Manifest.toml - there is "packages.jl", which manually calls "Pkg.add" to for preset list of dependencies.
Not all includes were used to put it all together, there was some fiddling with LOAD_PATH
Logically the project contains 3 parts that I see there and something as I would see as "packages" in for example python world.
One "Common" module with basic util functions shared by all interested modules.
One module A, which has dependency on "Common".
Module B, which has dependency on A and "Common".
What I did is, I created 3 modules in their separate directories and to put it all together. These modules make sense internally and there is no real reason to expose them "outside". The whole code is in the end executable and there would be exposed probably just one function, that executes everything. I created loader file, which included all 3 module files. That way I got rid of LOAD_PATH and references in IDE started to work. This works for our purposes, but still isn't ideal. I have been reading quite a lot about Julia structure and possibilities - modules, packages, but still don't understand fully. And Revise doesn't work.
Is it correct to have modules like this? I like modules as they clearly set boundaries between modules using export lines.
I would also like to make the code as compatible with IDE as possible (LOAD_PATH settings didn't work for VS code and references to functions were broken) and also with Revise.
What is the typical structure for this?
How to clearly separate code while make the development easy?
How to make this work with Revise?
I expect it's good idea to make a package for this, but should I make it for the whole project? Then it would mean one "project" module and 3 submodules A, B and Common?
Or should it be 3(4) packages per module?
Thanks for any output. Comparison of some of the principles to Python/Java/kotlin/C#/Javascript module/packages could be helpful.
In CubicEoS.jl I've made a single package which provides two modules: CubicEoS with general algorithms and CubicEoS.BrusilovskyEoS with an implementation of necessary interface to make CubicEoS works on a concrete case. The last module depends on the first. Revise works well. As a user (not developer) of CubicEoS, I have scripts which run some calculations.
So, in your case, I would create a single package with four modules. The forth module is a hood for the others: Common, A and B. The possible file structure maybe like this
src/
TheHood.jl
Common/Common.jl
Module_A/Module_A.jl
Module_B/Module_B.jl
test/
...
examples/ # those may put out of here, but the important examples may be in test/
...
Project.toml
And, the possible module structure may be like this
# TheHood.jl
module TheHood
export bar
include("Common/Common.jl")
include("Module_A/Module_A.jl")
include("Module_B/Module_B.jl")
end
# Common/Common.jl
module Common
export util_1, util_2
using LinearAlgebra
util_1(x) = "util_1's implementation"
util_2(x) = "util_2's implementation"
end
# Module_A/Module_A.jl
module Module_A
import ..Common
export foo
foo(x) = "foo's implementation"
end
# Module_B/Module_B.jl
module Module_B
import ..Common
import ..Module_A
export bar
bar(x) = "bar's implementation"
end
Now, I'll answer the questions
What is the typical structure for this?
If the modules does not use independently, I would use the structure above. For small projects I've found "one package = one module" strategy painful when a core package updates.
How to clearly separate code while make the development easy?
In Julia, a module effectively is a namespace. In inner modules (like A, B, Common), I usually import the dev-modules, but use modules which a dev-module depends on (see above using LinearAlgebra vs import ..Common. That's my preference to clarify names.
How to make this work with Revise?
Turn the code into a package. That's preferable, because Reviseing of standlone modules is buggy (at least, in my experience). I'm usually using Revise like this
% cd where_the_package_lives # actually, where the project.toml is
% julia --project=. # or julia and pkg> activate .
% julia> using Revise
% julia> using ThePackage
After that I usually can edit source code and call the updated methods w/o restarting of the REPL. But, Revise has some limitations.
I expect it's good idea to make a package for this, but should I make it for the whole project? Then it would mean one "project" module and 3 submodules A, B and Common?
Or should it be 3(4) packages per module?
You should separate "scripty" (throughaway or command line scripts) and core (reusable) code. The core I would put in a single package. The scripty files (like examples/, CLI programs) should be alone using the package. The scripty files may define modules or whatever, but their users are endusers, not developers (e.g. running a script involves an i/o operation).
Just to end this.
The main thing I was missing and would save me a lot of time if I knew:
If you have your own package, it means the file src/YourPackage.jl will be "imported/included" once "using" keyword is being used and everything just works. No need to do any kind of import/LOAD_PATH magic.
just doing that fixed 95% of my problems. I ended up following patterns in accepted answer and also from the comment recommending DrWatson.
Only small thing is the fact that "scripts" don't work well with VSCode. "find all references" or "go to definition" and autocomplete don't work. They do work for everything within "YourPackage.jl" and it's imports perfectly and so does Revise. It's really tiny thing since scripts are usually like 3 lines of code.

Share a stylus sheet between packages

I've got an app broken into a handful of packages. Each of these packages has their own .styl sheet to style the components that specific package offers. Currently, these .styl sheets all rely on the same functions, mixins, and variables declared in the variables.import.styl that is in the ./client/styles folder. I do this because if I change the errorRed color in the variables.import.styl, it changes the color across all packages.
To get access to those variables, at the top of each package's stylesheet, I have a #import "./client/styles/variables.import". Alternatively, I could create a separate package for the stylus vars & then make that package a dependency in all the other packages. I don't love either option, but I suppose it's the price I pay to keep stylesheets separated by package. Anyone have a more elegant alternative?
It's worth noting that on the Meteor devel branch, my previous solution no longer works (stylus can't see folder above the package root). Regardless of whether this is fixed or not before the next version release, I know there's gotta be a cleaner solution.
As of Meteor 1.2, this is now a feature working out of the box, for both stylus and less stylesheets.
https://github.com/meteor/meteor/tree/devel/packages/stylus#cross-packages-imports
In your package.js Package.onUse section, use api.addFiles to declare stylus sheets provided by this package :
api.addFiles('styles/package-sheet.styl', 'client', {isImport: true});
Notice the isImport: true option ?
Then in your main app master stylus stylesheet you can import a specific package (let's suppose it's named my-username:mypackage) sheet using this syntax :
#import '{my-username:my-package}/styles/package-sheet.styl'
Note that for importing sheets within your app you will also need to use this new syntax, without any package name :
#import '{}/client/styles/app-sheet.styl'
The previous syntax will no longuer work !
// the Meteor build tool will complain about not finding the sheet
#import 'client/styles/app-sheet.styl'

How to build a function or mixin to check Sass or Sass library version

I'm building a Sass library and I want to let the user check both the library and Sass versions to see if he can safely output his code.
The library version is defined as a $variable on the index .sass file, and I wanted to use a function/mixin that could be like required_versions($library, $sass), where both arguments are the minimum required versions to be used on the project.
For Sass version checking, I saw this http://webdesign.tutsplus.com/articles/when-and-how-to-support-multiple-versions-of-sass--cms-20935, but I want something more acurate.
At first I thought I could use Version to get Sass version, and version_gt or version_geq to compare the versions stated in the function/mixin arguments with the Sass' Version :number and the library version defined on its index file, but these seem to be Ruby's only methods.
Is there a way to make something like this?

Adding custom include-path folders to LESS.build

I am currently using Sublime Text with LESS.build package to compile my .less files into CSS.
My current LESS.build cmd is:
"cmd": ["lessc", "screen.less", "${file_path}/screen.css", "--verbose"]
I tried to add some extra folders to the --include-path:
"cmd": [
"lessc",
"screen.less",
"${file_path}/screen.css",
"--verbose",
"--include-path='.:/var/www/whatever/'"
]
But, whenever i try to build my .less files the --include-path params seems to be ignored.
The only workaround i found is adding the full relative path on my #import:
#import "../../../www/whatver/config.less"; //Ugly solution
Can anyone point me where i am failing and/or any other workaround prettier than mine's?
Looks like there was a bug out for this. https://github.com/cowboyd/less.rb/issues/13
and there was a similar issue here LESS #import: Passing paths to lessc.

How can I add the "--watch" flag to this TextMate snippet?

I love TextMate as my editor for all things web, and so I'd like to use a snippet to use it with style.less files to automatically take advantage of the .less way of compiling .css files on the fly using the native
$ lessc {filepath} --watch
as suggested in the less documentation (link)
My (thanks to someone who wrote the LESS TM Bundle!) current TextMate snippet works well for writing the currently opened .less file to the .css file but I'd like to take advantage of the --watch parameter so that every change to the .less file gets automatically compiled into the .css file.
This works well when using the Terminal command line for it, so I am sure it must be possible to use it in an adapted version of the current LESS Command for TextMate since that only invokes the command to compile the file.
So how do I add the --watch flag to this command:?
#!/usr/bin/env ruby
file = STDIN.read[/lessc: ([^*]+\.less)/, 1] || ENV["TM_FILEPATH"]
system("lessc \"#{file}\"")
I assume it should be something like:
#!/usr/bin/env ruby
file = STDIN.read[/lessc: ([^*]+\.less)/, 1] || ENV["TM_FILEPATH"]
system("lessc \"#{file}\" --watch")
But doing so only crashes the TextMate.app.
Did you try running it as a background task?
system("lessc \"#{file}\" --watch &")
I'm guessing you have to put the --watch parameter before the file parameter to lessc, like so:
system("lessc --watch \"#{file}\"")
Take a look at this snippet. It doesn't use the --watch flag, but if you link it to the cmd+s key combination it works perfectly. The snippet will also compile any less files that reference (i.e. #import) the file that was changed. This is great if you have a until.less or something that you include in many different less files, if you change the util.less all the LESS files that depend on it will auto-compile.
Combine that script with the browser refresh script and you have a fairly decent web dev testing routine.

Resources