javascript - Angular 2 使用 SystemJS 和 Gulp 部署太重了

标签 javascript angular gulp systemjs

我使用 Angular 进行开发已经有一段时间了,但我刚刚开始使用 Angular 2,在完成 Angular 2 教程的快速入门后,我考虑尝试在服务器中以生产模式开发最终的应用程序。

我没有使用 SystemJS 和 Gulp 的经验,所以我花了一段时间,但我终于成功地让它工作了。现在我有两个问题:

对于 Hello World 应用程序来说,它非常重,大约 20MB,因为我必须从 Angular 2 库下载大量文件。我的猜测是我实际上并不需要那么多,但是尽管我一开始只使用了 @Angular/core 和 @Angular/platform-b​​rowser-dynamic(它们是我的应用程序 ts 文件中引用的内容),但 Angular 在部署中不断抛出错误消息直到我包含整个@Angular 库。

另一方面,当我运行该应用程序时,我再次看到许多单个文件正在下载,这不是我想要的。必须有一种方法可以只下载包含所有库的单个(缩小的)文件( bundle ?),但我不知道该怎么做。

有人可以帮我吗?

这是我的主要配置文件。

系统配置.js

(function(global) {

  // map tells the System loader where to look for things
  var map = {
    'app': 'app', // 'dist',
    '@angular': 'lib/@angular',
    'rxjs': 'lib/rxjs'
  };

  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app': { main: 'main.js',  defaultExtension: 'js' },
    'rxjs': { defaultExtension: 'js' }
  };

  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'http',
    'platform-browser',
    'platform-browser-dynamic'
  ];
  // Individual files (~300 requests):
  function packIndex(pkgName) {
    packages['@angular/' + pkgName] = { main: 'index.js', defaultExtension: 'js' };
  }
  // Add package entries for angular packages
  ngPackageNames.forEach(packIndex);

  var config = {
    map: map,
    packages: packages
  };

  System.config(config);

})(this);

index.html

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <link rel="stylesheet" href="./css/styles.css">
    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <script src="lib/shim.min.js"></script>
    <script src="lib/zone.js"></script>
    <script src="lib/Reflect.js"></script>
    <script src="lib/system.src.js"></script>
    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
  </head>
  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

gulpfile.js

var gulp = require('gulp');
var ts = require('gulp-typescript');
const babel = require('gulp-babel');

var tsProject = ts.createProject('tsconfig.json');

gulp.task('babel-dp', ['resources', 'babel']);
gulp.task('ts-dp', ['resources', 'ts']);

gulp.task('resources', () => {
  gulp.src([
    'node_modules/core-js/client/shim.min.js',
    'node_modules/zone.js/dist/zone.js',
    'node_modules/reflect-metadata/Reflect.js',
    'node_modules/systemjs/dist/system.src.js'
  ]).pipe(gulp.dest('web/lib'));

  gulp.src([
    'node_modules/@angular/**/*',
  ]).pipe(gulp.dest('web/lib/@angular'));

  gulp.src([
    'node_modules/rxjs/**/*',
  ]).pipe(gulp.dest('web/lib/rxjs'));

  gulp.src([
    'app/**/*.js'
  ]).pipe(gulp.dest('web/app'));

  gulp.src([
    'styles.css'
  ]).pipe(gulp.dest('web/css'));

  gulp.src([
    'index.html',
    'systemjs.config.js',
    'favicon.ico'
  ]).pipe(gulp.dest('web'));
});

gulp.task('babel', () => {
    return gulp.src([
    'app/**/*.ts'
    ])
        .pipe(babel({presets: ['es2015']}))
        .pipe(gulp.dest('web/js'));
});

gulp.task('ts', function(done) {
  var tsResult = tsProject.src([
      'app/**/*.ts'
    ])
    .pipe(ts(tsProject));
  return tsResult.js.pipe(gulp.dest('web/js'));
});

如果您需要任何其他文件,请告诉我。 非常感谢!

更新

我刚刚发现我可以使用 @angular 中的 umd.min.js 文件而不是单个 js 文件。虽然从 20 到 5MB 不等,但当 Angular 1 的缩小版本小于 1MB 时,看起来仍然相当多。

