如何使用SystemJS和Gulp准备发布版本?

时间:2016-01-05 15:00:51

标签: typescript gulp angular systemjs

我在Angular2项目中使用SystemJS。我为TypeScript使用tsconfig文件。我想使用gulp来连接和缩小我的生产版代码。我在解决代码问题上遇到了问题:每次尝试连接文件时,我都会遇到“角度”问题。没有定义或'系统'没有定义的。我试图修改我尝试从节点模块加载文件的顺序,但是我没有成功。

我想知道你们是否有这个问题,并找到答案了吗?

这是我的gulp文件:

var gulp = require('gulp'),
            .....


var paths = {
    dist: 'dist',
    vendor: {
        js: [
            'node_modules/systemjs/dist/system.src.js',
            'node_modules/angular2/bundles/angular2.dev.js',
            'node_modules/angular2/bundles/angular2-polyfills.js',
            'node_modules/angular2/bundles/router.dev.js'
             ...
        ],
        css: []
},
    app: {
        templates: [
            'app/**/*.html',
            '!node_modules/*.html'
        ],
        scripts: [
            'app/**/*.ts',
            'app/config.ts',
            'app/app.ts'
        ]
    }
};

var tsProject = ts.createProject('tsconfig.json', {
    out: 'Whatever.js'
});

gulp.task('dev:build:templates', function () {
    return gulp.src(paths.app.templates)
        .pipe(ngHtml2Js({
            moduleName: 'Whatever',
            declareModule: false
        }))
        .pipe(concat("Whatever.tpls.min.js"))
        .pipe(gulp.dest(paths.dist));
});
gulp.task('prod:build:templates', function () {
    return gulp.src(paths.app.templates)
        .pipe(minifyHtml({
            empty: true,
            spare: true,
            quotes: true
        }))
        .pipe(ngHtml2Js({
            moduleName: 'whatever',
            declareModule: false
        }))
        .pipe(concat(paths.appName + ".tpls.min.js"))
        .pipe(uglify())
        .pipe(gulp.dest(paths.dist));
});

gulp.task('dev:build:scripts', function () {
    var tsResult = tsProject.src()
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject));

    return tsResult.js
        .pipe(sourcemaps.write({
            sourceRoot: '/app'
        }))
        .pipe(concat('whatever.js'))
        .pipe(gulp.dest(paths.dist));
});

gulp.task('dev:build:styles', function () {
    return gulp.src(paths.app.styles)
        .pipe(sass())
        .pipe(gulp.dest(paths.dist + '/css'));
});
gulp.task('dev:build:vendor', function () {
    return gulp.src(paths.vendor.js)
        .pipe(concat('vendor.min.js'))
        .pipe(gulp.dest(paths.dist))
});

gulp.task('dev:build', [
    'dev:build:vendor',
    'dev:build:templates',
    'dev:build:scripts',
    'dev:build:styles',
], function () {
});

这是我加载文件的方式:

   <script src="vendor.min.js"></script>
   <script src="Whatever.js"></script>
   <script src="Whatever.tpls.min.js"></script>

以下是我得到的错误:

Uncaught TypeError: Unexpected anonymous System.register call.(anonymous function) @ vendor.min.js:2680load.metadata.format @ vendor.min.js:3220oldModule @ vendor.min.js:3749(anonymous function) @ vendor.min.js:2411SystemJSLoader.register @ vendor.min.js:2636(anonymous function) @ Whatever.js:2
Whatever.tpls.min.js:1 Uncaught ReferenceError: angular is not defined

3 个答案:

答案 0 :(得分:29)

你会得到&#34;意外的匿名System.register调用&#34;因为引用没有按正确的顺序加载。我使用JSPM来正确构建我的角度应用程序以进行生产。该过程分为4个部分。

第1部分:编译打字稿文件

&#13;
&#13;
var ts = require("gulp-typescript");
var tsProject = ts.createProject("./App/tsconfig.json");
gulp.task("compile:ts", function () {
    var tsResult = tsProject.src()
        .pipe(ts(tsProject));
    tsResult.js.pipe(gulp.dest("./wwwroot/app"));

});
&#13;
&#13;
&#13;

第2部分:配置config.js(告诉JSPM如何捆绑你的应用程序):

