I have a project where I wrote some new code in Expo with TypeScript (since I am more used to having a type safe language). However, I want to port what I wrote to something that was written with Expo with JavaScript.
I can manually just strip off the types as I go along to solve the problem, but I was wondering if there's a more automatic way of doing it. I know typescript eventually compiles down to JavaScript but I want to keep the HTML embedded code the same when I do the conversion. Is it possible?
The answer provided by #Jason is close to what I needed.
In the end I ran this command
npx tsc --jsx preserve -t es2020 --outDir js --noEmit false
This generated the .js and .jsx files in the js folder which can be copied over to non-typescript systems.
--noEmit false is needed for the Expo generated tsconfig.js which is noEmit: true
The -t es2020 generates output using ES2020 standards so you can get import and export along with the async await intact.
In the tsconfig.json file change "jsx": "react" to "jsx": "preserve" and then run tsc.
https://www.typescriptlang.org/docs/handbook/jsx.html
Related
Below is my Firebase hosting project folder structure:
projectFolder/store/public/scripts/*.min.js
projectFolder/src/*.js
After running terser, all my projectFolder/src/*.js will be minified to projectFolder/store/public/scripts/*.min.js as shown below:
EDIT: As requested by #Bergi, this is how my terser script looks like:
call terser src/site-ui-components.js -o store/public/scripts/site-ui-components.min.js -c -m
echo site-ui-components.min.js: Done.
call terser src/login.js -o store/public/scripts/login.min.js -c -m
echo login.min.js: Done.
call terser src/register.js -o store/public/scripts/register.min.js -c -m
echo register.min.js: Done.
call terser src/profile.js -o store/public/scripts/profile.min.js -c -m
echo profile.min.js: Done.
In my ES6 import, I do the following:
import { something1, something2 } from "/scripts/something.min.js";
This works fine during runtime, but I lose all the vs code intellisense for something1 and something2 during development time. If I enable the intellisense by doing the following, during runtime, my code breaks because obviously, it couldn't find "./something.js":
import { something1, something2 } from "./something.js"; // Error, something.min.js not found
I do not want to do something silly by adding the *.min.js to my all my non-minified js just to make both of them work. Secondly, I try to avoid using dynamic import by writing extra code to adapt to different environment.
So my question is:
How can I keep my intellisense for ES6 import without breaking my code during runtime?
Is there something wrong with my folder structure? E.g. not compliant to the best/common practice? Any recommendation?
Shall I, might as well, make the minified and non-minified js files as simply *.js instead?
Any advice would be much appreciated. Thank you!
After so much of searching and reading, I finally managed to figure out the use of baseUrl and paths of jsconfig.json in VS Code to solve my problems:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"/scripts/*": ["./store/public/scripts/*"]
}
}
}
Explanations:
The goal here is to make the following import works for both /src/*.js and /store/public/scripts/*.min.js without losing the inteliisense:
import { something1, something2 } from "/scripts/something.min.js";
For my case, it doesn't really matter if my JS in src references to /scripts/*.min.js because *.min.js are always getting from the latest object interfaces from the src. Whenever I change any JS file in the src, I just run my terser script for the new changes to be reflected by the intellisense, so not a big deal. Therefore, in order for both /src/*.js and /scripts/*.min.js to import from the same source without breaking the code during runtime, I can configure my jsconfig.json as shown above to achieve this goal:
"baseUrl": "."
The "." is the projectFolder where my jsconfig.json is stored, namely projectFolder/jsconfig.json.
"paths": {
"/scripts/*": ["./store/public/scripts/*"]
}
"/scripts/*" is the string pattern or import path that I use to reference the exported module files. So when I import { something1 } from "/scripts/something.min.js", VS Code always refers to "./store/public/scripts/*" for the intellisense.
I hope my explanation is clear to everyone.
I need to have two tsconfig.json files. One for testing and one for publishing. Reading through a number of Typescript repository issues it seems like the flag for specifying the tsconfig file to use is tsc --project tsconfig-test.json, however when using this I get the following error:
return path.replace(backslashRegExp, ts.directorySeparator);
^
Thoughts?
I have a typescript project that uses paths for imports. For example:
"paths": {
"#example/*": ["./src/*"],
}
Thus the project can import files directly from using statement like:
import { foo } from "#example/boo/foo";
For publishing to NPM I have I'm compiling the typescript files and then copying the result to a dist folder. Thus all the *.d.ts and corresponding *.js files are in the dist folder. I also copy package.json to the dist folder.
I now test this by generation a new typescript project and then run npm i -S ../example/dist, in order to install the project and attempt to run some of the compiled typescript code.
However the relative imports no longer work. For example if boo.ts depends on foo.ts it will say that it can't resolve foo.ts.
When I look at the *.d.ts files they contain the same paths that were used the source code before it was compiled. Is it possible to turn these into relative paths?
Update
I looks as if generating relative paths for Node is something Typescript does not perform automatically. If you would like this feature, as I would, please provide feedback on this bug report.
As a brief follow-up to arhnee's suggestion, it seems that as of Aug 2020, Microsoft still refuses to implement custom transformers for whatever reason, so these modules remain relevant.
So to future readers, here's how you can actually compile TS path aliases to relative paths. ttypescript is merely a transformer framework that requires a "path transformer" in order to actually convert the TS path aliases. Thus you will need to install both ttypescript and typescript-transform-paths.
npm i --save ttypescript typescript-transform-paths
Then, it's easy as just specifying usage by adding the following property to the compilerOptions object in tsconfig.json:
"plugins": [
{ "transform": "typescript-transform-paths" }
]
And finally, run ttsc instead of tsc.
There is a project called ttypescript that you can use for this. If you use it with the module typescript-transform-paths I beleive it will acheive what you want.
I have a tsconfig.json which specifies an outDir. The reason is that I want to separate the generated JavaScript output from the TypeScript sources.
So:
"compilerOptions": {
...
"outDir": "target/",
...
}
This works very well, until I compile the project with the typescript compiler only. All generated javascript output is created in the target/ directory.
But, if I call it with the angular compiler (ngc, it is essentially a wrapper around the tsc typescript compiler), we have an additional build step. It compiles the template files and components into typescript, which will be compiled further to javascript by the tsc.
These intermediary typescript files have the *.ngfactory.ts or *.ngsummary.json extension.
Now my problem is, that the ngc command generates these files still in my src/ directory, totally ignoring my outDir setting in my tsconfig.json.
What is the cause of this problem? Does any useful workaround exist?
Extension: regarding comments, ng from the angular-cli can do this. This leads to a side-question, how does it do with the ngc?
The cause of the problem was that ngc has some additional options in tsconfig.json what I didn't add.
The following settings in tsconfig.json do what I want.
"angularCompilerOptions": {
"genDir": "aot",
"skipMetadataEmit" : true
}
I need to change the TypeScript generated js file name to something else. How can I do that
For example I have MyCompany.ClassA.ts
It will generate MyCompany.ClassA.js by default
But I want MyCompany.ClassA.generated.js
I took a look at .tsConfig file but I couldn't find anything useful there.
ps. I am using VisualStudio2013 for Typescript and generating the js files
To compile a single TypeScript file to .js with a custom name, use --outFile:
tsc MyCompany.ClassA.ts --outFile MyCompany.ClassA.generated.js
Compiling multiple files to the .generated.js pattern would require a bit more work. You could compile one at a time as in the tsc example above.
tsc A.ts --outFile A.generated.js
tsc B.ts --outFile B.generated.js
Or you could use --outDir to collect the compiled files under standard names, and then rename them with your own script.
tsc --outDir ./generated
# run script to rename ./generated/*.js to *.generated.js
Note that --outFile and --outDir replace --out, which is deprecated:
https://github.com/Microsoft/TypeScript/wiki/Compiler-Options
The other answer here is good and comprehensive, but just to address this:
I took a look at the .tsconfig file but I couldn't find anything useful there
You can also set the outFile config in your .tsconfig.json under compilerOptions
{
"compilerOptions": {
"outFile": "./some/path/MyCompany.ClassA.generated.js",
...
}
}
See this example in the documentation