【问题标题】:How to combine (minify) compiled Angular 2 components?如何组合(缩小)已编译的 Angular 2 组件?
【发布时间】:2016-03-05 06:55:19
【问题描述】:

尝试缩小项目的已编译源代码以用于生产, 我使用 Gulp 作为任务运行器。

源文件如下所示,

html

<!--... . .  various scripts and styles . . . . . --->
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>

<script>
  System.config({
    packages: {        
      app: {
        format: 'register',
        defaultExtension: 'js'
      }
    }
  });
  System.import('app/main')
        .then(null, console.error.bind(console));
</script>
</head>
<body>
  <app></app>
</body>

我的app目录结构如下,

.
├── main.js
├── main.js.map
├── main.ts
├── main.app.js
├── main.app.js.map
├── main.app.ts
├── x.component1
│   ├── x.component.one.js
│   ├── x.component.one.js.map
│   └── x.component.one.ts
└── x.component2
    ├── x.component.two.js
    ├── x.component.two.js.map
    └── x.component.two.ts

app/main.ts

import {bootstrap}    from 'angular2/platform/browser';
import {MyAwesomeApp} from './main.app'

bootstrap(MyAwesomeApp);

main.app.ts

@Component({
    selector: 'app',
    template: `
        <component-1></component-1>

        <component-2></component-2>
    `,
    directives: [Component1, Component2]
})


export class MyAwesomeApp {

}

然后是组件,

@Component({
    selector: 'component-1',
    template: `
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Beatae ducimus, saepe fugit illum fuga praesentium rem, similique deserunt tenetur laudantium et labore cupiditate veniam qui impedit, earum commodi quasi sequi.
    `
})


export class Component1 {

}

@Component({
    selector: 'component-2',
    template: `
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Beatae ducimus, saepe fugit illum fuga praesentium rem, similique deserunt tenetur laudantium et labore cupiditate veniam qui impedit, earum commodi quasi sequi.
    `
})


export class Component2 {

}

所有的 TypeScript 文件都被编译为 ES5 JavaScript,进一步需要压缩到main.js

所以我的问题是,

  1. 我可以运行一个任务来收集所有已编译的.js 文件以缩小为单个文件并在生产分支中将其引用为main
  2. 这是否会破坏模块系统 import {x} from 'y'?
  3. 如果它破坏了模块加载系统,如何在 Angular 2 应用程序上连接文件?

我的 TypeScript 版本是 1.8.2

感谢您的帮助。