&#13;
&#13;
System.config({
  baseURL: "/",
  defaultJSExtensions: true,
  paths: {
    "npm:*": "jspm_packages/npm/*",
    "github:*": "jspm_packages/github/*",
    "node_modules*": "node_modules/*"
  },
  map: {
    'app': 'app',
    'rxjs': 'node_modules/rxjs',
    '@angular': 'node_modules/@angular'
  },
  packages: {
    'app': { main: 'bootDesktop.js', defaultExtension: 'js' },
    'rxjs': { defaultExtension: 'js' },
    '@angular/common': { main: 'index.js', defaultExtension: 'js' },
    '@angular/compiler': { main: 'index.js', defaultExtension: 'js' },
    '@angular/core': { main: 'index.js', defaultExtension: 'js' },
    '@angular/http': { main: 'index.js', defaultExtension: 'js' },
    '@angular/platform-browser': { main: 'index.js', defaultExtension: 'js' },
    '@angular/platform-browser-dynamic': { main: 'index.js', defaultExtension: 'js' },
    '@angular/router': { main: 'index.js', defaultExtension: 'js' },
    '@angular/router-deprecated': { main: 'index.js', defaultExtension: 'js' },
    '@angular/testing': { main: 'index.js', defaultExtension: 'js' },
    '@angular/upgrade': { main: 'index.js', defaultExtension: 'js' }
  }


});
&#13;
&#13;
&#13;

第3部分:使用gulp-jspm-build捆绑你的应用程序(我之前使用的是gulp-jspm,但它导致错误,所以我切换到gulp-jspm-build):

&#13;
&#13;
var jspm = require('gulp-jspm-build');
gulp.task("jspm_bundle", function () {
return jspm({
    bundleOptions: {
        minify: true,
        mangle: false
    },
    bundleSfx: true,
    bundles: [
        { src: './wwwroot/app/appBoot.js', dst: 'boot.bundle.min.js' }
    ]
})
.pipe(gulp.dest('./wwwroot/js-temp'));


});
//this will create a file called boot.bundle.min.js
//note I have set jspm to create a self-executing bundle
//I put mangle to false because mangling was causing errors 
&#13;
&#13;
&#13;

4:现在连接所有已经缩小的资产:

&#13;
&#13;
gulp.task("min:js", ["jspm_bundle"], function () {
    //this only concats boot.bundle.min.js
    //and dependencies.min.js which has already been minified such as es6-shim.js
    var files = [
        "./wwwroot/js-temp/dependencies.min.js",
        "./wwwroot/js-temp/boot.bundle.min.js"
    ];

    return gulp.src(files)
        .pipe(concat("boot.bundle.min.js"))
        .pipe(gulp.dest("./wwwroot/js"));

});
&#13;
&#13;
&#13;

最后,将一个漂亮的整洁脚本引用放入index.html:

&#13;
&#13;
<script src="~/js/boot.bundle.min.js"> </script>
&#13;
&#13;
&#13; 这种方法的一个很好的功能是你的捆绑应用程序将只包含你导入语句中实际引用的资产(如果你不需要它,jspm不会捆绑它)。

更新:修改config.js以符合Angular 2.0-rc.0 appp

更新2:tsconfig.json如下所示:

&#13;
&#13;
{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "declaration": false,
    "noLib": false,
    "target": "es5",
    "outDir": "wwwroot/app/"
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}
&#13;
&#13;
&#13;

答案 1 :(得分:4)

您可以使用SystemJS Builder

就像这个一样简单

var path = require("path");
var Builder = require('systemjs-builder');

// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('path/to/baseURL', 'path/to/system/config-file.js');

builder
.bundle('local/module.js', 'outfile.js')
.then(function() {
  console.log('Build complete');
})
.catch(function(err) {
  console.log('Build error');
  console.log(err);
});

您可以查看我的starter project

中的完整设置

答案 2 :(得分:0)

我认为我们找到了这个的根本原因。老实说,我以前去过那里,所以跟踪这类问题的方式是

  1. 检查角度和角度是否systemjs预先加载。
  2. 检查它们是否真的已装入。没有404惊喜。 (这听起来很愚蠢,但狗屎发生了)
  3. 如果您将库捆绑为vender.js,请确保它们以正确的顺序捆绑。检查输出文件,看看它们是否符合您的期望。