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.
Related
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.
May be a noob question about nodejs and typescript, consider i have src folder where all my .ts files are located, and a lib folder for compiled files.
When i commit files to ignore lib folder from .gitignore file, my question is simple :
- the other developper who is charged to pull my changes and start the production node server should compile first .ts files from source ? and then from package.json he target the compiled lib folder to run the script?
Thanks for your light
Yeah, in TS it's similiar to compiled languages- you have to compile (transpile) project before using it.
The common practice is to use CI/CD to transpile ts files and deploy transpiled ones to production.
If you want to simplify the process of running the application in development environment I recommend you taking a look on ts-node npm package
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).
I have been following this article:
How to create strongly-typed npm packages
and have been trying to setup my typescript project to publish it to npm.
It all seems to make sense but what is not covered is how to deal with d.ts files.
My project looks somewhat like this:
src
node
server.ts
browser
client.ts
common
contracts.d.ts
so when I compile this with "declaration": true and "outDir: "dist" I get:
dist
node
server.js
server.d.ts
browser
client.js
client.d.ts
both my server.ts file and client.ts files have
import {SomeType} from "../common/contracts";
in so when someone else uses this package the typescript compilation will fail as server.d.ts and client.d.ts both still have this import.
Node will run fine though as client.js and server.js do NOT have this import. tsc must remove imports of d.ts files.
What I want to happen is for the contracts.d.ts file to be copied to the dist folder as part of the build. How do I do that as part of the tsc build?
Current Workaround
What I am currently doing to get round this is rename my contracts.d.ts to just contracts.ts which means that all required files are present in the dist folder but it does mean that both the client and the server are having to load an empty contracts.js file that only contains
"use strict";
//# sourceMappingURL=contracts.js.map
I think that I have come up with quite a good solution to this.
I have moved my declaration files into a contracts folder so my project looks like this:
src
node
server.ts
browser
client.ts
dist
node
server.js
server.d.ts
browser
client.js
client.d.ts
contracts
common.d.ts
I then just include the contracts folder in the npm package and import files using ../../contracts/common. This path works both from the src folder when compiling and from the dist folder when building against this package.
If though the contracts are just types, I would still declare them in a .ts file. Or are the contracts generated from somewhere else?
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