【问题讨论】:

    标签: javascript angular minify


    【解决方案1】:

    如果要将所有 TypeScript 文件编译成一个文件,则需要使用 TypeScript 编译器的 outFile 属性。它可以通过 gulp-typescript 插件进行配置。

    这样你就不需要配置 SystemJS 来根据文件名加载模块了:

    <script>
      // Not necessary anymore
      /* System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      }); */
      System.import('app/main')
            .then(null, console.error.bind(console));
    </script>
    

    模块名称及其内容现在出现在这个单个文件中。对于 Angular2 发行版的打包捆绑文件(angular2.dev.jshttp.dev.js,...)也是如此。要使用此文件,只需将其包含在 script 元素中即可。

    这样您就不会破坏模块导入。

    然后你可以用gulp的uglify插件来缩小这个单个文件...

    【讨论】:

    • 这似乎对我不起作用。如果我做System.import('app/main'),它说它找不到文件。如果我做System.import('app/main'.js),它会加载文件但没有任何功能启动。我在这里最想念的东西..
    • 你是否将js文件包含在script元素中?
    • 是的,我有这个 ..&lt;script src="app/main.js"&gt;&lt;/script&gt;,然后是来自 angular.io/docs/ts/latest/quickstart.html 的所有脚本 .. 在它之前的“库”部分下。所以&lt;script src="app/main.js"&gt;&lt;/script&gt;是我在System.import之前的最后一个
    • 现在似乎添加了缩小。 github.com/Microsoft/TypeScript/issues/8
    • @ThierryTemplier 我使用 outFile 做过同样的事情,但是当我使用 gulp 进行丑化时它不起作用,请你看看这个stackoverflow.com/questions/38501914/…
    【解决方案2】:

    ** 使用 tsconfig.json 中的选项从 TS 创建单个文件。

    {
      "compilerOptions": {
        "target": "es5",
        "module": "system",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": true,
        "noImplicitAny": false,
        "outDir":"client/build/",
        "outFile": "client/build/all.js",
        "declaration": true
      },
      "exclude": [
        "node_modules",
        "server"
      ],
      "include": [
            "client/*.ts",
            "client/**/*.ts",
            "client/**/**/*.ts"
      ]   
    }
    
    // Include all folders to put to a file.
    

    ** 构建输出文件并包含如下内容: 示例:

    <script>
    
    
      // Alternative way is compile in all.js and use the following system config with all the modules added to the bundles.
      // the bundle at build/all.js contains these modules
    System.config({
        bundles: {
          'client/build/all.js': ['boot','components/all/present','components/main/main','components/register/register','components/login/login','components/home/home','services/userdetails','services/httpprovider']
        }
      });
    
      // when we load 'app/app' the bundle extension interrupts the loading process
      // and ensures that boot of build/all.js is loaded first
      System.import('boot');
    
    
        </script>
    

    ** 像往常一样缩小 all.js 文件。

    【讨论】:

    【解决方案3】:

    由于您已经在使用 Gulp,您只需在您的 gulp 任务中添加 webpack 即可将所有 JavaScript 源文件(以及 Angular2 源文件)合并为一个。以下是您的 webpack.config.js 的示例:

    module.exports = {
      entry: './src/app/app',
      output: {
        path: __dirname + '/src', publicPath: 'src/', filename: 'bundle.js'
      },
      resolve: {
        extensions: ['', '.js', '.ts']
      },
      module: {
        loaders: [{
          test: /\.ts/, loaders: ['ts-loader'], exclude: /node_modules/
        }]
      }
    };
    

    您的 gulpfile.js 中的相关部分是

    var webpack = require('webpack-stream');
    var htmlReplace = require('gulp-html-replace');
    var gulp = require('gulp');
    
    gulp.task('webpack', function() {
      return gulp.src('src/app/*.ts')
        .pipe(webpack(require('./webpack.config.js')))
        .pipe(gulp.dest('src/'));
    });
    

    gulp.dest('src/') 替换为您希望生产代码驻留的相关位置。

    然后您需要处理您的 HTML 文件以获得适当的 JavaScript 源文件引用(也在 gulpfile.js 中)。

    gulp.task('html', ['templates'], function() {
      return gulp.src('src/index.html')
        .pipe(htmlReplace({
          'js': ['bundle.js']
        }))
        .pipe(gulp.dest('dist/'));
    });
    

    如果你想缩小你的 JavaScript 文件,你可以使用UglifyJS2。 (但请注意,混淆存在一些问题,因此mangle: false。有关更多信息,请参阅此SO link)。以下是相关的 gulpfile.js 内容:

    gulp.task('js', ['webpack'], function() {
      return gulp.src('src/bundle.js')
        .pipe(uglify({
                mangle: false
              }))
        .pipe(gulp.dest('dist/'));
    });
    

    通过这种方式,您的生产代码最终会出现在您可以部署它的 dist 文件夹中。现在,您可以选择是否将其检入生产分支。

    如果您想在一个非常小的 Angular2 应用程序上查看工作版本,请随时参考我的 words project on Github

    【讨论】:

    • 对我来说,将增加的文件设置为几乎 50% :( 没有其他解决方案吗?
    【解决方案4】:

    如果你使用 @angular/cli 你可以运行

    ng build --prod
    

    压缩和压缩代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多