Nothing happens when running a simple Groovy Ratpack script - groovy

I'm new to groovy and ratpack. I have read that i can simply put my entire application in a file and run it like a simple groovy script groovy filename.groovy. When I run one example script nothing seems to happen and pointing the browser to localhost:5050 has no effect... I'm sure I'm missing something big...What I have to do in order to get started?
Do I need to start the application in some way, other than running the script?
#GrabResolver("https://oss.jfrog.org/artifactory/repo")
#Grab("io.ratpack:ratpack-groovy:0.9.0-SNAPSHOT")
import static ratpack.groovy.Groovy.*
ratpack {
handlers {
get {
response.send "Hi!"
}
assets "public"
}
}

Use latest versions of ratpack (0.9.2[released today] or 0.9.1). They seem to work the way you are trying to use.
#GrabResolver("https://oss.jfrog.org/artifactory/repo")
#Grab("io.ratpack:ratpack-groovy:0.9.2")
import static ratpack.groovy.Groovy.*
ratpack {
handlers {
get {
response.send "Hi!"
}
//assets "public" //Not required if there is no asset to refer to
}
}
You can also run the script from groovyConsole to start the server.
Running as a script is a good starting point. Using ratpack for projects, I suppose a good staring point will be to use gradle as well, with something like below as the project structure.
-- client
-- server
|_ src
|_ ratpack
|_ ratpack.groovy
|_ build.gradle
You can effectively use ratpack-groovy plugin in gradle if you are already familiar with gradle and opting to use it. Here is an example app of using ratpack gradle plugin in a ratpack app. Another example where you can see usage of ratpack (server), mongo (db) and AngularJS (as client)

Related

Having Issues using Esri ArcGIS API for JavaScript in Lightning Web Component (require is not defined at eval)

I'm trying to implement Esri ArcGIS JS in Lightning Web Component. While using ArcGIS JS, the sample code uses require function to load modules. In order to do that I'm trying to use require.js. I downloaded it from here (Require.js). And then uploaded to my sandbox as static resource. I'm trying to use that static resource in my Lightning Web Component. I also added the script tag for the ArcGIS Javascript API in my Experience Cloud site's header as
<script src="https://js.arcgis.com/4.24"></script>
Lightning Web Component:
import { LightningElement, track } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import requireJS from '#salesforce/resourceUrl/requireJS';
export default class TestMap extends LightningElement {
renderedCallback() {
loadScript(this, requireJS).then(() => {
console.log('requireJS loaded');
require([
"esri/geometry/Extent"
], (
Extent
) => {
var initExtent = new Extent({
xmin: -15884312,
ymin: 1634835,
xmax: -6278767,
ymax: 7505198,
spatialReference: 102100
});
});
}).catch(exception => {
console.log(exception);
});
}
}
My problem right now, eventhough I can see in the Network tab that the require.js is loaded from static resource, require function cannot be found.
Exception message catched
I'm not sure where is the issue since this is how I loaded my all javascript files before.
I was expecting to see the the require function is working after the require.js script loaded from Static Resource.
This one is a bit tricky, I will try to guide you as much as I can.
First, don't put the script tag in your website header. This is a last chance solution, we'll keep it if nothing else work.
Second, requireJS is not compatible with LWC (or Locker Service to be precise). So you can forget it. loadScript is in someways similar.
Now the solution, usually I download the whole from a CDN and host it as a static resource. Then you can load it via loadScript and use it as per the documentation.
In case the library is really small, it could be created as a LWC and then be imported but usually libraries are too heavy regarding Salesforce limit.
Looking at the library, it seems that they do not provide any compiled full version (which is probably huge). In this case I would recommend to make a custom build locally containing only the necessary pieces of code and then uploading as a static resource. Unfortunately I can't help on this part as I still didn't do it myself yet.
Feel free to comment and I will improve my answer is it's unclear.

Detect whether an npm package can run on browser, node or both

