If I want to support scripting in my application, does scriptcs offer any particular advantages over just using the plain vanilla Roslyn script engine?
Unfortunately there's not much documentation on hosting scriptcs yet, but I'll try to give you a short summary.
Hosting scriptcs in your application provides several features that vanilla Roslyn doesn't:
Pluggable Engines
While scriptcs comes with the Roslyn and Mono engines by default, you can easily replace it with another engine, i.e. F#, LOLcode or even Brainfuck.
Pre-processing
scriptcs will process your scripts and extract things like references (#r) and load other scripts (#load). There was also recently introduced custom ILineProcessors which lets you hook into the pipeline for custom processing. An example processor could look like this:
public class GistLineProcessor : DirectiveLineProcessor
{
protected string DirectiveName
{
return "gist";
}
protected override bool ProcessLine(IFileParser parser, FileParserContext context, string line)
{
var gistId = GetDirectiveArgument(line);
var gistContents = DownloadGistContents(gistId);
parser.ParseScript(gistContents, context);
return true;
}
private static string DownloadGistContents(string gistId)
{
// Download gist contents...
}
}
This processor will download a gist and execute it as part of your script, i.e. #gist 12345678.
NuGet integration
scriptcs has integration with NuGet. This means that if you want scripts to be able to use NuGet packages, just install them and they will automatically be loaded from within the packages folder.
Script packs
Script packs is scriptcs' way to remove boilerplate code. They can import namespaces, reference assemblies and expose functionality to scripts through Require<T>(). See Martin Doms' excellent blog post about building a scriptcs script pack. For a comprehensive list of available script packs, see Script packs master list.
REPL
As you probably know, scriptcs has a REPL. This can be reused in your own application to provide an interactive scripting session.
Debugging
Using the vanilla Roslyn script engine, you can't debug scripts very easily. scriptcs gives you the ability to debug scripts with source mapping through #line directives inserted during pre-processing.
I may have forgotten something, but these are the main points for choosing scriptcs over vanilla Roslyn. When it comes to the actual hosting, you have two options:
ScriptCs.Core
This is a super lightweight library that contains the core components of the scriptcs pipeline. However, it doesn't contain implementations for IScriptEngine (the engine that actually executes code) and IInstallationProvider (the component that installs packages, i.e. NuGet), these live in ScriptCs.Hosting and ScriptCs.Engine.Roslyn. If you use this library, you will have to do all the wire-up of the components yourself and you also need to provide an implementation for the engine and the package installer.
ScriptCs.Hosting
ScriptCs.Hosting is a convenience layer for hosting scriptcs in an application. It's used internally in scriptcs.exe and does all the wire-up of the components (via Autofac) for you. It contains the NuGet implementation for the package installer and has a dependency on ScriptCs.Engine.Roslyn by default. This is the preferred way to host scriptcs as it provides a ScriptServicesBuilder to easily replace scriptcs' internal services. See scriptcs' Program.cs for example usage.
This could sound confusing so if you have questions, please ask on JabbR, Github or on the Google Group.
Related
I'm looking for a module system for Nashorn. From what I can tell, CommonJS is the way to go concerning modules for JS. I have looked through the list (here and here) and have found little in the way of a CommonJS implementation for Java.
Narwhal is no longer active and it's documentation is no longer hosted on GitHub. Is there an existing CommonJS implementation which supports Java or should I start a new project?
Have a look at jvm-npm here https://github.com/nodyn/jvm-npm. This project is used by nodyn as the CommonJS module system. It is NPM-aware, meaning you can load modules directly from NPM, but it does not provide any of the Node.js API.
Here is a simple example usage:
$ npm install pegjs
npm http GET https://registry.npmjs.org/pegjs
npm http 200 https://registry.npmjs.org/pegjs
pegjs#0.8.0 node_modules/pegjs
$ jrunscript
nashorn> typeof require
undefined
nashorn> load('./jvm-npm.js')
nashorn> typeof require
function
nashorn> var PEG = require('pegjs');
nashorn> typeof PEG
object
It is primarily all Javascript, but the actual loading of files from the filesystem and such is done using Java.
I asked a very similar question on the Nashorn mailing list a little while back, here's Sundar's (Nashorn Engineer) reply:
From: A. Sundararajan
To: nashorn-dev#openjdk.java.net
I forgot to add. Nashorn does not contain any builtin module system.
But, if a module system is pure JS + Java, it must be possible to run
on nashorn.
Nashorn supports "load" (loads scripts from URL, File, resources) and
"loadWithNewGlobal" (loads script but into a fresh global scope)
primitives in addition to the good old 'eval'. So, it should be
possible for any module system to be implemented on top of nashorn in
pure JS or perhaps with a bit of Java code.
-Sundar
I've been looking for such an implementation for a while. I've been using a little patched version of Rhino-Require. Although Rhino claimed to be CommonJS compatible, AFAIK, it implemented only modules and not packages (package.json) can't be parsed.
RingoJS should be compatible. But Nashorn will never be see.
Laterly, Oracle announced project Avatar which relies on Avatar.js or here. It's the official project of what was unofficially called Node.jar. But as of now, you have to compile it by yourself. The project is very young.
Another very young project is Nodyn which relies on dyn.js.
So, if understood well, CommonJs should work with avatar-js and nodyn, but those two are still pretty young. I don't understand why avatar-js in not fully distributed along with nashorn though.
A kind of solution would be to add a CommonJS compatibility script like the one for Rhino which adds importClass/importPackage (mozilla_compat.js) which would add CommonJS compatibility into nashorn, kind of Rhino-Require shim thoroughly tested.
I had the same need, and I used jvm-npm for a while, but I needed something that would work even without allowing usage of Java packages inside JavaScript, so I wrote my own version here: https://github.com/coveo/nashorn-commonjs-modules
It's implemented entirely in Java and supports loading modules from elsewhere than the filesystem (Java resources, a custom database, etc.)
It's published on Maven Central if someone wants to use it.
There's also nashorn-require, you can get that off of github too. I've used it, I was able to do
engine.eval(reader("src/main/javascript/nashorn-require.js"),bindings);
engine.eval("var initRequire = load('src/main/javascript/nashorn-require.js');",bindings);
engine.eval("initRequire({mainFile : 'src/main/javascript/foo', debug : true})", bindings);
engine.eval("var babel = require('babel');",bindings);
and then transpile JSX React components to ES5 with
Buffer input = findTemplateSource(fileLocation,context);
bindings.put("input",input.toString());
result = engine.eval("babel.transform(input,{ presets: ['react', 'es2015'] }).code;",bindings);
Then when I pulled react and react-dom into my browser and loaded the resulting js components, things worked fine, so I'm sure Babel was perfectly happy, though I'm not sure about if it will find 3rd-party plugins or not...
I'm trying to optimize my company's application.
Tha architecture at this time is composed of different folders (inside common folder) for different sections of the app (for example Managing Bills, Managing Canteen, Managing Events etc etc).
Every js and css are included in the first page of the application (login.html) because I'm using the simple page template of jQuery Mobile.
Now I'm considering to add some other components to make the app easier to mantain and maybe speed it a bit.
What do you think about:
RequireJS to divide each section in a module so i can load only the javascript of a particular module at run-time instead of loading within login.html
Inline #imports for CSS files to produce single composite CSS
uglify.js to Minimize file sizes
Handlebars.js to realize fragments of html reusable
Do you think is a good way of work for an application that will become greater by adding new sections?
Do you think of other tools?
Thank you
This is a very broad question. I think you're on the right track... I'll list some libraries that could be worth trying:
Require.js - Will give you the ability to have 'modules' and dynamically determine and load dependancies. Alternatively some people prefer patterns such as the Revealing Module Pattern, jQuery Plugin Style or Common JS style modules. For what it's worth I recommend Require.js.
Bower is a package manager, you can use it to bower install [package]. They have a lot of packages here and you can also link it to your own repo. This could be helpful for managing dependancies.
Uglify.js and Google Closure Compiler are both good for minifying your code. Remember that some minification configurations such as advance mode could break your code. Run tests against the minified version of your source code.
QUnit is good for doing JavaScript unit tests. There are many other alternatives like Jasmine, which is what the Cordova guys use.
Lodash is another (faster) implementation of underscore.js that will provide a lot of utility methods for working wit arrays, objects, functions, etc. It also includes templating support. There's a good talk by the author here.
There a MV* JavaScript frameworks that could help more than jQuery (DOM+AJAX+Animations) or jQuery Mobile (Mostly UI) such as: Dojo, AngularJS, Backbone and Ember.js.
For UI you may want to checkout Adobe's topcoat repository and website. There's also Twitter Bootstrap and Foundation which allow you do to responsive design out of the box. If you're set on jQuery Mobile I personally like this Flat theme.
JSDoc and YUIDoc are good alternatives for documenting your JavaScript code.
I have no idea how many of those tools will interact inside Worklight Applications. It should be fine, since Worklight doesn't impose a certain set of JavaScript libraries you have to use. However, I haven't personally tried most of them inside Worklight Applications.
I'm trying to get set up with unit tests for google app scripts, and I found two projects:
https://code.google.com/p/gas-unit/
https://code.google.com/p/gasunit/
So I'm confused which to use :-)
I just had a go with the unhyphenated gasunit, which seems to expect that the script is embedded in a spreadsheet, which I am a little unclear on how to do ... and the scripts I want to test are web based scripts rather than spreadsheet ones
I had more luck testing the hyphenated gas-unit, which managed to send me both an email output of the test and generate a results page in my google site:
https://sites.google.com/site/testappscript2/TestResults
so I'm going to with gas-unit for the moment, but I'd really like to see some official testing framework incorporated by Google. In particular I'd like to find some way to get these scripts to be run with some frequency to send me the results. Also I'd love to get some BDD going; see my other posts:
How to get Cucumber/Capybara/Mechanize to work against external non-rails site
how to use capybara has_text
Come on Google, you famously have "Testing Rocks, Debugging Sucks" in all your bathrooms? How about better testing support for Google Apps Scripts?
You can try out QUnit for Google Apps Script. It is a patch for QUnit turned into a Google Apps Script library with API docs.
All you need is a script project that imports a QUnit library (for example the one with the project key MxL38OxqIK-B73jyDTvCe-OBao7QLBR4j) and has a doGet function that configures QUnit using URL parameters and optionally also with your own settings, loads a function that runs your tests, and finally returns QUnit.getHtml(). Here is an example:
function doGet( e ) {
QUnit.urlParams( e.parameter );
QUnit.config({ title: "Unit tests for my project" });
QUnit.load( myTests );
return QUnit.getHtml();
};
// Imports the following functions:
// ok, equal, notEqual, deepEqual, notDeepEqual, strictEqual,
// notStrictEqual, throws, module, test, asyncTest, expect
QUnit.helpers(this);
function myTests() {
module("dummy module");
test("dummy test", 1, function() {
ok(true);
});
}
Then authorize the script, save a version of it, publish the script project ("Deploy as web app") and go to the test URL ("latest code") with your browser. Your tests will be run and results will be displayed via HtmlService. You can single-click on them to see their assertions, but as of writing this, you will probably not be able to do so in Firefox 20 and 21 due to Caja issue 1688.
I just wrote another testing framework named GasT for my google spreadsheet add-on development & testing.
GasT is a TAP-compliant testing framework for Google Apps Script. It provides a simple way to verify that the GAS programs you write behave as expected. https://github.com/huan/gast
My goal is to get a simple tap tool like tape(for javascript) or bats(for bash). the test suite format is quite clear:
var gastLibUrl = 'https://raw.githubusercontent.com/zixia/gast/master/src/gas-tap-lib.js'
eval(UrlFetchApp.fetch(gastLibUrl).getContentText())
var test = GasTap.setPrintDriver('Logger')
function gast() {
test('do calculation right', function (t) {
var i = 3 + 4
t.equal(i, 7, 'I can calc 3 + 4 = 7')
})
test('Spreadsheet exist', function (t) {
var ss = SpreadsheetApp.openById('1TBJpvlW3WWney4rk1yW5N9bAP8dOMkWxI97dOtco-fc')
t.ok(ss, 'I can open spreadsheet')
})
test.finish()
}
Hope someone will like it. :)
there's a online version, you can go to have a look on it here: https://docs.google.com/spreadsheets/d/19M2DY3hunU6tDQFX5buJmZ_f3E8VFmlqAtodyC-J8Ag/edit#gid=0&vpid=A1
The clasp tool provides the ability to develop and deploy Apps Script projects locally from the command-line.
From the clasp repo:
npm install -g #google/clasp
enable Apps Script API: https://script.google.com/home/usersettings
Develop locally and use the clasp tool to deploy.
Edit the node-google-apps-script project has been deprecated in favor of clasp
There is the node-google-apps-script package to allow using standard JavaScript packages and automated testing tooling.
npm install -g node-google-apps-script.
Go through the authorization steps to provide client secrets to allow uploading and importing Apps Script projects.
Use gulp or grunt or whatever you use for test running normal JavaScript projects.
There is an official Google sample available that uses this workflow.
See Google Apps Developer Blog post announcement for more details.
Once the files are downloaded, convert them to TypeScript by renaming them to end with .ts instead of .js. Once they are TypeScript, ava can be used to test them. Converting them to TypeScript also lets one use ES6 language features.
I created gas-unit (https://code.google.com/p/gas-unit/) and have spent a bit of time over the last few days tidying up the examples and adding a HTML test runner.
I have been using it myself for some spreadsheet manipulation I've been doing with reasonable success. I've also been using Jasmine for non-GAS client side js work and have really enjoyed that. I miss the ability in gas-unit to easily create spys and I favour the BDD style of specification writing.
gas-unit has been a great learning exercise for me and it does work although there may be undiscovered issues with scope and closure - this is my first significant js exercise outside of DOM manipulation.
I think the future for testing in GAS has to be with a port of QUnit (as Adam suggests) or Jasmine. I had a quick look at what it would take to port Jasmine but as yet have not been able to find the time to tackle it.
Check out QUnitGS2 - a new Apps Script library using the latest version of QUnit (v2.10.1).
Ember don't seems to play well with requirejs or building with r.js without some hackery.
Bit hard to manage a large application, I like to break down my file structure as HMVC, which manages modules bit easier :
app
- blah
- modules
-module1
- controller
- model
- view.
Has anyone come up a build stack to automate the compilation into single file with dependency management?
Update: You should now be starting new projects using ember-cli, which provides all the build/dev tools plus many other useful features.
Original answer:
An example Ember project using grunt.js as a build system:
https://github.com/trek/ember-todos-with-build-tools-tests-and-other-modern-conveniences
I've used this as a starting point for some Ember apps and it works well.
Ember don't seems to play well with requirejs or building with r.js without some hackery.
Why do you want to use require.js in the first place?
As for making this all work you'll need a build tool. I recommend brunch (Node) or iridium (Ruby). Brunch is more simple and supports many different module formats. Iridium is much more powerful. It uses Minispade for modules. Require.js/AMD is not needed because your js is always delivered as a single concatenated file.
For stand-alone ember dev I use ember-skeleton as a starting point, which is itself based primarily on rake-pipeline.
https://github.com/interline/ember-skeleton
This provides the whole kit-and-kaboodle for beginning an app, but the meat of it is the rake-p Assetfile, which describes how rake-pipeline will digest all the files, filter their contents, and ultimately combine them into the final handful of files. Additionally, the combination of loader.js and the minispade filter allows the use of 'require()' statements for managing dependencies amongst your files.
I am beginning a fairly large new project using ColdFusion. This new project will include several developers and as such documentation of code will be key.
Another issue I am hoping to avoid (either with adequate code documentation or some other tool) is the duplication of code. A tool that would be able to "index" the code for searching or diagramming would likely help here.
What are others out there using either specifically for ColdFusion or language agnostic. We will likely be using ColdBox for the underlying framework if that makes a difference.
Thanks for any any all suggestions.
-c
Well, it's impossible to tell you which framework to use without knowing more about your project, but I can list out some tools that will be useful no matter which framework you use.
Language-agnostic tools:
GitHub.com organization+teams
Jenkins continuous integration
Apache ANT build scripts
Apache Maven for project management
Coldfusion-specific tools:
MXunit unit testing framework
MockBox for unit testing (if you use ColdBox: ColdBox-specific tutorial)
ColdDoc documentation generator
Javascript-specific tools:
JSLint or JSHint for JS code cleanup
Jasmine unit testing
Ideally, your Jenkins build server should:
Do a fresh checkout from source control
Run all unit tests and stop the build if they fail
Generate documentation
Generate a production-ready package of your project
At a minimum, I highly recommend using source control, setting up Jenkins with MXunit tests, and scheduling daily automated builds.
We used the Atlassian suite at my last job. Mostly Jira for tracking and Greenhopper for agile but the other tools may help, fisheye, bamboo, and crucible. If you host it yourself I believe they have a one time $10/product price tag that. Depending on your team's size may or may not work. If money is no subject the suite worked really nicely. It also has built in support for svn and maybe more by now.
http://www.atlassian.com/software
Sounds to me what you need is a methodology, not a tool. If you have a clearly defined set of objects/responsibilities. There should be no crossover in scripting, and if you determine a common API for the objects being coded, I would think you'd be fine.