Open Serg046 opened 3 weeks ago
Hi, yes, for now, the DICC runtime is server-side only due to depending on AsyncLocalStorage
, which isn't available in browsers. There is a TC39 proposal for a similar API which, if accepted and implemented by browsers, would allow me to support the same features in browsers, and it is Stage 2 already, which means we might see it implemented reasonably soon. Until then, I think I could separate the async context tracking features into a subclass, and allow you to switch e.g. in config which variant you want to use - so you'd get dependency injection in the browser without async context tracking, without sacrificing async context tracking on the server. Would that work?
Yes, it would be great. I am now using a webpack plugin that patched dicc.js which is not something good to have. I'd even start using dicc inside dicc to describe all its dependencies and expose them for replacement publicly (sort of dogfooding pattern).
Hi, sorry for the delay, I've been busy rewriting the DICC compiler basically from scratch lol, anyway check out v1.0.0-rc.0 of both packages - the runtime package now externalises the async_hooks
dependency using a dynamic import and handles the case when the import fails (as would be the case in browsers), so you should be able to bundle it easily. If your bundler complains about async_hooks
, there will usually be an option to define some packages as "external", so the bundler will just leave the dynamic import as-is. This should give you a working implementation of the DICC Container in browsers, obviously minus "local" services / container.fork()
. Let me know if it works!
The config stopped working: https://github.com/skyscrapercity-ru/skyscrapers/blob/main/dicc.yaml
project: './tsconfig.json'
containers:
src/service-provider.ts:
className: 'ServiceProvider'
typeCheck: true
resources:
src/services/*.ts: ~
src/components/*.ts:
exclude:
- src/components/component-template.ts
Configuration error: Invalid config: [
{
"code": "unrecognized_keys",
"keys": [
"exclude"
],
"path": [
"containers",
"src/service-provider.ts",
"resources",
"src/components/*.ts"
],
"message": "Unrecognized key(s) in object: 'exclude'"
},
{
"code": "unrecognized_keys",
"keys": [
"typeCheck"
],
"path": [
"containers",
"src/service-provider.ts"
],
"message": "Unrecognized key(s) in object: 'typeCheck'"
}
]
Ouch, sorry, not a very helpful error message.. The config schema changed a bit in the new version:
typeCheck
option has been removed entirely for nowexclude
option has been split into excludePaths
for files and excludeExports
for object paths, so in your case go with excludePaths
I'm off to bed for now, it's almost 3am here, I'll look into the other issues more tomorrow!
Something else is changed:
project: './tsconfig.json'
containers:
src/service-provider.ts:
className: 'ServiceProvider'
resources:
src/services/*.ts: ~
src/components/*.ts:
excludePaths:
- src/components/component-template.ts
Unsupported: Overload signatures are not supported
Container: src/service-provider.ts (ServiceProvider)
Resource node_modules/@babel/core/src/transform-file.ts
Path: transformFile
Seems it tries to scan more folders than expected
Well it means you must've exported something that the resource scanner followed to the mentioned file. The resource scanner picks up everything you export from any resource file which matches the resource pattern and then follows some of those exports further - e.g. namespaces, object literals etc. So apparently you're exporting (or re-exporting) something somewhere that the resource scanner follows to the transformFile
function declared in the Babel transform-file.ts
file.
Edit: weird thing is, the transformFile
path should be the full object path starting from one of the resource files that match your configured pattern to the declaration being examined, so you'd literally have to do something like export { transformFile } from '@babel/core'
in a resource file. I don't know if the code that is up in your repository is up to date with what triggered this error, but I can't see anything that should do this in your source files.
Yes, I am testing it there in the main branch. The prev. version works fine. It is proved by github actions build. I will try to understand why the thing happens. I felt like dicc started to scan the whole modules folder as it started to work significantly longer than before.
That shouldn't happen.. I'm literally just passing the resource patterns that you specify in dicc.yaml
to TS Morph, and the patterns in your config file should be pretty fool-proof.. weird. I'll try cloning your repo and replicating it locally.
Actually, could you first push your latest code? The repo looks out of date, at least the dicc.yaml
file is still the old one..
Yes because I don't want to push something that doesn't work yet. The config I use to try rc version is here above. So I use that config and do npm run di
.
Interesting thing, the following config
project: './tsconfig.json'
containers:
src/service-provider.ts:
className: 'ServiceProvider'
resources:
src/services/*.ts: ~
src/components/*.ts: ~
works fast without intensive scanning and generates this (no services):
import { Container } from 'dicc';
interface PublicServices {
}
interface DynamicServices {}
interface AnonymousServices {}
export class ServiceProvider extends Container<PublicServices, DynamicServices, AnonymousServices> {
constructor() {
super({
});
}
}
Once I add the exclude path from the example above, it starts scanning node_modules and fails eventually.
Explicit service definitions work. So, there are two issues with rc.0: something wrong is with exclusions and implicit registrations don't work.
Aah, I see what the second problem is caused by: the new implementation of the compiler builds a list of all known definitions present in your resource files, but when it analyses those definitions, it starts with public services and follows their dependencies; and then during compilation it only includes services which were analyzed. So services which aren't used are not included in the final result. This is actually supposed to be a feature - it avoids dead / unreachable code - but it does mean that you need at least one explicit service definition, because implicit service definitions cannot be public. By design, you should only explicitly call container.get()
in application entrypoints - in all other places you should rely on injection. It's documented, but it is new behaviour, sorry about the confusion.
I'll look into the exclusion issue asap and post back when I know more!
Okay, so there was a bug caused by eagerly resolving absolute resource & exclusion paths; this is now fixed and released as dicc-cli
RC2. Sorry for the delay!
I have successfully compiled a container but once I start using it, I get the following:
That's my generated container:
Then I inspected this
dicc
module and found this https://github.com/cdn77/dicc/blob/main/core/dicc/src/container.ts#L1C10-L1C27. Is there any fix for that for browsers?P.S. I am now using just a mock like this and features work (constructors only):