readFileSync - no such file or directory on packaged app - node.js

I am working on an Electron app.
I have several JSON files from my src folder that need to be copied over to a user-folder during app initialization (settings, config, etc).
It works well when on dev mode and when I do import the JSON files.
But based on how I need it, readFileSync is the best way to implement this.
var srcPath = path.resolve(__dirname, '../config/settings.json')
fs.readFileSync(srcPath)
I am getting an error though when running the packaged exe app (in asar).
Getting error messages like this:
Error: ENOENT: no such file or directory, open
'C:\Users\username\Desktop\NodeJS\branches\Electron
\myApp\dist\electron\My-App-win32-x64\resources\config\settings.json'
readdirSync() also does not work for the same reason.
I understand that my relative path is different in the packaged version
I checked the asar file and I can't seem to find my JSON files. Not sure if I am checking correctly though since it is bundled up by Webpack.
My file in this example is located in:
C:\Users\username\Desktop\NodeJS\branches\Electron\myApp\src\config\settings.json
How can I make this work?
Is there a way to force electron (I am using Electron-Packager with Quasar framework) to include my JSON files in the packaged app?
Does Webpack not bundle up the JSON files??
Thoughts? Help please!

As a workaround, I just created a folder that will contain 'post-packaging' scripts. One of which does a copy from my src folder to my dist\electron\appName\resources folder (using robocopy).

Related

How to copy asset files before deploying cloud functions to Firebase

I have a firebase project where I write typescript functions to be deployed into Google Node Cloud functions.
When I run the firebase deploy --only functions command, it transpiles my code into javascript and put the js output into a folder called lib next to src folder where my typescript functions are.
However, some of my functions need access to local files such as .ttf files or some other file types. Those don't get copied over to the lib folder and therefore, I get errors in runtime Error: ENOENT: no such file or directory, open path/to/file
Question 1 : How do I get the deploy command to copy assets files to the output folder ?
Question 2 : Given that all my functions live in separate files, in separate folders, and so do my assets, how should I reference my assets so that they can be found ? Should I give the path to the asset file relative to the lib folder or relative to where the function lives ?
EDIT -1
See the project structure here :
the code that need the font lives in the some-function.ts file. And it uses the pdfmake library that needs fonts to work.
Here is how I do it in the some-function.ts file :
const fonts: TFontDictionary = {
Poppins: {
normal: './fonts/Poppins/Poppins-Regular.ttf',
bold: './fonts/Poppins/Poppins-Bold.ttf',
italics: './fonts/Poppins/Poppins-Medium.ttf',
bolditalics: './fonts/Poppins/Poppins-Thin.ttf',
}
};
const pdfmake = require('pdfmake');
const printer = new pdfmake(fonts);
So how do I reference such fonts given that they are located in the fonts folder. or event if I put them in a separate folder at the root or src ?
After some digging I came to a solution that I would like to share here.
1- First thing, as suggested by #Dharmaraj, I added a script that removes the lib folder, before building the project, and copy my assets files before deploying.
So in the package.json under functions folder, I updated the build command as follow
"remove-lib":"rm -rf lib",
"copy-assets":"cp -rf src/path/to/your-folder/fonts lib/path/to/your-folder",
"do-build":"tsc",
"build": "npm run remove-lib && npm run do-build && npm run copy-assets",
Actually, adding the remove lib command solved another issue I had with deploying functions. I think this should be the default behaviour because when you rename function files, old ones stick in lib folder causing all sort of issues.
Anyway, now in order to correctly reference your asset, just construct the path as ${__dirname}/fonts/some-font.ttf provided that the fonts folder lives in the same folder as the file your are editing.

__dirname in typescript for nodejs

