Using Yeoman/Brunch tools with a hybrid Django/Backbone app? - javascript

I'm building a hybrid web application with Django on the back end and Backbone on the front end.
The structure is as follows: I generate all the HTML in Django templates, use request.is_ajax to decide which templates to return, and use Backbone to pull in HTML as needed (I do this because I want to support non-JavaScript users).
Anyway, my question is this. As my JavaScript code gets more complex, I would like to be able to do the following things automatically:
Asynchronous JavaScript loading
Concatenating and minifying CSS files
Concatenating and minifying JavaScript files
JS-linting
I'm not too worried about image optimisation or package management. Is this possible with the setup I have? Currently it's a standard Django app:
/media
/js
main.js <-- Backbone code is in here
/plugins
backbone.js
underscore.js
/css
main.css
results.css
/img
/myapp
admin.py
models.py
views.py
/templates
/myapp
index.html <-- references to all JS and CSS files here
I'm not sure if I should be using Yeoman (or just grunt) or Brunch, or if there's a simpler way. Whatever I use, I am not sure if can just drop it into the js directory, or if the location of the templates will complicate things.
Currently I know how to use require.js to load the JS asynchronously, but I don't know how to concatenate, lint etc - hence looking for a tool. Maybe I should just write a shell script :)

I can advice to start with simply brunch. Brunch is simpler than grunt, because its plugins work reasonable out-of-box, without the need to write 500-lines-of-code-gruntfiles. It it also much faster, recompilation of your app will be done instantly.
Your setup shall look like this
public/ # The directory with static files which is generated by brunch.
app.js # Ready to be served via webserver.
app.css # Don’t change it directly, just run `brunch watch --server`.
assets/ # And then all changed files in your app dir will be compiled.
images/
frontend/ # Main brunch application directory. Configurable, of course.
app/ # Your code will reside here.
assets/ # Static files that shall not be compiled
images/ # will be just copied to `public` dir.
views/ # Create any subdirectories inside `app` dir.
file-1.js # JS files will be automatically concatenated to one file.
file-2.js # They will be also usable as modules, like require('file-2').
file-1.css # CSS files will be automatically concatenated to one file.
stuff.css # JS and CSS files may be linted before concatenation.
tpl.jade # You may have pre-compiled to JS templates. Also with `require`.
vendor/ # All third-party libraries should be put here. JS, CSS, anything.
scripts/ # They will be included BEFORE your scripts automatically.
backbone.js
underscore.js
package.json # Contains all brunch plugins, like jshint-brunch, css-brunch.
config.coffee # All params (you can concat to 2, 5, 10 files etc.)
# are set via this config. Just simple, 15 lines-of-code config.
To create new app, take a look at brunch skeletons which are like basic boilerplates. Pick any, then use brunch new --skeleton <url>, launch brunch watcher with brunch watch --server and you’re ready. When you will want to deploy your app, simply build stuff with brunch build --optimize which will automatically minify files.

I can advice to start with simply grunt. There are grunt task for all your needs:
grunt-contrib-usemin will replaces references to your original files with optimized vers
grunt-contrib-uglify will minify your JavaScript
grunt-contrib-mincss will minify your CSS
grunt-contrib-jshint runs jshint on your JavaScript files
use requireJs to load your files ansynchronous and grunt-contrib-requirejs to compile the files into one file if needed

Related

Webpack 2: Watch external files

I have a project that uses source files external to the project. Effectively, there is the actual project source code (an Typescript/Angular 2 application, lets call it the 'core' stuff), and this is a generic web application that is meant to be the base code that consumes these external source files.
The external files include additional stuff-- that could be SCSS files, images, evn additional JS. The way I want this to work is that webpack copies these external files from any source directory (this is critical, it is not part of the core project) to a local .tmp directory. The files in the .tmp directory are worked on along with the core src files to generate the prod output.
I can't figure out how to add these additional external source files to the watch list. Effectively what I'm looking to do is watch that directory and as things change, it re-copies the affected files to the local .tmp directory and triggers a recompile.
Presently I have to restart webpack and have a very very ugly solution using Grunt to watch the additional files. It's nasty but these kinds of workarounds have historically been what I've had to do with webpack.
Does anyone have a better solution? Ideally I'd like to not have to mix grunt with webpack. Webpack should be able to do this, but its hard to know whether there's an existing plugin for this or what the best approach would be.
Also, please spare the "look for it on google" or "read the docs" comments. I've combed through it all, hard, and have not found anything.
Thanks in advance.
As of now Webpack doesn't watch external files out-of-the-box . You need a plugin for that.
Basically idea is to have a file watcher module chokidar / watch , listening to the file change , and when there is a change, restart the webpack compilation phase . Webpack plugins can access the compilation object and we you need to hook it to a compiler phase i.e. 'emit' , 'after-emit' etc.
This Webpack plugin exactly solves your problem - https://www.npmjs.com/package/filewatcher-webpack-plugin .

