You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求SystemJS最新版本替代registerDynamic实现Angular动态模块加载方案

SystemJS 0.21.x registerDynamic Replacement & Angular Dynamic Module Loading Update

Hey there! Let's break down how to update your old SystemJS code and explore better alternatives for modern Angular projects. SystemJS 6+ completely removed the registerDynamic API, so we'll adjust your code to use the latest supported methods first.

What Replaces registerDynamic in SystemJS 6+?

The old registerDynamic was designed for non-ES module formats. In the latest SystemJS versions, you have two primary replacements:

  • System.set with explicit module objects: Best for wrapping dynamic code into a module structure SystemJS understands.
  • System.register: For replicating the full module loading lifecycle (require/exports/module pattern) if you need more control.

For your use case, we'll use System.set since we're working with a dynamic JavaScript string that follows the old CommonJS-style pattern.

Rewritten Code for SystemJS 6+

Here's the updated version of your component, with key changes to replace registerDynamic and align with modern SystemJS APIs:

import * as _dal from 'data-access-layer';
import * as _ngbForms from '@ng-bootstrap/ng-bootstrap';
import * as _ngCommon from '@angular/common';
import * as _ngCore from '@angular/core';
import * as _ngForms from '@angular/forms';
import * as _ngHttpClient from '@angular/common/http';
import { Compiler, Injector, ViewContainerRef } from '@angular/core';

@Component({
  selector: 'app-custom-mod',
  templateUrl: './custom-mod.component.html',
  styleUrls: ['./custom-mod.component.css']
})
export class CustomModComponent implements OnInit {
  // Inject required Angular dependencies in the constructor
  constructor(
    private compiler: Compiler,
    private injector: Injector,
    private vc: ViewContainerRef
  ) {}

  ngOnInit() {
    this.LoadComponent();
  }

  LoadComponent() {
    const moduleId = `@customModule-${this.id}`;
    
    // 1. Register existing dependencies (this part stays mostly unchanged)
    System.set('@angular/core', System.newModule(_ngCore));
    System.set('@angular/common', System.newModule(_ngCommon));
    System.set('@angular/forms', System.newModule(_ngForms));
    System.set('@angular/common/http', System.newModule(_ngHttpClient));
    System.set('@ng-bootstrap/ng-bootstrap', System.newModule(_ngbForms));
    System.set('@dal', System.newModule(_dal));
    // Don't forget to register '@app' if it's a local project dependency
    // System.set('@app', System.newModule(/* Your app module exports here */));

    // 2. Clean up existing module if it exists
    const normalizedId = System.normalizeSync(moduleId);
    if (System.has(normalizedId)) {
      System.delete(normalizedId);
    }

    // 3. Replace registerDynamic with manual module creation + System.set
    const dynamicCodeRunner = new Function(
      'require', 'exports', 'module',
      this.Javascript
    );

    // Execute the dynamic code in a CommonJS-like context
    const moduleExports = {};
    const moduleContext = { exports: moduleExports };
    dynamicCodeRunner(
      (dep) => System.get(System.normalizeSync(dep)),
      moduleExports,
      moduleContext
    );

    // Wrap the result into a SystemJS-compatible module
    const dynamicModule = System.newModule({
      default: moduleContext.exports.default || moduleContext.exports
    });

    // Register the dynamic module with SystemJS
    System.set(normalizedId, dynamicModule);

    // 4. Import and compile the module (Angular logic remains similar)
    System.import(moduleId).then((module) => {
      this.compiler.compileModuleAndAllComponentsAsync(module.default)
        .then((compiled) => {
          const moduleRef = compiled.ngModuleFactory.create(this.injector);
          const _injector = moduleRef.injector;
          const widgets = _injector.get('widgets');
          const resolver = moduleRef.componentFactoryResolver;
          const componentFactory = resolver.resolveComponentFactory(widgets[0][0].component);
          this.componentRef = this.vc.createComponent(componentFactory);
          this.componentRef.instance.OnLoad();
        });
    }).catch(err => {
      console.error('Failed to load dynamic module:', err);
    });
  }
}

Key Changes Explained:

  • Removed registerDynamic: We manually execute your dynamic JavaScript in a CommonJS-style context, then wrap the result into a SystemJS-compatible module and register it with System.set.
  • Normalization Consistency: We normalize the module ID upfront to match SystemJS's internal registry rules.
  • Error Handling: Added a catch block to debug any loading/compilation failures—critical for dynamic code scenarios.

Better Alternatives to SystemJS for Angular

If you're looking to modernize your workflow, consider these frameworks/approaches that integrate natively with Angular:

1. Angular Native Dynamic Loading

Angular has built-in APIs for dynamic component/module loading without external tools:

  • Use ViewContainerRef.createComponent (Angular 13+) for direct component injection.
  • For dynamic modules, use compileModuleAsync (note: runtime compilation requires JIT mode or disabling Ivy in Angular 13+).

2. Webpack Module Federation

For large-scale dynamic loading (like microfrontends), Webpack Module Federation is the industry standard. It lets you dynamically load modules from remote servers, share dependencies efficiently, and works seamlessly with Angular's build pipeline—no SystemJS required.

内容的提问来源于stack exchange,提问作者Guru Kara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:21:38