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

Angular1.6与Angular5共存迁移咨询:无需改旧代码且可独立运行

Hey there, great question! Running AngularJS 1.6 and Angular 5 side-by-side without modifying your legacy code is totally feasible using Angular's official UpgradeModule. Let me break down a complete implementation for you, including project structure, Grunt build setup, and how to run both apps independently.


Core Approach

We'll leverage Angular's UpgradeModule to bootstrap both AngularJS 1.6 and Angular 5 in the same page. The legacy AngularJS code stays 100% untouched, while the new Angular 5 app can coexist or even interact with it (if needed). We'll also set up separate entry points to run each app independently.


Project Structure

Here's a clean, maintainable structure that keeps legacy and new code completely separated:

angular-hybrid-project/
├── legacy/                  # Your unmodified AngularJS 1.6 codebase
│   ├── app/
│   │   ├── controllers/
│   │   ├── directives/
│   │   ├── services/
│   │   └── app.js           # Original AngularJS entry module
│   ├── index.html           # Pure AngularJS standalone entry
│   └── assets/              # CSS, images, etc. for legacy app
├── ng5-app/                 # Angular 5 application code
│   ├── src/
│   │   ├── app/
│   │   │   ├── app.module.ts
│   │   │   ├── app.component.ts
│   │   │   └── upgrade/     # Upgrade bridge code
│   │   │       └── upgrade.module.ts
│   │   ├── index.html       # Hybrid app entry (both frameworks)
│   │   └── main.ts          # Angular 5 bootstrap entry
│   └── tsconfig.json
├── Gruntfile.js             # Unified build configuration
├── package.json
└── .gitignore

Key Code Implementations

1. Unmodified AngularJS 1.6 Code

Your legacy app.js stays exactly as-is:

// legacy/app/app.js
angular.module('legacyApp', [])
  .controller('LegacyController', function($scope) {
    $scope.legacyMessage = "Hello from AngularJS 1.6!";
  });

2. Angular 5 Upgrade Bridge

Create an upgrade module to bootstrap both frameworks:

// ng5-app/src/app/upgrade/upgrade.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static';
import { AppComponent } from '../app.component';

// Declare global AngularJS variable for TypeScript
declare var angular: any;

@NgModule({
  imports: [
    BrowserModule,
    UpgradeModule
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class UpgradeAppModule {
  constructor(private upgrade: UpgradeModule) {}

  ngDoBootstrap() {
    // Bootstrap the legacy AngularJS app alongside Angular 5
    this.upgrade.bootstrap(document.body, ['legacyApp'], { strictDi: true });
  }
}

3. Angular 5 Entry Point

Update main.ts to use the upgrade module:

// ng5-app/src/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { UpgradeAppModule } from './app/upgrade/upgrade.module';
import 'core-js/es6';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';

platformBrowserDynamic().bootstrapModule(UpgradeAppModule);

4. Entry HTML Files

Pure AngularJS Entry (legacy/index.html)

Keep your original legacy entry:

<!DOCTYPE html>
<html ng-app="legacyApp">
<head>
  <meta charset="UTF-8">
  <title>Pure AngularJS 1.6 App</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>
  <script src="app/app.js"></script>
</head>
<body ng-controller="LegacyController">
  <h1>{{ legacyMessage }}</h1>
</body>
</html>

Hybrid Entry (ng5-app/src/index.html)

Load AngularJS first, then bootstrap Angular 5:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Hybrid AngularJS + Angular 5 App</title>
  <!-- Load AngularJS dependencies -->
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>
  <!-- Load unmodified legacy code -->
  <script src="../../legacy/app/app.js"></script>
  <!-- Load Angular 5 polyfills -->
  <script src="assets/shim.min.js"></script>
  <script src="assets/zone.js"></script>
</head>
<body>
  <!-- Angular 5 component -->
  <app-root></app-root>

  <!-- Unmodified AngularJS component -->
  <div ng-controller="LegacyController">
    <h2>{{ legacyMessage }}</h2>
  </div>
</body>
</html>

Grunt Build Configuration

1. Package Dependencies

Add these to your package.json:

{
  "name": "angular-hybrid-app",
  "version": "1.0.0",
  "devDependencies": {
    "grunt": "^1.0.4",
    "grunt-contrib-copy": "^1.0.0",
    "grunt-contrib-connect": "^3.0.0",
    "grunt-contrib-watch": "^1.1.0",
    "grunt-ts": "^6.0.0-beta.22",
    "typescript": "^2.9.2"
  },
  "dependencies": {
    "@angular/common": "^5.2.11",
    "@angular/compiler": "^5.2.11",
    "@angular/core": "^5.2.11",
    "@angular/platform-browser": "^5.2.11",
    "@angular/platform-browser-dynamic": "^5.2.11",
    "@angular/upgrade": "^5.2.11",
    "core-js": "^2.5.7",
    "rxjs": "^5.5.12",
    "zone.js": "^0.8.29"
  }
}

2. Gruntfile.js Setup

Configure tasks for building, running the pure legacy app, and running the hybrid app:

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    // Compile TypeScript for Angular 5
    ts: {
      default: {
        tsconfig: './ng5-app/tsconfig.json'
      }
    },

    // Copy static assets to dist folder
    copy: {
      ng5Assets: {
        files: [
          { expand: true, cwd: 'ng5-app/src', src: ['index.html'], dest: 'dist/ng5' },
          { expand: true, cwd: 'node_modules/core-js/client', src: ['shim.min.js'], dest: 'dist/ng5/assets' },
          { expand: true, cwd: 'node_modules/zone.js/dist', src: ['zone.js'], dest: 'dist/ng5/assets' },
          { expand: true, cwd: 'node_modules/@angular', src: ['**/*.umd.min.js'], dest: 'dist/ng5/assets/angular' }
        ]
      },
      legacyAssets: {
        files: [
          { expand: true, cwd: 'legacy', src: ['**/*'], dest: 'dist/legacy' }
        ]
      }
    },

    // Development servers
    connect: {
      legacy: {
        options: {
          port: 8080,
          base: 'dist/legacy',
          livereload: true
        }
      },
      hybrid: {
        options: {
          port: 8081,
          base: 'dist/ng5',
          livereload: true
        }
      }
    },

    // Watch for file changes
    watch: {
      ts: {
        files: ['ng5-app/src/**/*.ts'],
        tasks: ['ts', 'copy:ng5Assets'],
        options: { livereload: true }
      },
      legacy: {
        files: ['legacy/**/*'],
        tasks: ['copy:legacyAssets'],
        options: { livereload: true }
      }
    }
  });

  // Load plugins
  grunt.loadNpmTasks('grunt-ts');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Custom tasks
  grunt.registerTask('build', ['ts', 'copy']);
  grunt.registerTask('run-legacy', ['build', 'connect:legacy', 'watch:legacy']);
  grunt.registerTask('run-hybrid', ['build', 'connect:hybrid', 'watch:ts']);
};

How to Run
  1. Install dependencies: Run npm install
  2. Run pure AngularJS app: Execute grunt run-legacy, then visit http://localhost:8080
  3. Run hybrid app: Execute grunt run-hybrid, then visit http://localhost:8081

Both apps run independently, and your legacy AngularJS code remains completely unmodified.


Key Notes
  • Ensure your AngularJS module name matches what's referenced in the UpgradeAppModule
  • TypeScript's tsconfig.json should target ES5 and use CommonJS modules for Angular 5 compatibility
  • If you don't need interaction between the two frameworks, they'll run entirely independently in the same page

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:51:50