Javascript 动态生成适当的角度元素,而不增加构建大小? 总结:
当在开关盒内多次调用Javascript 动态生成适当的角度元素,而不增加构建大小? 总结:,javascript,angular,sass,web-component,angular-elements,Javascript,Angular,Sass,Web Component,Angular Elements,当在开关盒内多次调用createCustomElement()时,所有组件都将包含在构建中,而不仅仅是实际使用的组件。这会使用重复的代码增加生成大小 细节 我有一个多站点架构的Angular 11应用程序。每个站点的angular.json中都有一个项目,因此它们可以独立构建,并根据包含“siteCode”的相应environment.ts文件生成自己的dist bundle 对于我网站中的一个大组件——我们称之为myWidget——我还将其导出为通用web组件(也称为“Angular Elem
createCustomElement()
时,所有组件都将包含在构建中,而不仅仅是实际使用的组件。这会使用重复的代码增加生成大小
细节
我有一个多站点架构的Angular 11应用程序。每个站点的angular.json
中都有一个项目,因此它们可以独立构建,并根据包含“siteCode”的相应environment.ts
文件生成自己的dist bundle
对于我网站中的一个大组件——我们称之为myWidget——我还将其导出为通用web组件(也称为“Angular Element”,也称为“custom Element”),供其他网站使用。因此,我在主应用程序的一个子项目中有myWidget,它也在angular.json
中列出了自己的项目。这意味着我可以运行一个构建,该构建应该只包含给定站点的myWidget(显然还有核心Angular框架)
myWidget子项目的app.module.ts(简化):
import { MyWidgetSite1Component } from './my-widget/site-widgets/my-widget-site1.component';
import { MyWidgetSite2Component } from './my-widget/site-widgets/my-widget-site2.component';
import { MyWidgetSite3Component } from './my-widget/site-widgets/my-widget-site3.component';
@NgModule({
declarations: [AppComponent],
imports: [MyWidgetModule]
})
export class AppModule {
constructor(private injector: Injector) {
//Create generic web component version of myWidget. Use correct child version per site.
switch (environment.siteCode) {
case "site1": {
const myWidgetCustomElement = createCustomElement(MyWidgetSite1Component , { injector: this.injector });
customElements.define('site1-myWidget', myWidgetCustomElement);
break;
}
case "site2": {
const myWidgetCustomElement = createCustomElement(MyWidgetSite2Component , { injector: this.injector });
customElements.define('site2-myWidget', myWidgetCustomElement);
break;
}
case "site3": {
const myWidgetCustomElement = createCustomElement(MyWidgetSite3Component , { injector: this.injector });
customElements.define('site3-myWidget', myWidgetCustomElement);
break;
}
}
}
}
问题:它包含构建中的所有三个组件,而不仅仅是将用于该站点的组件(通过webpack bundle analyzer验证)
进一步的背景
这里的三个特定于站点的myWidget组件都继承自一个公共基础组件,其中所有的实际逻辑都是相同的,因此它们几乎是相同的。我这样做是为了能够为该站点加载适当的CSS文件,并将它们作为特定于组件的CSS打包到导出的MyWidget web组件中。它使用shadowDom封装,这样web组件就与插入到其中的父页面完全隔离。因此,所讨论的组件如下所示:
my-widget-site1.component.ts
@Component({
selector: 'my-widget-site1',
templateUrl: '../my-widget/my-widget.component.html', //Shares base myWidget template
//First file does nothing but import appropriate site's stylesheets from main project. It would
//have been better to directly include them here, but that resulted in odd build errors.
styleUrls: [
'./my-widget-site1.component.scss',
'../my-widget/my-widget.component.scss'],
encapsulation: ViewEncapsulation.ShadowDom
})
export class MyWidgetSite1Component extends MyWidgetComponent implements OnInit {
//Do not add any code here
}
@import '../../../../../../src/app/sites/site1/theme.scss';
@import '../../../../../../src/styles.scss';
@import '../../../../../../src/app/sites/site1/styles.scss';
my-widget-site1.component.scss
@Component({
selector: 'my-widget-site1',
templateUrl: '../my-widget/my-widget.component.html', //Shares base myWidget template
//First file does nothing but import appropriate site's stylesheets from main project. It would
//have been better to directly include them here, but that resulted in odd build errors.
styleUrls: [
'./my-widget-site1.component.scss',
'../my-widget/my-widget.component.scss'],
encapsulation: ViewEncapsulation.ShadowDom
})
export class MyWidgetSite1Component extends MyWidgetComponent implements OnInit {
//Do not add any code here
}
@import '../../../../../../src/app/sites/site1/theme.scss';
@import '../../../../../../src/styles.scss';
@import '../../../../../../src/app/sites/site1/styles.scss';
结论
我可以想出一些解决这个问题的总体思路:
1)动态加载所需组件的一些技巧,而不是在交换机情况下加载?
我什么也没找到。似乎只要我必须导入组件,它就会包含在构建中
2)避免每个站点都有多个版本的组件?
我很想这样做,但我不知道如何避开CSS问题。特定站点的适当CSS文件需要在构建时绑定到此组件中,以便将它们封装在web组件的影子根中,而不是作为单独的CSS文件构建,并导入到消费页面的全局范围中。这意味着我不能在angular.json
我试图在SCS上执行动态@import
语句,但这似乎不可能
您能否以某种方式在构建过程中编写脚本,以便在构建时选择正确的scss文件?我不知道从哪里开始做这样的事情。我想出了一个有趣的解决方案
通过使用“快捷方式”指向必要的scss文件而不是完整路径,我可以摆脱对多个组件文件的需要,并有效地实现动态导入:
@import "theme";
@import "styles";
@import "site-styles";
您可以通过angular.json
配置它将在其中找到指定文件的文件夹:
"stylePreprocessorOptions": {
"includePaths": [
"src/app/sites/site1/", //theme.scss and site-styles.scss are here
"src/" //styles.scss is here
]
}
因此,现在我可以使用一个始终具有相同导入的组件,但在构建时,它实际上会为正在构建的站点使用正确的文件
有关快捷方式语法的信息:您是否尝试过使用?