I'm building a NextJs application which uses a set of abstractions to enable code from both react (Component logic etc.) and node (API logic) to utilize same types and classes. The motive here is to make the development process seem seamless across client side and server side.
For example. a call on User.create method of the User class will behave differently based on the runtime environment (ie. browser or node) - on the browser, it will call an api with a POST request and on server it will persist data to a database.
So far this pattern worked just fine, and I like how it all turned out in terms of the code structure. However, for this to work, I have to import modules responsible for working on the server and browser to a single module (which in this case is the User class) this leads to a critical error when trying to resolve dependencies in each module.
For example I'm using firebase-admin in the server to persist data to the Firebase Firestore. But it uses fs which cannot be resolved when the same code runs on the browser.
As a work around I set the resolve alias of firebase-admin to false inside the webpack configuration (given it runs on browser) see code below.
/** next.config.js **/
webpack: (config, { isServer }) => {
if (!isServer) {
// set alias of node specific modules to false
// eg: service dependencies
config.resolve.alias = {
...config.resolve.alias,
'firebase-admin': false,
}
} else {
// set alias of browser only modules to false.
config.resolve.alias = {
...config.resolve.alias,
}
}
While this does the trick, it won't be much long until the process gets really tedious to include all such dependencies within resolve aliases.
So, my approach to this is to write a script that runs prior to npm run dev (or manually) that will read all dependencies in package.json and SOMEHOW identify packages that will not run on a specific runtime environment and add them to the webpack config. In order to this, there should be a way to identify this nature of each dependency which I don't think is something that comes right out of the box from npm or the package itself.
Any suggestion on how this can be achieved is really appreciated. Thanks`

How do I mix Typescript namespaces with External modules when "Don't do it" is not an option

Situation
I have a Typescript app written using namespaces. I want to move some of this logic (Google OAuth) out of the client and into a node service. I have created a nearly complete project for that here.
This new project has a node component that will make authorisation requests to google using a secret key and a client component that can be re-used by other applications that will communicate with the server. I also have a testHarness app that uses this client to test it and make sure that I can use it in a namespace based application.
I have some shared interfaces that both the client and server consume.
I want my client code to be usable in projects that use externam modules and namespaces - i.e. my existing project.
It must be possible
I have read in many places
Do not use "namespaces" in external modules.
Don't do this.
Seriously. Stop.
Such as on this answer but I am still convinced that this must be possible. The reason that I think this is that in my project I have a dependency on RxJs. This project in my node_modules folder is used by both the client and the server.
What I have tried
In my project I have a contracts.d.ts file that I want to share between both the client and the server.
StackOverflow
I looked at this question:
Typescript es6 import module "File is not a module error"
And made my contracts look like this:
// test.js - exporting es6
export module App {
export class SomeClass {
getName(): string {
return 'name';
}
}
export class OtherClass {
getName(): string {
return 'name';
}
}
}
and then tried the various import methods listed:
import * as app1 from "./test";
import app2 = require("./test");
import {App} from "./test";
I got each of these to work so that my server AND client compiled correctly but then as soon as I tried to compile my testHarness app - that uses namespaces - it failed:
src/testHarness/testHarness.ts(4,38): error TS2304: Cannot find name 'PricklyThistle'.
src/testHarness/testHarness.ts(4,38): error TS2503: Cannot find namespace 'PricklyThistle'.
Copying Declaration Files from node_modules
As I said, I am convinced that this is possible as dependencies that I import into node_modules are used by both my client and server projects and my client can still be used with internal namespaces.
To go down this route I edited a d.ts file in the Rx ts folder and added a new interface. I verified that both client and server could use this interface and that my testHarness app (with namespaces) woudl compile. All was good!
I then copied this edited file into my common folder. I had to rename the module to avoid conflicts but then I get:
src/node/youTubeAuthenticationServer.ts(3,23): error TS2306: File '/src/common/rx.test.d.ts' is not a module.
My edited declaration file looks like:
declare module RxTest {
export interface TestInterface{
propertyOne: string;
propertyTwo: number;
}
}
declare module "rx.test" { export = RxTest; }
Workaround
For now I have just copied the interfaces that are used by both applications. This works and there are only 2 small interfaces so it's not a big deal. It is very anooying though. One of the great things about node is that is uses the same language as the browser. If you can't share code that is not good. I also have other much larger code bases that I want to do similar things with and in these situations copying code will not be a viable solution.
Any new projects I work on I will exlusively use external modules but when working with legacy code this is not always possible.
I really hope someone can help.
Thanks
If find your question a bit confusing, there's too much description and too little examples (code/configuration) of what you have.
Try to do this:
declare module "rx.test" {
export interface TestInterface{
propertyOne: string;
propertyTwo: number;
}
}
If that doesn't work, please edit your question and add the directory structure that you have, the tsconfig.json file(s) that you have, explain how you build (tsc, gulp, etc) and so on.

Setting release configuration for SPA / webpack

I'm developing a Single Page Application and using Webpack for bundling up the modules.
One of my source files (I'm using TypeScript) has settings and configuration used in the application e.g.
// app-settings.ts
export class AppSettings {
public static ApiUrlPrefix: string = "//localhost/myapi/";
}
Which I then use in my code like:
//some-class.ts
import {AppSettings} from "./app-settings"
export class SomeClass {
contructor() {
var something = AppSettings.ApiUrlPrefix;
}
}
When release time comes, I'm going to want the settings to match the live environment.
What's a good way with either gulp, npm or webpack configs to update the settings file? I've seen the HtmlWebpackPlugin which can take a template and plug in some options, so I guess I'm looking for something similar.
You can also use the webpack.DefinePlugin. The Define plugin allows you to pass "Free Global" or "macro-like" variables into your project that you can use. To use webpack.DefinePlugin simply require() webpack into your project.
Here's the documentation and an example on how to use it.

Grunt task to optionally include an AMD module for different environment

I'm developing a web app using Require.js for AMD and amplify.request to abstract away my AJAX calls. The other advantage to amplify.request is that I've defined an alternative module containing mocked versions of my requests that I can use for testing purposes. Currently, I'm switching between the two versions of my request module by simply commenting/un-commenting the module reference in my main.js file.
What I'd love to do is use Grunt to create different builds of my app depending on which module I wanted included. I could also use it to do things like turn my debug mode on or off. I'm picturing something similar to usemin, only for references inside JavaScript, not HTML.
Anyone know of a plugin that does this, or have a suggestion about how I could do it with Grunt?
On our current project we have a few different environments. For each of them, we can specify different configuration settings for the requirejs build.
To distinguish between these different environments, I've used a parameter target.
You can simply pass this to grunt by appending it to your call like
grunt --target=debug
And you can access this parameter in the Gruntfile, by using grunt.option, like
var target = (grunt.option('target') || 'debug').toLowerCase();
The line above will default to debug. You could then make use of the paths configuration setting of requirejs to point the build to the correct module. Example code below.
requirejs: {
compile: {
options: {
paths: {
"your/path/to/amplify/request": target === "debug" ? "path/to/mock" : "path/to/real",
}
}
}
}

Resources