Angular 5/6导入远程组件失败,求解决方法
Let's break down your problem first:
- The
Cannot find moduleerror happens because Angular's default module bundler (Webpack) doesn't support loading remote URLs directly—Webpack is designed to resolve dependencies at build time, so dynamic URL expressions throw it off. - The
Critical dependencywarning ties into this: Webpack can't statically analyze the dynamicimport()argument, so it flags it as a potential issue. - You're trying to load a raw TypeScript file (
app.module.ts) remotely, but browsers and module loaders can't execute TS directly—it needs to be compiled to JavaScript first.
Here's how to fix this step by step:
1. Serve Compiled JavaScript, Not Raw TypeScript
First, your remote module file must be a compiled ES/CommonJS JavaScript file, not a .ts file. Angular (and browsers) can't parse TypeScript directly in the browser without a preprocessor.
Compile your app.module.ts to JavaScript first (using tsc with settings to output a module), then host that .js file on your remote server/Gist.
2. Use SystemJS Properly (If You Stick With It)
You're using System.import(), but you need to configure SystemJS to recognize remote modules and handle their format:
- Install SystemJS via npm:
npm install systemjs - Add SystemJS to your project (either in
angular.jsonscripts or directly inindex.html) - Configure SystemJS to allow remote module loading in
index.html:
<script> System.config({ meta: { 'https://*.js': { format: 'esm' // Match the format of your compiled JS module } } }); </script>
- Fix the Webpack warning by telling it to ignore the dynamic import:
ngAfterViewInit(){ const url = 'https://your-server/compiled-app.module.js'; // Use compiled JS here // Tell Webpack to skip analyzing this dynamic import const importer = (url: string) => Observable.fromPromise( // @ts-ignore System.import(/* webpackIgnore: true */ url) ); importer(url) .subscribe((modules) => { this.cfr = this.compiler.compileModuleAndAllComponentsSync(modules['AppModule']); this.putStuffHere.createComponent(this.cfr.componentFactories[0], 0); }); }
3. Alternative: Load Remote Code via HttpClient (No SystemJS)
If you don't want to rely on SystemJS, you can fetch the compiled JS code directly with HttpClient, then compile it using Angular's compiler:
import { HttpClient } from '@angular/common/http'; import { Compiler, Injector } from '@angular/core'; constructor( private http: HttpClient, private compiler: Compiler, private injector: Injector ) {} ngAfterViewInit() { const remoteJsUrl = 'https://your-server/compiled-app.module.js'; this.http.get(remoteJsUrl, { responseType: 'text' }).subscribe(async (code) => { // Evaluate the remote code to get the module (only do this with trusted sources!) const remoteModule = eval(code); // Compile the module and create a component const moduleFactory = await this.compiler.compileModuleAsync(remoteModule['AppModule']); const moduleRef = moduleFactory.create(this.injector); const componentFactory = moduleRef.instance .componentFactoryResolver .resolveComponentFactory(remoteModule['YourComponent']); this.putStuffHere.createComponent(componentFactory); }); }
⚠️ Important: Using eval carries security risks—only load remote code from fully trusted sources.
4. Fix CORS Issues
If you're still getting errors, check if the remote server has CORS enabled. Browsers block cross-origin requests by default, so the remote server needs to send headers like Access-Control-Allow-Origin: * (or your specific domain) to allow your Angular app to fetch the resource.
5. Verify the Remote Module Structure
Make sure your compiled remote module exports the AppModule correctly, just like your local module does:
// Compiled app.module.js example export class AppModule { /* ... */ } export class YourComponent { /* ... */ }
内容的提问来源于stack exchange,提问作者hamobi