How can I minify and concatenate a dir full of JavaScript files?

I'm working on a legacy Ruby on Rails 4 codebase.
It contains hundreds of .js files...
$ find app/assets -name '*.js' | wc -l
268
In production mode, it isn't so bad because the Rails Asset Pipeline minifies them and concatenates them into one file.
But in development, page refreshes take an extremely long time.
I don't think they need to load in a specific order, but I'm not 100% sure.
I want to compile (minify and concatenate) only a specific subdir (recursively) of JavaScript files in development mode.
Is there some tool I can point at a dir and output one minified .js file?
Ideally, this would be something that could watch a dir and recompile on changes.
I suspect that maybe Browserify or Webpack might be able to do that, but it isn't obvious to me from the docs how it would work in practice.
You can use Grunt to concat/minfy all your js(or a subset). However, if you update one, you need to recompile manually.
http://gruntjs.com/

Grunt uglify - replace original file

I have an angular application that uses require.js to load all scripts. The application is deployed to the web server using Hudson CI. When the deploy job runs, I want to:
Minify all JavaScript files but preserve the original file names so that the require.js config file works out of the box.
Have an option to exclude specific JavaScript files while running uglify.
The JS files are distributed all across the application, which has an ontology similar to the following:
app/
common/
controllers/
factories/
services/
assets/
js/
Is there a way to do this?
you need grunt-contrib-uglify
for the excluding files requirement:
http://gruntjs.com/configuring-tasks#files

Deployment Strategy for Require JS Optimized/Concatenated Website Files

My question is partly technical and partly about deployment strategies and workflow. I built a project using Require JS. It includes a number of distinct js modules, and is built upon Kirby CMS. The directory structure of the project is something like this:
project
assets
styles
style.css
js
scripts
script1.js
script2.js
script3.js
vendor
app.js
images
fonts
content
...
kirby folders
....
The file app.js is called in the footer of my site's page like so:
<script data-main="/assets/js/app" src="/assets/js/vendor/require.js"></script>
It configures RequireJS by calling the requirejs.config() function and then calls the main script file that loads everything else using RequireJS's requirejs() function.
I've used RequireJS' s optimization tool to compile the project in such a way that the optimized files are all dumpted into a directory called dist (a name I just picked up from this tutorial). So in the end dist contains a replication of every directory and file under assets, only optimized, and the file app.js is a concatenated and optimized version of all the js modules that I have in the project. So far so good.
What I am unsure about, however, is how I'm the supposed to make use of this new secondary version of all the code. What for instance if I want to deploy a version of the site to the production server without all the source js files? Each time I deploy the site, I would need to go through my code and in every place that I referred to files under the assets directory, I would need to replace that with dist. I deploy using git and beanstalk. One way to do this would be to manage different branches for staging, production, and development, in which the production and perhaps staging branches have references to the files under dist, but this seems awkward.
So my question is given this kind of optimization set up, which if you look at the tutorial linked above is one way to do this, how then do you manage the switch to the optmized version of everything seemlessly, without having to go back into your code and change everything up? Is there some key part of the process that I'm missing here?
Each time I deploy the site, I would need to go through my code and in every place that I referred to files under the assets directory, I would need to replace that with dist.
I've looked at the tutorial you've linked to and do not see how it is true for the tutorial. The tutorial does not use absolute paths, so should be deployable from dist just as well as from the directory that contains the pre-optimization sources. If you cannot do this for your application, that's because you've done something different from the tutorial. Your script tag, for instance, shows absolute paths.
So the solution is to design your application to avoid absolute paths. This way, you won't have to change paths when you deploy from dist. I'm using this very method to deploy optimized and non-optimized versions of one of my apps.

Not precompile on certain assets - Rails

I have a RoR project in which i have several assets that i don't want them to be precompiled in production mode. These assets are compound by JS/CSS files and currently they are placed under app/assets/javascript/ism/.
Actually, it's the whole ism folder which i don't want to compile. Though in development mode it's useful and comfortable to keep those files there to work with them, in production mode they shouldn't be there. In production mode those files are all compiled (externally) in a separate file which is served by S3 ant not from RoR/Nginx. The externally compiled file is even linked manually, not by RoR.
<script type="text/javascript" src="http://s3.blabla.com/file_compiled.js"></script>
So, what should it be the best way?
It's less than perfect, however you can prevent these files from being compiled by moving the ism directory out of the asset pipeline and serving them statically. E.g moving /app/assets/javascript/ism/ to /public/ism/.
If you don't want these files on production at all, you could simply add public/ism/* to your .gitignore file (assuming you're using git).

Categories