This is the first time I'm using typescript in my node project.
my directory structure looks like this
root
src // typescript files
index.ts
build // compiled js files
src
index.js
storage // storage for media
I'm outputting my compiled javascript into ./build
now, In my index.ts file, I have
fs.existsSync(resolve(__dirname, '../storage'))
This works when i'm running nodemon with ts-node and of course fails when I run javascript output from build.
I believe there's a way to tell typescript to process these files according to tsconfig.compilerOptions.outDir
or compile as srcNew/index.js instead of build/src/index.js but I'm not able to find it.
I figured it out,
Turns out this is a behaviour of typescript compiler.
And you should only set tsconfig.compilerOptions.rootDir when you want your current directory structure to be a part of the tsconfig.compilerOptions.outDir directory. Otherwise it would copy your current directory struture into outDir as it is.
You can read more about it here.

How can i download file inside app folder ?[ after packaging ]

This is my current folder structurebefore packaging
WRM_80.. is my downloaded folder.
I have these two lines of code inside index.js to download and show html in my electron window
fs.createReadStream('./Report.zip').pipe(unzip.Extract({ path: './'+folderName }));
LoginWindow.loadURL(`file://${__dirname}./`+folderName+`/t01s01q01.html`);
in development mode its working fine, file downloaded inside the same folder where my index.js exists. But after packaging the app file is downloading outside app folder. Packaged folder structure is given below WRM_80.. is my downloaded folder.
after packaging
That's why I can not load that downloaded file into window. How can I download file inside app folder? If that is not possible, how can I load external file from resources\app location ?
By referencing the directory as ./folder_name you are essentially telling the application to download to the working directory. In this case, the working directory is the folder that the program is contained in. While developing and using the electron command, the working directory is the root of your application. However once installed and running as a .exe, the working directory changes to the location of the executable.
To solve this problem, do not use the current working directory. Instead use the user / application data folder to store this information. It is not only a consistent location across development and deployment, but it is also the semantically correct place to store application data.
In Electron you can get the path to the application data folder for your app with:
const {app} = require('electron');
app.getPath('userData')
So your code should look something like this:
var userData = app.getPath('userData');
fs.createReadStream(`${userData}/Report.zip`).pipe(unzip.Extract({ path: `${userData}/${folderName}` }));
LoginWindow.loadURL(`file://${userData}/${folderName}/t01s01q01.html`);

trying to convert app.js to Typescript in Webstorm

I am trying to convert the app.js in my NodeJS project in webstorm, to application.ts. I pasted the app.js code into a new file "application.ts" and replaced "app.js" with "application.ts" in the package.json file. The .ts file is not getting converted to .js even though the FileWatcher for typescript is on and works on every other file in the project. But when I "run" the project in Webstorm, I the project actually starts and runs "app.js" which I have obviously not deleted. Not sure, what other settings need to be changed to get this right. I plan on renaming application.ts to app.ts to suit the convention, once its successfully converted.
--Update--
Here's what my typescript filewatcher settings look like:
Your file watcher is configured so that it merges all .ts files into a single main.js - see the arguments:
--out main.js
What is your application.ts - main application file? Would you like to generate a single .js for each .ts, or merge them? In the first case, you need to change the watcher arguments as follows:
--module commonjs --sourcemap $FileName$
then it will produce a singe js for each ts with name matching original ts file, with the format compatible with Node.js
To run the generated application.js instead of the original app.js from withihn WebStorm, you have to change the Node.js run configuration accordingly
By the way, if all you need is renaming 'app' to 'application', just refactor/rename original app.ts to application.ts - the generated files (.js and .map) will be updated accordingly
Some links you may find useful:
http://igorzelmanovich.blogspot.ru/2013/01/converting-existing-javascript-code-to.html
Is there a tool to convert JavaScript files to TypeScript
http://stackful-dev.com/typescript-nodejs-vim-and-linux-oh-my

Where should cake generated js files from a coffeescript node app go?

I'm using coffeescript while writing a node js app and use cake watch to compile my js files real time.
That's great to be able to do that - but where should I stick those js files? Right now, I'm saving them right next to their respective coffeescript files, but that just feels awkward...
The convention I've gotten comfortable with is to put CoffeeScript files in a src directory and have "compiled" JavaScript output to a lib directory. Like so:
package.json
lib/mymodule.js
src/mymodule.coffee
If you publish the module to the npm registry, you can just include the resulting lib directory, which is conventionally where projects written in JavaScript keep there .js files. This keeps everything consistent.

Resources