Using Bullmq sandboxed job with NX by building files separately - javascript

I am working on an nx monorepo and it has multiple projects within it. I have been working on server code to complete heavy tasks that may arise separately from the rest of the server process. To achieve this I am using bullmq to queue tasks and parallelize their execution. However, because the tasks I am running are time and CPU-intensive, jobs are frequently stalled. To avoid this I want to run the tasks in a separate sandboxed process. The way to make a sandbox process needs a reference to a .js file that will be generated when the project compiles (if I write the task handler in the handler.ts file I need to reference the handler.js file).
The problem is that nx combines every source file into one when it builds the project. I need a way to force nx to build source files separately so that I can access the compiled task handler file.
I run into a stack overflow answer that suggested writing a custom target for building the specific project within the monorepo. But it was not a solution for me as it has issues when importing code from an external library within the monorepo.
Or if you have any alternative solutions, I am open to suggestions

Related

Typescript in `file://` environment

Recently I just picked up Typescript for a personal project. Since the project is designed to be ran locally (explicitly file://), I won't be able to use import/export features due to CORS restrictions. Aware of another similarly written question but lacking the specific context on my use case, I pose these questions:
How does one tell Typescript that all (or at least certain) scripts are imported to HTML via <script type="text/javascript" src="./source.js">?
Does Typescript's tsc build projects with this in mind? Also, does it edit existing HTML files to take this into consideration too? If not, are there tools to automate this process as well?
I don't want to bundle them like webpack or tsc-bundle does, since a secondary objective to this project is to keep all .js files human-readable just as much as the .ts files do.
Building Typescript using tsc -p tsconfig.json, configured to "target" : "ES2015" and "module" : "None", only outputs their respective .js files and doesn't update any of the HTML's <script> includes. Am currently maintaining the html file by manually inserting and juggling any new modules that emerges over the course of development.
My current load order in index.html is as follows:
index.js handles UI controls and loads first.
The remaining pseudo-modules .js files loads in-between, since these only define classes and doesn't perform any operations, so I figured it's safe to load them here.
main.js handles all the code from javascript "modules" and loads last.
My main concern is that my in-between modules might load out of order due to human error.
Edit: Running a local webserver is out of the question too, since the project is meant to target audience with limited technical knowledge, with the index.html file the only file they need to run in their browser.

Building two applications into one

So I've two separate applications - one is REST Api written in java which is exported as a war. The other is a REACT javascript application which is rendered in a folder with 1 HTML, 1 CSS and 1 JS file.
Now my organization wants me to package the two applications in gradle and offer 1 single war for deployment.
Personally I think it's a terrible idea, but well, can't always choose.
My question is, can that even be done, if yes how can I do it. Important to note that it has to be a gradle build.
Theoretically, you should be able to package assets into your .war and have Tomcat (or whatever) serve them alongside your actual assets.
You should be able to place them alongside the WEB-INF folder at the same level. The container will serve them directly.
You probably want a build step that runs whatever JS things needs to run (minification, etc). Another build step could take the output of that and dump it into war.

VertX Webserver static content webroot

I've got two projects which I've created:
A web UI built using webpack
A Vert.x webserver written in java built using Gradle
I want to find a way to bring the resulting build dir contents of the first project into the second as the webroot which will be server up using the StaticHandler.
Is anyone aware of a clean way to do this? I want to preserve the two git projects as they are because I like using the webpack dev server for development of the UI and it generally feels cleaner to have them separated.
I was looking at potentially using the bitbucket pipelines build on my repo, however bringing the assets generated by the first project into the build of the second is where I'm facing issues.
You could create a gradle task that before that depends on the jar task (so it runs before it) executes webpack compile into the resources directory. So when your jar task runs it bundles the compiled webpack code.

Bundler for javascript, or how to source control external javascript files

I am in the process of converting an existing Rails 3.1 app I made for a client into a Backbone.js app with the Rails app only as a backend server extension. This is only a personal project of mine, to learn more about Backbone.js.
While setting up Backbone.js (using Backbone-on-Rails), I noticed I have some dependencies (like backbone-forms) that come from external sources and are frequently updated.
I've grown accustomed to using Bundler to manage my Ruby gems, but I haven't found anything similar for JavaScript files. I'm wondering if there is any way to do the same for Javascript (and possibly css) files.
Basically I can see three possibilities to solve this issue:
Simply write down all the sources for each JS file and check these sources from time to time to see what has changed.
Use some kind of existing "Bundler for Javascript" type of tool, I've been looking for something like this but have yet to find anything (good).
Since most of these JS files will be coming from Git anyway, use Git to get the files directly and use checkout to get the latest version from time to time.
I prefer the last option, but was hoping on some more input from other people who have gone this route or preferred some other way to tackle this issue (or is this even an issue?).
I figure the Git way seems easy, but I am not quite sure yet how I could make this work nicely with Rails 3.1 and Sprockets. I guess I'd try to checkout a single file using Git and have it be cloned in a directory that is accessible to Sprockets, but I haven't tried this yet.
Any thoughts?
You don't mention it in your alternatives, but ideally you should use something like Maven to manage your dependencies. Unfortunately, there are no public repositories for javascript files. This discussion lists some other options which might be of help to you: JQuery Availability on Maven Repositories
For now I've settled on using the Git solution combined with some guard-shell magic.
The steps I follow:
Create a dependencies directory somewhere on your local drive
Clone the repositories with javascript (or css) files you want to use in the app
Set up a custom guard-shell command to do the following:
group 'dependencies' do
guard 'shell' do
dependencies = '~/path/to/dependencies/'
watch(%r{backbone-forms/src/(backbone\-forms\.js)}) {|m| `cp #{dependencies + m[0]} vendor/assets/javascripts/#{m[1]}` }
end
end
Place the Guardfile at the root of the app directory
It takes some time to set things up, but after that, when you have the Guard running, and you pull changes into your dependencies, the required files are automatically copied to your application directory, which are then part of your repository.
It seems to work great, you need to do some work for each new file you want to include in the asset pipeline, but all that is required is cloning the repository in your dependencies directory and adding a single line to your Guardfile, for example for the backbone-form css:
watch(%r{backbone-forms/src/(backbone\-forms\.css)}) {|m| `cp #{dependencies + m[0]} vendor/assets/stylesheets/#{m[1]}` }
Also, the reason I added this Guard to a group is because I keep my dependencies outside the main application directory, which means guard normally doesn't check my dependencies directory. To make this work, I start up my main Guard processes using bundle exec guard -g main and use bundle exec guard -w ~/path/to/dependencies -g dependencies in a new terminal window/tab to specify the -w(atchdir).

How can I convert a multi-file node.js app to a single file?

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()").

Categories

Resources