choosing assets sailsjs - javascript

I've started using SailsJS for a small web app and so far it's great.
However I'm struggling with the assets and layout.
Basically I would like to be able to use different type of assets (groups of css files) depending on the page.
For this, I wrote 2 different layouts, each should includes the correct css files.
However, when I add those files in the config/assets.js files there all bundled together.
Is there a way to specifiy in my layout which assets i want to use ?
I know you can specify assets.js or assets.styles but I would like to be able to create my own group .
I also tried to put those assets in a different directory (public for example) and load them manually in my layout. It's still not working because the server doesn't want to 'serve' them.
Any idea ?

Glad you're liking Sails :)
For now, you can (a) bring in all styles all the time and make only the relevant ones apply (b) use another tool (like Grunt) to bundle assets like you would in a vanilla node.js project or (c) link the stylesheets manually (put them in your public folder).
As for the roadmap-- the community is working on more options for serving templates/styles/client-side logic. There's an open spec here:
https://github.com/balderdashy/sails/issues/240
Hope that helps!

I know this is old, but in case anyone else comes across this; in recent versions of sails the asset pipeline is built around grunt by default (I haven't used sails before 0.10.x).
You can add your own exports in tasks/pipeline.js and link those to the appropriate location in tasks/config/sails-linker.js. E.g. you could have a views/public folder and tell sails-linker to inject publicCSS vars there. Then adjust your layout.ejs so that it imports the styles/javascript from whichever folder.

Related

Use of vendor folder in web design

I am starting to build a website from scratch using python, django, and bootstrap. I have noticed that many times js, css, img. and fonts are stored in a folder vendor, such as:
/static/js/vendor/bootstrap/bootstrap.min.js
/static/css/vendor/bootstrap/bootstrap.min.css
or something similar.
What is the benefit of this folder structure over something like:
/static/bootstrap/js/bootstrap.min.js
/static/bootstrap/css/bootstrap.min.css
In the first example, when using the vendor folder as I have often seen, I would have to download bootstrap and unpack the downloaded folder into the js and css vendor sub-directories. In the second example, I can download bootstrap and drop the downloaded folder into /static without having to unpack anything.
It clearly marks which files are third-party libraries that should not be edited directly.
The vendor folder is where you usually (I'm using the word 'usually' because it's not exactly a rule but more of a preference in the coding community with the purpose of having a semantic directory structure) keep third-party resources(icons, images, codes, you name it) as opposed to a lib (library) folder where you or the author of the site/application to be specific keep your original codes in.
So if I were to download and use the site/application in the hypothetical scenario above, I can then create relevant folders for each data type (src/images for images, style/css for css, script/js for js, etc) and move required assets from the lib folder to the new folders without having to edit the third-party codes (or other assets) thus making it easier to rollback on any changes made that cause errors and such.

Dynamically load JS/CSS per template with Meteor

I understand a couple questions (i.e. this) of this nature have already been posted, however no solid solution has been found. From what it seems, Meteor currently lacks of the ability to dynamically load/render different UI JavaScript (i.e. uilang) or CSS files per template. In my application, I have templates that require specific JS libraries and CSS as oppose to other templates.
For example:
user.html requires -> uilang.js, user_ui_code.js, userstyle.css
admin.html requires -> uilang.js, admin_ui_code.js, admin_style.css
I would need each js/css file to render/load depending on which route gets requested (i.e. example.com/user or example.com/admin), for things like different background-colors, transitions, etc. Meteor documentation states:
Files in /public are served to the client as-is. Use this to store assets such as images. For example, if you have an image located at /public/background.png, you can include it in your HTML with or in your CSS with background-image: url(/background.png). Note that /public is not part of the image URL.
So you would think that putting all your js/css/images assets in public and calling the needed files statically in head would solve the problem. Instead, it seems that the JS (CSS as well) files get concatenated and it all runs at the same time regardless of which route you are on, thus overlapping code. I'm not sure if I am missing something blatantly obvious or is this an actual issue in Meteor?
Thanks for any help.
Meteor doesn't yet support lazy/on demand loading of resources. The feature is on the roadmap as "incremental loading".
In the meantime, have a look at numtel:publicsources and numtel:privatesources, which let you create bundles for lazy loading resources, with or without authentication.

Bundles and Virtual Paths

I am setting up a new site using angular, mvc and web api. The static content (js, css, images, etc) will be in Site A, the MVC site will be in Site B and the api will be in Site C. These are all separate sites, not virtual directories. I'm trying to use bundling in the MVC site to bundle the js and css files from the static site for use in the MVC site.
I've set up a Virtual Path Provider but when I load the site angular doesn't work and also doesn't throw any errors. I'm assuming that the angular.js file is not being loaded from the bundle because if I include a local javascript file angular works.
Is what I want to do possible? If so, how?
Virtual Path Providers only apply to views, not things like CSS and JS. Unfortunately, there's not really a good way to handle this scenario. The bundler can only act on files within the same project, not those in a separate project. If you want a separate site to handle your static assets, then you pretty much just have to resort to referencing them directly. You can use the Web.config's app settings section to set the base URL for your static site (that way you have just one place to go if you need to change it later and you can do things like run transforms on it to have a different value in production). This also means you're somewhat on your own for bundling and minification. However, you can make your static site an MVC site as well just to get the bundling infrastructure and then use that site to handle bundling. All your bundles should be at the standard location of /Content/[style bundle name].css or /bundles/[script bundle name].js. There's a cache busting string added to the path, but you can somewhat handle that manually.

Best way to keep files that are used in multiple projects in sync?

I have a few files called "helpers.scss", "helpers.js" and "consolerules.js" that I use in every one of my projects. When I'm working on a project I'm modifying one of the files, for example I will add a function for replacing all strings within a strings into "helpers.js" but then when I open my other project I don't have that function.
Or I will add a helper css class in helpers.scss in the other project and I don't have it in the other projects.
What is the best way so I can always keep them in sync when I edit them in one of the projects? I was thinking of bower, gists, git, dropbox, google drive or something like that ...
I used two ways to handle these:
Get a CDN like server
Have a single version of those files and place them on a server. For example you could have URLs such as:
https://cdn.example.com/css/helpers.css
https://cdn.example.com/js/helpers.js
If you want to support versions (maybe you should?), you can add that to the filename:
https://cdn.example.com/css/helpers-1.3.css
https://cdn.example.com/js/helpers-1.2.js
Or to the path if you view all your files as having one common version:
https://cdn.example.com/1.2/css/helpers.css
https://cdn.example.com/1.2/js/helpers.js
Versioning is useful if you want to test a website with the newest version before using that version on your live site.
This is most certainly the easiest way if you can implement it that way. Now all your other websites will use those URLs instead of local versions of the files:
<link type="text/stylesheet" href="https://cdn.example.com/1.2/css/helpers.css"/>
Pull those files at build time
Depending on how you organize your websites (it is really not clear from your questions) and assuming you have folders on your machine with the original source, you can bring in those files as required with a script that you run before you upload your sites.
In my case, I like to do that in three steps:
I write the files
I copy the files to a .../build/... folder
I send the .../build/... folder to my test or production server
One reason for this is to generate a build folder that includes exactly what you want, verify it, then send it to your server. That verification happens only when you write your script. Once done, it should not require any additional work.
So... one reason to get such a script is that I can compile my files. For example, if you write PHP code, the servers only need the most compressed version of your code (unless you are debugging and need to find line numbers...) The script that generate the build folder could do:
for p in php/*.php
do
php -w $p build/$p
done
Now your PHP code on your server may be something like 20% smaller.
Similarly, you could copy your helper.css file as in:
cp ../helper-project/css/helper.css build/public_html/css/.
This copies the helpers.css file to your build folder. Since it grabs that file from your unique ../helper-project folder, you will always end up with the latest.
And instead of a simple cp command, you could also minimize that file at the same time:
cleancss --remove-empty ../helper-project/css/helper.css > build/public_html/css/.
The only problem here is that if you make changes to the helper-project, it won't automatically update all the projects. You still have to do in each project and run the script(s) that generate the build folder and copy that to your servers. Yet, I find that to be a practical way of doing things because that way I know when I do the update and I can test the resulting website(s) before going to production and once I update a production site, I can verify that it's still all working just fine.
You can do this with git (or any modern VCS); I assume you are using some sort of VCS for your code.
If you have a project being managed in git, you can even add multiple remotes, such that you can pull in code from multiple sources.
If you are using a VCS like git, then it is just a matter of doing a git pull <remote ref> <branch ref> whenever you want to sync up.
Otherwise, the comments to your question offer some alternatives.

How do you manage your Javascript files?

Nowadays, we have tons of Javascript libraries per page in addition to the Javascript files we write ourselves. How do you manage them all? How do you minify them in an organized way?
Organization
All of my scripts are maintained in a directory structure that I follow whenever I work on a site. The directory structure normally goes something like this:
+--root
|--javascript
|--lib
|--prototype.js
|--scriptaculous
|--scriptaculous.js
|--effects.js
|--..
|--myOwnScript.js
|--myOwnScript2.js
If, on the off chance, that I'm working on a team uses an inordinate amount of scripts, then I'll normally create a custom directory in which we'll organize scripts by relationship. This doesn't happen terribly often, though.
Compression
Though there are a lot of different compressors and obfuscators out there, I always come back to YUI Compressor.
Inclusion
Unless a site is using some form of a master page, CMS, or something that dictates what can be included on a page beyond my control, I only included the scripts necessarily for the given page just for the small performance sake. If a page doesn't require any script, there will be no script inclusions on that page.
First of all, YUI Compressor.
Keeping them organized is up to you, but most groups that I've seen have just come up with a convention that makes sense for their application.
It's generally optimal to package up your files in such a way that you have a small handful of packages which can be included on any given page for optimal caching.
You also might consider dividing your javascript up into segments that are easy to share across the team.
Cal Henderson (of Flickr fame) wrote Serving JavaScript Fast a while back. It covers asset delivery, not organization, but it might answer some of your questions.
Here are the bullet points:
Yes, you ought to concatenate JavaScript files in production to minimize the number of HTTP requests.
BUT you might not want to concatenate into one giant file; you might want to break it into logical pieces and spread the transfer cost over several pages.
gzip compression is good, but you shouldn't serve gzipped assets to IE <= 6, so you might also want to minify/compress your JavaScript.
I'll add a few bullet points of my own:
You ought to come up with a solution that works for both development and production. In development mode, it should pull in extra JavaScript files on demand; in production it should bundle everything ahead of time. Switching from one behavior to the other should be as easy as setting a flag.
Rails 2.0 handles all this through an asset cache; other web app frameworks might offer similar solutions.
As another answer suggests, placing third-party libraries in a lib directory is a good start. You can also divide your own JS files into sub-directories if it makes sense. Ideally, you'll be able to arrange them in such a way that the files in a given sub-directory can be concatenated into one file.
I will have a folder for all javascript, and a sub folder of that for 3rd party/shared libraries, and sub folders for each component of the site to keep everything organized.
For example:
/
+--/javascript/
+-- lib/
+-- admin/
+-- compnent1/
+-- compnent2/
Then run everything through a minifier/obfuscator during the build process.
I'v been using this lately:
http://code.google.com/apis/ajaxlibs/
And then have a "jscripts" folder where I keep my custom code.
In my last project, we had three kinds of JS files, all of them inside a JS folder.
Library code. A bunch of functions used on most all of the pages, so they were put together in one or a few files.
Classes. These had their own files, organized in folders as needed, but not necessarily so.
Ad hoc JS. Code that was specific to that page. These were saved in files that had the same name as the JSP pages they were supposed to run in.
The biggest effort was in having most of the code on the first two kinds, having custom code only know what to call, and when.
This might be a different approach than what you're looking for, but I've been playing around with the idea of JavaScript templates in our blog engine. In a nutshell, you assign a Javascript template to a page id using the database and it will dynamically include and minify all the JavaScript files associated with that template and create a file in a server-side cache with the template id as a file name. When a page is loaded, it calls the template file which first checks if the file exists in the cache and loads it if it does. If it doesn't exist, it creates it on the fly and includes it. I also use the template file to gzip the conglomerate JavaScript file.
The template idea would work well for site-wide JavaScript (like a JavaScript library), but it doesn't cover page-specific JavaScript. However, you can still use the same approach for page specific JavaScript by including a second file that does the same as above.

Categories