Forum Stats

  • 3,851,884 Users
  • 2,264,052 Discussions
  • 7,904,889 Comments

Discussions

rootDir for Custom components

Venkata Rahul S
Venkata Rahul S Member Posts: 37 Blue Ribbon

My application has a set of common typescript classes in a directory (and its sub-directories) named fwk.

I am also creating custom components, which at build time are translating into a versioned directory structure. For example, one such component is an AuthProcessor component. This component is directly under my jet-composites (created by the ojet create component command). The AuthProcessor uses the configuration taken from classes declated in the fwk/common/configuration. To tell the typescript compiler, I edited the tsconfig.json and added

"fwk/*": [

"src/ts/fwk/*"

]

to the paths section.

Now there are at least two points I am not clear about. First and more serious is the runtime compilation issue, which results in a Typescript Error: fwk/common/configuration/CustomConfiguration.ts is not under rootDir (web/ts/jet-composites). This error is during the actual service. So something is going wrong at runtime, leading to the files not getting loaded and hence the component remaining incomplete (oj-incomplete), post rendering.

What is curious is that the rootDir for composite components is being treated as web/ts/jet-composites rather than the src/ts, as mentioned in the tsconfig.json. So there is something about jet-composites that I am missing.

Second, how accurate are VS Code imports intellisense suggestions? In other words, if I take the VS Code not showing compilation issues as a baseline, will my build process go through? Even if it does, I have the more serious first problem.

A related issue seems to be mentioned here. But I cannot find the loop snippet described by the author of that post.

Any ideas?

Tagged:

Best Answers

  • Duncan Mills-Oracle
    Duncan Mills-Oracle Member Posts: 4,079 Employee
    Answer ✓

    In order to be portable, custom components are always rooted to a path that represents the root of that component or the Pack that it is a member of, if that is the case.

    The JET ojet command line tool takes care of setting up that root path during the build process e.g. if you have a component my-button, then a path my-button pointing to the folder root of the component e.g. web/js/jet-composites/my-button/1.0.0/ will be automatically created. (In a typescript project there is also a mapping created in the tsconfig as well)

    This allows components to be switched between versions and deployment locations without the consuming application code having to change. It's also key in the optimization process for components during an ojet build --release

    The down-side of this protocol is that a custom component should never depend on a file that is outside of it's own root folder unless that is declared with a dependency in the metadata e.g. a component can depend on another component, and as part of that dependency it will gain access to the resources of that second component via a predictable path e.g. my-button could import 'my-shared-fwk/common/configuration'

    In fact there is a component type specifically for this purpose called a resource component:

    So the usual arrangement is to promote any common code into one of these resource components and then it can be re-used from both the core application and from any custom components using a predicable path.

  • Duncan Mills-Oracle
    Duncan Mills-Oracle Member Posts: 4,079 Employee
    Answer ✓

    If you want a lighter-weight solution you can always manually define a requirejs path for the location for the shared resources where they are today and then have the component import from this path rather than from an absolute location. That approach is fine if the components are not intended for re-use across projects - but generally it's actually simpler to define the resource component as the whole path thing is then taken care of for you.

Answers

  • Venkata Rahul S
    Venkata Rahul S Member Posts: 37 Blue Ribbon

    @John 'JB' Brock-Oracle or any other expert, need your expertise here. The problem continues despite the path now being correctly mentioned.

    The above comment made by me did not solve the issue.

  • Duncan Mills-Oracle
    Duncan Mills-Oracle Member Posts: 4,079 Employee
    Answer ✓

    In order to be portable, custom components are always rooted to a path that represents the root of that component or the Pack that it is a member of, if that is the case.

    The JET ojet command line tool takes care of setting up that root path during the build process e.g. if you have a component my-button, then a path my-button pointing to the folder root of the component e.g. web/js/jet-composites/my-button/1.0.0/ will be automatically created. (In a typescript project there is also a mapping created in the tsconfig as well)

    This allows components to be switched between versions and deployment locations without the consuming application code having to change. It's also key in the optimization process for components during an ojet build --release

    The down-side of this protocol is that a custom component should never depend on a file that is outside of it's own root folder unless that is declared with a dependency in the metadata e.g. a component can depend on another component, and as part of that dependency it will gain access to the resources of that second component via a predictable path e.g. my-button could import 'my-shared-fwk/common/configuration'

    In fact there is a component type specifically for this purpose called a resource component:

    So the usual arrangement is to promote any common code into one of these resource components and then it can be re-used from both the core application and from any custom components using a predicable path.

  • Venkata Rahul S
    Venkata Rahul S Member Posts: 37 Blue Ribbon

    I see the point. But it really is crippling to insist on a resource component.

  • Venkata Rahul S
    Venkata Rahul S Member Posts: 37 Blue Ribbon

    There is another issue even if we were to take this answer. If I place my common files outside the component, the compilation is going ahead without problems. So should it not be stopped at compile (itself of the typescript) time itself rather than allowing it appearing in runtime when the server is delivering the UI?

  • Duncan Mills-Oracle
    Duncan Mills-Oracle Member Posts: 4,079 Employee
    Answer ✓

    If you want a lighter-weight solution you can always manually define a requirejs path for the location for the shared resources where they are today and then have the component import from this path rather than from an absolute location. That approach is fine if the components are not intended for re-use across projects - but generally it's actually simpler to define the resource component as the whole path thing is then taken care of for you.

  • Venkata Rahul S
    Venkata Rahul S Member Posts: 37 Blue Ribbon

    Thank you very much. Require path is what I started using as a work-around. But will see how best to take the resource component.

    Do we have resource components in the cookbook?

  • Duncan Mills-Oracle
    Duncan Mills-Oracle Member Posts: 4,079 Employee

    There is not an example in the cookbook - that being said there would not be a lot to show. The "internal" layout of the resource component is up to you, it can be any folder structure as deep as you like. All we care about from the tooling perspective is that there is a component.json in the root folder for the component with the type set to "resource" and a version number.

    The only additional bit of metadata of interest is that the resource component can document "publicModules" which indicate the public APIs that the component shares- for the use case where a resource component has been shared and you want to document what entry points other teams are allowed to use. The --release build process will create bundles from those publicModules. In your case though you would not need this feature.

    Here's a sample component.json for one anyway (had to upload with a .txt extension)