It's not clear to me from the docs and guides whether the following is feasible with Opal:
I've written a builder gem which implements an API to build an object tree which is then written to XML (or AIXM to be exact, an aeronautical format). There are currently runtime dependencies, but I could get rid of those.
There's a guide on configuring gems for Opal, however, is it possible to use an opalized gem in a JavaScript project? Or convert it to a Node package?
We are currently in a process of designing a good NPM integration. But as of now, yes. You can build an Opal project to a .js (or .mjs) file and require it in the Node environment.
One issue though: Opal does not behave well in the JS environment, as it defines globals, modifies prototypes, etc. - it may cause a mess, though most incompatibilities have been sorted out over the years (in any case, you may consider running Opal code in a WebWorker). The main issue here is that such a package will inadvertently include opal corelib - and you should take care to include it just once. So, your Opal part of the application should be compiled together, not split together into multiple packages. We will work on correcting that issue in the following months.
As for interfacing Opal from JS, you should take a look at this: https://github.com/opal/opal/blob/master/docs/compiled_ruby.md#ruby-from-javascript
Related
I was reading the Rails webpacker gem documentation where it says:
Webpacker makes it easy to use the JavaScript pre-processor and bundler webpack 4.x.x+ to manage application-like JavaScript in Rails. It coexists with the asset pipeline, as the primary purpose for webpack is app-like JavaScript, not images, CSS, or even JavaScript Sprinkles (that all continues to live in app/assets).
However, it is possible to use Webpacker for CSS, images and fonts assets as well, in which case you may not even need the asset pipeline. This is mostly relevant when exclusively using component-based JavaScript frameworks.
I'm trying to understand the rationale behind using both the older assets pipeline for CSS/images/JS-sprinkles if webpacker is capable of handling all of this?
I've read some other articles that walk me through using webpacker for all of this, but I don't understand the reasoning behind this decision.
Is this just to support legacy applications and eventually the older assets pipeline will go away and webpacker will be used for everything in Rails apps?
As a maintainer of an app that existed before Webpacker, I can give you one reason:
It's hard to migrate an existing frontend from Sprockets to Webpack.
Sprockets builds all JS into one big file with shared scope. Webpack isolates the scope of every JS module. To migrate to Webpack, you need to make sure your code still works with the scope isolation.
Which is often problematic, because in the Sprockets times you didn't have proper JS requires, either, and had to rely on globals or top-scope variables to share code and data between your JS source files.
Rails doesn't offer a painless transition path from Sprockets compilation to Webpack. So, it must support both.
But to answer your other question - going forward, you should use Webpacker if you have enough JS to make it worthwhile.
If your frontend is simple, you will skip some JS nuisances if you use Sprockets. Like if you want to add 10 lines of JS to your app, you might not want to setup a whole JS environment with dependency management and node_modules etc - which is the price of using Webpack/Webpacker. It would be even more senseless to manage a JS environment if all you want is to compile CSS and add digests to your image filenames - which Sprockets is perfectly capable of, without a package.json and anything else JS related.
Therefore, there's a second reason:
Webpacker is good for apps that have a significant frontend codebase. Sprockets is good for adding a bit of JavaScript to a traditional server-rendered app, and for apps with no JavaScript at all.
I don't have experience in front-end but I want to create a simple app using Angular 2.
Why do I need to install Node.js as a prerequisite step? Why does Angular use Node.js?
There are a couple of things that Angular uses Node.js for:
Installing and managing packages. From the Quickstart tutorial:
Angular application developers rely on the npm package manager to install the libraries and packages their apps require. The Angular team recommends the starter-set of packages specified in the dependencies and devDependencies sections.
Compiling the TypeScript used into JavaScript that the browser understands - browsers can't process TypeScript natively and the SystemJS imports used in your code aren't supported in browsers yet:
We strongly recommend transpiling (AKA compiling) to JavaScript during a build phase before running the application for several reasons including:
We see compiler warnings and errors that are hidden from us in the browser.
Precompilation simplifies the module loading process and it's much easier to diagnose problems when this is a separate, external step.
Precompilation means a faster user experience because the browser doesn't waste time compiling.
We iterate development faster because we only recompile changed files. We notice the difference as soon as the app grows beyond a handful of files.
Precompilation fits into a continuous integration process of build, test, deploy.
node.js is required in order to install the library using the node package manager (npm).
It is not required to run an app using angular2, only to build it.
For any modern JS based application, as the complexity grows, the app becomes difficult to manage.
In order to make developing and managing complex applications simpler, there are frameworks such as Angular, React etc. and they provide number of tools for the same.
These tools are linting, scaffolding, running unit test cases, starting web server for local development, minify and creating build for the production use etc.
These tools are based on NodeJS as it is JavaScript only and therefore can be customize as per developers needs.
And that's the reason you need Node.js for Angular2 development.
I would like to upgrade my existing Rails and Angular 1.x application. I'm following the ng-upgrade documentation and seeing that there are many dependencies including systemjs, typescript, tsd and a few other javascript libraries. Ideally there would be a angular-2 gem that would have all the dependencies but I'm not able to find that. Next I looked for gem's for each dependency but there isn't one for tsd.
Does it make sense to switch over to a custom build strategy so I can use npm for javascript package management? I read this article that recommends gulp but I do like the convenience of the asset pipeline.
Can anyone point me to examples of successfully using ng-upgrade with a rails project? Does it use a custom build solution like gulp or does it use the asset pipeline?
My main suggestion is not upgrading yet to Angular2, is still heavily in development and you'll face a lot of this issues like not finding a gem for rails.
Anyway, currently, angular2 can't be compiled with sprockets (the default rails pipeline), so you really want a custom solution.
My main suggestion is go with webpack, other options are browserify or gulp (and others), that's mainly a matter of taste. Overall, configuring a pipeline for angular2 is complicated, you have to take care of .d.ts files through typings (which is the updated version of tsd which now is deprecated), you have to transpile your typescript through tsc and possibly through babel too if you want to use async/await (which are really cool). You'll lose the ability to reference to your files in rails like image_path and such, using a custom pipeline, so you want to take that into account too.
Typescript is much more complex to compile than simple coffeescript files, you depend on every other file it reference, since it needs to compile check against it, don't expect something straightforward.
That being said, if you really want to work with Rails and Angular (2 or not), the right way to handle it is to have two separate projects, one with only the Rails app and one with the AngularJS path. In this way you separate concern, you can have a custom pipeline for Angular2 without impacting Rails and you'll be forced to correctly code your Angular2 app by using Rails as a JSON API, as you should.
My solution was to keep it as simple as possible without using webpack or the asset pipeline. I put the ts files in public and configured rails to serve the npm assets through the pipeline.
I put up a starter project with this structure as an example: https://github.com/jonnysamps/rails-ng2-starter
In many ways it has the benefits of having separate backend/frontend projects but keeps all the code together.
use angularjs gem
gem 'angularjs-rails', '~> 1.4', '>= 1.4.8'
insert into application.js
//= require angular
You can use http://bower.io/#install-bower and you can add two files to your the rails app .bowerrc and bower.json which is like GemFile
If I have a node.js application that is filled with many require statements, how can I compile this into a single .js file? I'd have to manually resolve the require statements and ensure that the classes are loaded in the correct order. Is there some tool that does this?
Let me clarify.
The code that is being run on node.js is not node specific. The only thing I'm doing that doesn't have a direct browser equivalent is using require, which is why I'm asking. It is not using any of the node libraries.
You can use webpack with target: 'node', it will inline all required modules and export everything as a single, standalone, one file, nodejs module
https://webpack.js.org/configuration/target/#root
2021 edit: There are now other solutions you could investigate, examples.
Namely:
https://esbuild.github.io
https://github.com/huozhi/bunchee
Try below:
npm i -g #vercel/ncc
ncc build app.ts -o dist
see detail here https://stackoverflow.com/a/65317389/1979406
If you want to send common code to the browser I would personally recommend something like brequire or requireJS which can "compile" your nodeJS source into asynchronously loading code whilst maintaining the order.
For an actual compiler into a single file you might get away with one for requireJS but I would not trust it with large projects with high complexity and edge-cases.
It shouldn't be too hard to write a file like package.json that npm uses to state in which order the files should occur in your packaging. This way it's your responsibility to make sure everything is compacted in the correct order, you can then write a simplistic node application to reads your package.json file and uses file IO to create your compiled script.
Automatically generating the order in which files should be packaged requires building up a dependency tree and doing lots of file parsing. It should be possible but it will probably crash on circular dependencies. I don't know of any libraries out there to do this for you.
Do NOT use requireJS if you value your sanity. I've seen it used in a largish project and it was an absolute disaster ... maybe the worst technical choice made at that company. RequireJS is designed to run in-browser and to asynchronously and recursively load JS dependencies. That is a TERRIBLE idea. Browsers suck at loading lots and lots of little files over the network; every single doc on web performance will tell you this. So you'll very very quickly end up needing a solution to smash your JS files together ... at which point, what's the point of having an in-browser dependency resolution mechanism? And even though your production site will be smashed into a single JS file, with requireJS, your code must constantly assume that any dependency might or might not be loaded yet; in a complex project, this leads to thousands of async load barriers wrapping every interaction point between modules. At my last company, we had some places where the closure stack was 12+ levels deep. All that "if loaded yet" logic makes your code more complex and harder to work with. It also bloats the code increasing the number of bytes sent to the client. Plus, the client has to load the requireJS library itself, which burns another 14.4k. The size alone should tell you something about the level of feature creep in the requireJS project. For comparison, the entire underscore.js toolkit is only 4k.
What you want is a compile-time step for smashing JS together, not a heavyweight framework that will run in the browser....
You should check out https://github.com/substack/node-browserify
Browserify does exactly what you are asking for .... combines multiple NPM modules into a single JS file for distribution to the browser. The consolidated code is functionally identical to the original code, and the overhead is low (approx 4k + 140 bytes per additional file, including the "require('file')" line). If you are picky, you can cut out most of that 4k, which provides wrappers to emulate common node.js globals in the browser (eg "process.nextTick()").
I want to write an HttpHandler that compiles CoffeeScript code on-the-fly and sends the resulting JavaScript code. I have tried MS [JScript][1] and IronJS without success. I don't want to use [Rhino][2] because the Java dependency would make it too difficult to distribute.
How can CoffeeScript be compiled from .NET?
CoffeeScript-dotnet
Command line tool for compiling CoffeeScript. Includes a file system watcher to automatically recompile CoffeeScripts when they change. Roughly equivalent to the coffee-script node package for linux / mac.
CoffeeSharp
Includes a command line tool similar to CoffeeScript-dotnet as well as a http handler that compiles CoffeeScripts when requested from an asp.net site.
SassAndCoffeeScript
Library for Asp.net mvc that compiles sass and coffeescript files on request. Also supports minification and combination.
Manually Compile With IronJS
IronJS is a .NET javascript interpreter that can successfully load the CoffeeScript compiler and compile CoffeeScript.
Manually Compile With Node.js
Get the node binaries and add the bin directory to your path. Write a node.js script to load the CoffeeScript compiler and your CoffeeScript files and save the compiled javascript.
CoffeeScript is now fully supported by Chirpy:
http://chirpy.codeplex.com/
You specifically said that you wanted to write a runtime compiler, so this may not be exactly what you are looking for, but if the main point is to have a way to generate the javascript result, the Mindscape Web Workbench is interesting. It is a free extension for Visual Studio.NET 2010 and available in the Extension Manager. It gives Intellisense, syntax highlighting and compiles to JS as you write. I am just getting started using it but looks promising. Scott Hanselman talks about it here. It also supports LESS and Sass.
I've managed to compile CoffeeScript from .NET using IKVM, jcoffeescript and Rhino. It was straightforward, except that the JCoffeeScriptCompiler constructor overload without parameters didn't work. It ran OK with a java.util.Collections.EMPTY_LIST as parameter.
This is how I did it:
Download IKVM, jcoffeescript and Rhino.
Run ikvmc against js.jar, creating js.dll.
Run ikvmc against the jcoffeescript jar.
Add a reference to the jcoffeescript dll in Visual Studio. More references may be needed, but you will be warned about those.
Run new org.jcoffeescript.JCoffeeScriptCompiler(java.util.Collections.EMPTY_LIST).compile() in your code.
The next step would be to create a build task and/or an HTTP handler.
Check out the new coffeescript-dotnet project, which uses the Jurassic JavaScript implementation.
Since the CoffeeScript compiler now runs on Internet Explorer, after a couple of recent tweaks, it should be good to go within other MS-flavors of JavaScript as well. Try including extras/coffee-script.js from the latest version, and you should be good to go with CoffeeScript.compile(code).
I tried running the bundled extras/coffee-script.js through Windows Based Script Host (or just wscript) and it didn't report any issues. I then added this line:
WScript.Echo(CoffeeScript.compile('a: 1'));
at the end of the file and run it through wscript again and it printed the resulting JavaScript correctly.
Are you using COM objects? Can you share some more of the code responsible for initialising the MScript object reference?
CoffeeScript in Visual Studio 2010
It's Chirpy's fork (chirpy is a tool for mashing, minifing, and validating javascript, stylesheet, and dotless files)
"OK, I think I got it working on my fork, based mostly on other peoples' work. Check it out:
http://chirpy.codeplex.com/SourceControl/network/Forks/Domenic/CoffeeScriptFixes"
from http://chirpy.codeplex.com/workitem/48
I don't have a direct answer, (I hope you find one), but maybe take a look at the following to see how it might be done.
Jint - JavaScript interpreter for .NET
Using IKVM to compile Rhino would get rid of the Java runtime requirement.
jcoffeescript. I haven't looked at jcoffeescript, but I think it depends on JRuby and Rhino. You could possibly IKVM.NET this as well.
IronJS now supports CoffeeScript and is generally faster than the other .NET JS engines:
I have a blog post about wiring the two together here:
http://otac0n.com/blog/2011/06/29/CoffeeDemo-A-Simple-Demo-Of-IronJS-Using-CoffeeScript.aspx
My main editor is VS 2010 and I love the WorkBench extension. it's nice it auto compiles to js everytime you hit save on your .coffee file, also introduces you to SASS which I had read about but never got around.
They offer a pay version to that will autmaically shrink/minify your js and css files as well, since your.coffee and .scss are your source files anyway.
I'd encourage all VS users to go ahead and install this especially if you run VS 2010.
The only knock, and someone please correct me or enlighten me, is that with .coffee syntax it's not highlighted the way say html, js, c# code is. it might be because I am using a color scheme from http://studiostyl.es/ and for the record http://studiostyl.es/schemes/coffee- just shares the name coffee no special syntax highlight support for coffeescript that I am aware of. but no reason not to start using the workbench addin today!
Okay workbench website claims: syntax highlighting so again maybe it's the studiostyle.es i chose.
I know this is old but I came here to answer a very similar question: How do I get my CoffeeScript to compile using Visual Studio 2012 Express? Note that the free Express version does not allow any extensions so I could not continue to use the Mindscape Workbench extension that had served me well for quite some time.
It turns out to be very easy. Just use NuGet to install the Jurassic-Coffee package and off you go.
One advantage of using this package over mindscape workbench is that you can reference your coffee directly from the script tags in the html. It minifies and caches the compiled JS so you only do work if the requested coffee file has changed.
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="home.coffee"></script>
</head>
The mindscape workbench allows you to bundle together different coffescript files which is very handy for modularising your coffeescript. You can also do this using Jurassic Coffee by utilising the #= require statement to include other coffee module files, for example:
#= require Classes\GridWrapper.coffee
class UsersGrid
constructor:->
#grid = new GridWrapper()
I think having the #= require staement in the coffee file is actually cleaner and clearer than the mindscape workbench approach, which kind of hides all this behind their interface so you forget easily what dependencies you have.
Note
There is one potential gotcha. The Nuget installer will put in an httphandler entry into your web.config that may not be compatible with IIS Express integrated managed pipeline mode.
You might therefore see the following error:
An ASP.NET setting has been detected that does not apply in Integrated
managed pipeline mode.
To fix this just remove the handler shown below.
<system.web>
//other stuff
<httpHandlers>
<add type="JurassicCoffee.Web.JurassicCoffeeHttpHandler,JurassicCoffee" validate="false" path="*.coffee" verb="*" />
</httpHandlers>
</system.web>
You could simply write a port of it to C#. I have ported Jison to C# (which is the underlying project that makes CoffeeScript run). I would think it may be a bit different, but both Jison parsers work the same.
I have not pull requested it back yet to Jison's main architecture, but will be doing so soon.
https://github.com/robertleeplummerjr
Instead of shelling out to CScript you could shell out to Node.js (here are self-contained Windows binaries)
I've tried to compile the extras/coffee-script.js file, unmodified, to jsc, the JScript.NET compiler for .NET, and I got many errors. Here are the noteworthy ones:
'require' is a new reserved word and should not be used as an identifier
'ensure' is a new reserved word and should not be used as an identifier
Objects of type 'Global Object' do not have such a member
Other errors were caused by the above said errors.
You might also want to check out jurassic-coffee, it is also a coffee-script compiler running the original compiler in jurassic.
It features sprocket style "#= require file.coffee" or "#= require file.js" wich can be used to keep .coffee files modular and combined right before compilation as well as embedding .js files.
It sports a HttpHandler with file watchers for .js and .coffee files that keeps track of what .coffee files needs to be re-compiled and pass through to the compiled *.js files for the rest.
jurassic-coffee is also available as a Nuget package
https://github.com/creamdog/JurassicCoffee
I've done an HttpHandler that uses Windows Script Host behind the scenes: https://github.com/duncansmart/LessCoffee and works great (it also compiles *.less files).
It's on NuGet: http://nuget.org/List/Packages/LessCoffee
It's based on this simple wrapper: https://github.com/duncansmart/coffeescript-windows
I wrote an inteructive shell using v8.
https://github.com/mattn/coffee-script-v8
This work as single executable file. (Don't use external files)
It can't use require(). But enough to learn coffeescript.