I'd like to replicate what sencha app watch is doing in a custom executable to get more control over the whole process... Watching the file system seems pretty straight forward, but what is it with the rebuild that app watch is allegedly doing?
In the documentation it just says (I quote):
This command watches the current application’s source code for changes
and and rebuild the necessary outputs to support “dev mode”.
So what exactly does "rebuild" mean? When I manually run sencha app build it takes like forever to finish, while sencha app watch is doing it quite a bit faster... So I doubt that this is what it actually does.
A rebuild command per se doesn't exist either...
It's doing the equivalent of sencha app build development. The reason it goes faster is that it keeps the JVM running and it doesn't re-run the initialisation tasks continually.
If you want to take more control of this yourself, the relevant Ant tasks are in the Sencha CMD distribution - most (but not all) Sencha CMD commands are delegated down to the Ant tasks.
It's a little smarter than doing a simple build - because it knows which files have been changed, it knows what steps it needs to do. As such, it won't run redundant steps (another speed win).
One key difference is with CSS - using sencha app watch will create the CSS once, and then subsequent edits are processed using Fashion instead.
Related
Some things to know:
I understand how to make a HTML / CSS / JS website.
I understand how to make a Node JS app and host it on Heroku
I encountered a problem that was very confusing and I still working it out. I am making a firebase project using their latest tree-shaking V9 SDK
import { initializeApp } from 'firebase/app';
I understand Node JS is meant for backend (it can't be run in a browser) so how am I supposed to "build" this into something that I can reference in a script tag? I've heard of webpack but that requires you to run npm run build so how is that practical in any way? That would mean every change I make I would have to build it?
Developer Testing:
How would one live preview this Node JS app on a localhost if Node JS can't be run in a browser? I would live to be able to preview this Node JS app and quickly make changes if that's possible.
I've heard of webpack but that requires you to run npm run build so how is that practical in any way? That would mean every change I make I would have to build it?
Yes, that's the general idea. You make changes to script files on your local machine (or network), and then in order to see the changes take effect, you rebuild the app so that a new bundle is generated. This bundle can then be hosted on your web server or development server, and once it's there, you can refresh the page to see the differences.
But almost all of this can be automated, resulting in it not really being much of a chore at all.
Nodemon is a popular tool that watches a directory for changes and can run Node scripts when a change is detected. With it, you could, for example, make a change to a file, and then it'll automatically rebuild your app.
For Webpack in particular, there's webpack-dev-server, which can automatically refresh a page when the app gets rebuilt.
So, during development, the workflow can be as simple as - make a change, then alt-tab to your browser (hosting the app on localhost) to look at the changes.
Bundles built for the purpose of eventually hosting them on the front-end can easily incorporate Node modules - the build process can take the code from the module, and the bundle produced can include that code. This sort of thing is extraordinarily common.
Before I give some background, I'd like to clarify that I'm not looking for how to simply spawn a new script under the Electron runtime as a renderer process, I'm trying to use a plain Node runtime.
So I'm aware Electron has some different flavor of a JS runtime under its hood similar to NW.js and I'm trying to get consistent performant results for my report.
Unfortunately, this seems to be much more difficult than I had imagined. I'm specifically testing the speed of the mailparser module although that's not necessarily important here.
I first ran it on the Electron app we're working with, which uses Electron Forge. I called the test script through IPC as that's what we intend to use, so it was called within the callback for ipcMain.handle. Here, the performance was really bad and it was taking 30-50 seconds for our test to complete.
I then ran a test script that just opens a blank HTML file in the same Electron Forge app, and runs the test script in the background. This was much better at 8-12 seconds.
Next, I set up a new directory with a test set, a plain Electron installation, and a mailparser installation. I did not electron-rebuild here, but mailparser does rely on node-iconv and so has native bindings.
I ran a test script with Electron just calling the same line of code. This did not use Electron Forge. The performance here was slightly better at 5-9 seconds.
I then ran another test script, this time just with plain old node, and the performance here was excellent at 1-3s.
So I have two questions here:
Why is the performance varying so much in the Electron tests? Although I used IPCMain, I used the new .handle which should be asynchronous and run in the context of Electron's node runtime, so it should have the same performance as running outside the callback. Moreover, the Electron Forge and plain Electron tests also differ by a couple of seconds which made no sense to me as I assumed Electron Forge would just wrap the Electron binary under the hood.
Seeking optimal and consistent results, I'm wondering how I can spin up a child process with the node runtime inside Electron. Doing this normally just starts a new renderer process which is running Electron's (slower) JS runtime. I'd like to avoid leaving Electron Forge but the only solution I can think of is to bundle precompiled binaries with the process running under the Node runtime built for each platform.
For question 1 it’s hard to know what the problem is without being able to replicate it in code. You might try posting an issue on the Github site for the Electron team re this. They are more likely to know the answer, but they ask for code as well.
Having said that, it isn’t that hard to spin up a child process that is just running node and frees you from Electron/Electron Forge overhead. The easiest is to use node’s fork command, but to tell it to use the main node executable rather than electron.exe. You can just hand it a script to run, so you don’t need to worry about precompiled binaries.
The code below (and here) running on the main process will run a script called server.js in the same folder:
const serverPath = path.join(__dirname, 'server.js');
const { fork } = require('child_process');
child = fork(serverPath, [],
{
execPath: "node",
stdio: ['pipe', 'pipe', 'pipe', 'ipc']
});
If you do that you get a child node.exe process with IPC enabled, rather than an electron.exe process. It can be made to communicate over IPC with the main Electron process. It can also use any npm modules installed from your usual package.json, because the script can be in the same folder as your other scripts. So if it works this is quite a clean solution.
I entertained myself this afternoon by writing some code that does this. I’ve put this on Github. It uses mailparser to parse a simple mail in the node.exe process in server.js.
This also packages correctly with Electron Forge as far as I can see, in terms of including the correct scripts. It won't package node itself, so that either needs to be installed on the target machine or I think you'll need to distribute node.exe.
By the way it isn’t entirely clear whether you’ve actually tried this approach and it’s one of those scenarios where it runs slowly. There is still some overhead, because we’re setting up IPC. If it does still run slowly in your use case then I think it’s possible to use node’s spawn command to create a completely standalone process.
We are currently building our frontend js codebase (angularjs) using nodejs with grunt, which seems to be a popular setup, but we are not happy with this solution. Does anyone have suggestions for a build setup for e.g. linting, minimizing our js, running less, etc (in addition to some custom steps for angular in general and for our application specifically) without using nodejs at all?
I would leave it at that to avoid starting a flamewar, but here are, for context, some of the shortcomings of the current setup in our view:
grunt does not have even the basic functionality of a 1970s build system, like automatically re-building only files that have been modified based on file modification time
npm is causing constant headaches running on our build servers at every build
If grunt does not have even the basic functionality of a 1970s build system, why won't you use a 1970s build system then?
Just use make if that's what you're happy with. It still works fine. There's no reason not to use it if it you're satisfied with how it works.
I often use the Ext.require() functionality of Extjs which lets the it dynamically load the specific content.
But the documentation specifies that when released to the production environment, the dynamic loading feature should never be used. So how can I deal with so many Ext.requires() in my code? The official doc said that the sencha cmd could solve this problem if you follow the scaffolding. But I didn't know about the sencha cmd when I wrote the code.
So, how should I update my code?
The simplest way to merge all your JS files into a production build (taking care of ExtJS requirements) is to use SenchaCMD.
If you didn't follow CMD practices during development it could be quite hard. Fortunately your JS source code will not be changed, you must only be sure to have defined "requires" attribute correctly instead of using Ext.requires (otherwise it would continue to use dynamic loading...).
It really depends on you project structure and you coding style, but steps are:
Download Sencha CMD (last version)
Create a fresh Sencha app with "sencha generate app"
Add your application start logic in the "launch" method of Application.js (consider adding also all your missing requirements in this class)
Add all your source files in the app folder and try to run "sencha app build" (better if you add a subset of your app, try to build it, eventually fix it, the add another part).
Now you should have 2 new builds: "production build" is a single file minified JS, "testing build" is single file non mified. There is also a "development mode" of sencha CMD that starts a Tomcat server and deploy you application as you are doing now.
I have grunt watch setup so when i`m developing my files are automatically compiled, but after I pull i need to "touch" the files in order to trigger recompile the new files in case watch was not running while I pulled, is there a generic way to make grunt track last edit for files without having to "touch" the new files or should i just have grunt watch running before I pull (which while writing this seems like an adequate solution)?
Just have the watch run while you make the pull, or just run the tasks manually--the kind of detailed tracking you're suggesting just seems like overkill to me. Keep it simple!