Include external JS in Rails asset pipeline that gets bundled during deploys - javascript

I reviewed this question already - Including external libraries using the Rails 3.1 asset pipeline - which is basically what I'm looking for with one caveat: I'd like to include the external url in the asset pipeline so that when I deploy to production, the external url gets bundled into a file with the other local files that were required.
More details:
My use case here is that I have found a plugin on GitHub that I like, and being a good member of the open source community, I'd like to help contribute back. The most time efficient technique that I'm considering is to fork the repo, then point my local project that needs that file to the raw source of the required JS file during development, but have that file get bundled with the rest of my application when I deploy to staging / production. This would allow me to keep the plugin tied closely to the parent project, but keep things on my own track so that I can decide when to merge in updates from the base project as well as submit any fixes I have back to the parent with easy pull requests.
With that said, I have not been able to find any documentation about how to do this with the current rails JS asset pipeline or if it is possible at all. Some quick tests locally point to the idea that this works in a css file but not for js files. Can anyone confirm if this is possible? Thanks!

I would use something like this custom rake task. Basically what you do is write that rake task into the beginning of your deploy script, but modified to put the file in your vendor/assets folder (or where ever you want that is pulled into the asset pipeline.)
That way you pull the requested file on deploy, but it's there in your code when your asset pipeline bundles everything up.
Here is the code in-case the link rots:
namespace :remote_file do
desc "Get a file from a remote server"
task :fetch do
# based on http://snippets.dzone.com/posts/show/2469
# http://farm1.static.flickr.com/92/218926700_ecedc5fef7_o.jpg
Net::HTTP.start("farm1.static.flickr.com") do |http|
resp = http.get("/92/218926700_ecedc5fef7_o.jpg")
open("fun.jpg", "w") { |file| file.write(resp.body) }
end
end

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 to deploy a backbonejs app to a production server.

I wrote a small single page application in BackboneJS and not sure how to get it into production. I typically use grunt serve command and it runs everything and displays to localhost:9000.
How do I do this on a production server so I can access the app from www.example.com.
Backbone apps are all static files man, so you can put it in a CDN or just have apache/nginx serve them as static files.. Doesnt get any simpler than that really.
Get a server
Install nginx/apache
Configure nginx/apache to use your example.com and link it your /path/www/your-backbone-app
Copy over your dist/ directory to /path/www/your-backbone-app
i really suggest you minify the hell out of your html/css/js since you said your backbone app is all one "page". Make 1 js file with everything inside (look into require.js and "r.js").
Profit!
Your best choice is to do it all in your computer: require.js can do all of this automated! ->. join and minify all that apply, change the html code to reflect the new minified names of the css and js, zip. Finally run this from the console scp -r ~/yourapp/dist/ server:/path/www/your-backbone-app. Greatest thing of all this is you dont have to do anything else after that command. Enjoy.

Adding javascript files to Yeoman webapp generated website

I am playing with the yoman trying to build a web site using the webapp generator.
If Managed to create a web site that works under grunt server, when I change a js file grunt notices the change change and does a live load and everything works as you would expect.
When I try a plan grunt, it attempts to run the dist task, it manages to include my html files, but skips any of the javascript or script files I created in the script and styles diretores. I assume its the case I have to tell grunt to includes these files
Files such as main.js seem to make it through, but there are no references to main.js in the Gruntfile, so I not sure which part of Gruntfile.js to change.
Doing a yo doctor reports
[Yeoman Doctor] Everything looks all right!
Q. How to do I tell grunt to include and user created files.
Q. I noticed that all my image files where renamed, fair enough how do I refer to a file that I known is going to be renamed in a javascript file
Q. Does anybody known a good web resource for yoman where these quesion might have already been answered?
Be careful on this glob pattern scripts/{,*}/*.js. This takes only the js files that are inside scripts or immediate child folders.
Make sure to change it to scripts/**/*.js to include all js files in all subfolders.
Also get an idea on tags build: css, build: js in your index.html, wiredep plugin used by Yeoman in gruntfile to understand what files will be injected into dist folder.

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.

VS2013: Publish minified bundle created on files outside of the project

I use Visual Studio 2013 and .NET 4.5 for an MVC project.
I've learning to use AngularJS via several videos on Pluralsight and one of them walks through the process of using Grunt to clean the output directory, then use ngmin to min-safe the Javascript files.
My process is using a gruntfile.js to clean and run ngmin against the javascript files in my solution, then put them in a directory called app_built. This is executed via a batch file in the pre-build for the project and then I include it via a ScriptBundle with IncludeDirectory pointing to the app_built directory. My intent is to use the Bundling features of .NET 4.5 to do the rest of the minification and concatenation of the Javascript after all the files have been min-safed via Grunt.
I specify the path to the min-safed files with the following:
bundles.Add(new ScriptBundle("~/bundles/minSafed")
.IncludeDirectory("~/app_built/", "*.js", true));
If I run this on my local machine, it runs fine without a hitch. The Javascript is minified and bundled as I'd expect and the resulting web application runs fine as well.
If I publish the website to a remote server, I get a server error that the "Directory does not exist. Parameter name: directoryVirtualPath". I assume this error is saying that it's unable to find the directory populated with my many *.js files. I also assume this is because they weren't published since they aren't part of the solution, even though the folder they reside in is a part of the solution (it's just empty within the solution explorer in Visual Studio).
If my assumption is correct, what can I do to add these files to my solution so they'll be published with the rest of my web application with minimal effort on my end each time?
And if I'm incorrect in the assumption, what I can I do to resolve this otherwise?
Thanks!
I never did find a great way of going about this. I found information at http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx that seems related, but I was unable to make it work.
Rather, since I knew the name of the outputted file, I simply created such an empty file in my project and referenced that where I needed to. I then had the pre-build task replace the contents of that file with the externally minified version and it would be packaged with the project as necessary, so it works well enough.

Categories