另一方面,即使我使用了这些 umd.min.js 文件,chrome 在加载应用程序时仍然下载单个文件。

更新2

我成功地按照评论中的建议使用 systemjs-builder 创建了一个捆绑文件。现在我有一个文件bundle.app.js 包含我的所有应用程序代码,我的index.html 现在看起来像这样

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <link rel="stylesheet" href="css/styles.css">
    <!-- 1. Load libraries -->
    <script src="app/bundle.app.js"> </script>
    <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script>
      System.import('app').catch(function(err) { console.error(err); });
    </script>
  </head>
  <!-- 2. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

但是现在chrome找不到html中导入的js:shim.min.js、zone.js、Reflect.js和system.src.js。 我在 systemjs.config.js 中添加了一行以包含 node_modules 以防万一,但我认为没有必要。无论如何,它也不起作用。这些导入不应该已经包含在 bundle 中吗?

最佳答案

好吧,我终于得到了一个有效的配置,所以我将在这里复制所需的所有文件,以防有人发现它有帮助。

index.html

<html>
  <head>
    <title>Angular 2 QuickStart Deploy</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <link rel="stylesheet" href="css/styles.css">
    <!-- 1. Load libraries -->
    <!-- Polyfill(s) for older browsers -->
    <script src="lib/shim.min.js"></script>
    <script src="lib/zone.js"></script>
    <script src="lib/Reflect.js"></script>
    <script src="lib/system.src.js"></script>
  </head>
  <!-- 2. Display the application -->
  <body>
    <my-app>Loading...</my-app>
    <!-- application bundle -->
    <script src="app/bundle.app.js"></script>
  </body>
</html>

gulpfile.js

const gulp = require('gulp');
const ts = require('gulp-typescript');
const babel = require('gulp-babel');
const Builder = require('systemjs-builder');

// systemjs-builder
const builder = new Builder('.', 'systemjs.config.js');

// typescript transpiler
var tsProject = ts.createProject('tsconfig.json');

gulp.task('babel-dp', ['resources', 'babel']);
gulp.task('ts-dp', ['resources', 'ts']);

gulp.task('bundle:app', () => {
  builder.buildStatic('app/*.js', 'web/app/bundle.app.js')
  .then(function() {
    console.log('Build complete');
  })
  .catch(function(err) {
    console.log('error ' + err);
  })
})

gulp.task('resources', () => {
  gulp.src([
    'node_modules/core-js/client/shim.min.js',
    'node_modules/zone.js/dist/zone.js',
    'node_modules/reflect-metadata/Reflect.js',
    'node_modules/systemjs/dist/system.src.js'
  ]).pipe(gulp.dest('web/lib'));

  gulp.src([
    'styles.css'
  ]).pipe(gulp.dest('web/css'));

  gulp.src([
    'index.html',
    'favicon.ico'
  ]).pipe(gulp.dest('web'));
});

gulp.task('babel', () => {
    return gulp.src([
    'app/**/*.ts'
    ])
        .pipe(babel({presets: ['es2015']}))
        .pipe(gulp.dest('web/js'));
});

gulp.task('ts', function(done) {
  var tsResult = tsProject.src([
      'app/**/*.ts'
    ])
    .pipe(ts(tsProject));
  //return tsResult.js.pipe(gulp.dest('web/js'));
  return tsResult.js.pipe(gulp.dest('app/js'));
});

其余文件没有改变。 对我来说,这里的要点是使用 systemjs-builder 创建 bundle (感谢 @Thorsten 的提示)以及在 index.html 中使用 bundle 。

关于javascript - Angular 2 使用 SystemJS 和 Gulp 部署太重了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38238267/

相关文章:

javascript - 扩展浏览器以处理 Apple 键盘事件

javascript - 在html中显示图片

angular - typescript 错误在@ionic-native/geolocation 中找不到名称 'Observable'

javascript - 创建组件代替点击事件

node.js - 无法将命名空间用作 Angular 类型

javascript - 构建 JavaScript 项目 Travis-CI 时出错

node.js - 在终端中停止 Gulp 时如何关闭 BrowserSync 的旧实例?

javascript - 将时间输入设置为数据库中的日期时间

node.js 错误 : Cannot find module 'lodash.assign'

javascript - 映射下拉列表选择 URL