1 year ago
#379753
Terry
Refactor Typescript into folders doesn't seem possible with reference dependencies and enums
I have used TypeScript to create a jQuery plugin. Currently, I have a nodejs app as the host of my typescript files during development. I would edit my *.ts files in VS Code and use tsc --build
to compile them and could debug inside VS Code (with additional *.html files referencing the generated .js files).
The folder structure was quite simple.
+-- client
| +-- ClientApp.ts
| +-- DynamicApp.ts
| +-- Interfaces.d.ts
| +-- ThirdParty.d.ts
| +-- tsconfig.json
+-- tsconfig.json
+-- tsconfig-base.json
ClientApp.js - This file was distributed to clients that wanted to use our plugin and had minimal code that was actually a 'shim' for our addin. This code is/was rarely touched because we didn't want to go through the hassle of having clients update their local .js file.
DynamicApp.js - This file is the actual implementation of our addin and changes frequently. We host this in a Content Management System (CMS) that serves the file to the client. This is possible via ClientApp.js calling $.ajax()
to our CMS to get the file content, then it injects it into the DOM.
const script = document.createElement('script');
script.innerHTML = contentFromCMS;
body.appendChild(script);
This allowed us to make updates to the actual implementation of the plugin and test/deploy at our speed to the production CMS.
Below is what I had for 'tsconfig.json' settings, which I think I basically got when I followed a tutorial to create this site a long time ago. To be honest, I'm not up to complete speed on all the settings/power of tsconfig.json - especially now, 2-3 years later.
Contents of tsconfig-base.json (root)
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": true,
"sourceMap": true,
"outDir": "./build",
"removeComments": false,
"strict": true,
"esModuleInterop": false,
"forceConsistentCasingInFileNames": true,
"listEmittedFiles": true
}
}
Contents of tsconfig.json (root)
{
"extends": "./tsconfig-base.json",
"references": [
{ "path": "./server" },
{ "path": "./client" }
],
"files": [
/* Empty files array specifies that no files should be compiled directly as part of this master package */
]
}
Contents of client/tsconfig.json
{
"extends": "./../tsconfig-base.json",
"compilerOptions": {
"composite": true,
"outDir": "./../public/KatApp/Global",
"tsBuildInfoFile": "./../build/cache/client/.tsbuildinfo",
"suppressImplicitAnyIndexErrors": true
}
}
My Refactor Problem I have made a .NET Core site as the host (since neither the nodejs site nor .NET Core site are the actual host of the files during live execution, I was just more comfortable with .NET Core and Visual Studio Proper). I basically want to break apart ClientApp.ts and DynamicApp.ts into separate files for each class, but I have to keep the output of simply ClientApp.js and DynamicApp.js. Currently, the DynamicApp.ts is more than 7K lines and it is getting unwieldly to navigate, especially for developers who aren't in there frequently.
As I understand, to accomplish this I have to use the "outFile": ""
setting in tsconfig.json
. Additionally, it seems you can only have one outFile
per tsconfig.json
file and only one tsconfig.json
per folder, so I restructured my application to look like this.
+-- Scripts
| +-- ClientApp
| | +-- ClientApp.ts
| | +-- ClientHelper.ts
| | +-- tsconfig.json
| +-- DynamicApp
| | +-- DynamicApp.ts
| | +-- DynamicHelper.ts
| | +-- tsconfig.json
| +-- Shared
| | +-- Interfaces.d.ts
| | +-- ThirdParty.d.ts
| +-- tsconfig.json
So the goal is to combine all files in the ClientApp
folder into ClientApp.js and all the files in DynamicApp
folder into DynamicApp.js.
Originally, since all the *.ts files were in same folder, everything just worked. I didn't have any /// <reference path="" />
declarations or anything. Now, with this setup and things in separate folders, I'm encountering some frustrating issues along with issues that prevent it from building.
- Code Duplication - Remember that
ClientApp
will dynamically inject the code fromDynamicApp
into the DOM, so I can't have duplicated classes, enums, etc. generated in bothClientApp
andDynamicApp
otherwise I would assume it would cause compile errors and run time. - Enums - ClientApp.ts has an
enum
declared that is used in ClientApp.ts, DynamicApp.ts, and Interfaces.d.ts. I tried usingreference
,"files"
setting in tsconfig.json, changing todeclare enum
inside my Interfaces.d.ts file, but all were preventing the build from working for different reasons or causing runtime exceptions. So not only do I have a problem getting the enum shared across all files, but the I haven't been able to find any direction on how reference an enum from a *.d.ts file in general. - Dependencies - Currently,
ClientApp
has some static methods that are also called byDynamicApp
. But in the new folder structure, if I add areference
insideDynamicApp
toClientApp
, whenDynamicApp
compiles, it regenerates/injects all the code fromClientApp
again which would cause js errors I assume. My game plan to get around this was to have all the shared code assigned on various$.fn.ClientApp.methodABC=function(){...}
items in a shared *.ts file, and reference that from bothClientApp
andDynamicApp
. Then, even with code generated twice and ran, yes it was wasted overhead/re-assignment, but at least I don't think it would cause client side compile errors.
I feel like there is something easy I am missing (and unfortunately, I'm not up to speed on module loaders/resolvers on the client side and not sure if they'd even work in our scenario).
javascript
typescript
enums
tsconfig
0 Answers
Your Answer