使用UMD捆绑包捆绑Angular 2应用程序(不构建供应商捆绑包)

sha*_*non 6 bundle systemjs webpack angular

我目前正在将我的Angular 2应用程序与WebPack捆绑在一起.我们仍在进行快速循环,因此我们希望包含很少变化的Angular 2 UMD CDN准备捆绑包,而不是为我们的构建和应用程序加载过程添加延迟,例如:

<script src="https://npmcdn.com/@angular/core@2.0.0-rc.3/bundles/core.umd.min.js"></script>
<script src="https://npmcdn.com/@angular/common@2.0.0-rc.3/bundles/common.umd.min.js"></script>
<script src="https://npmcdn.com/@angular/compiler@2.0.0-rc.3/bundles/compiler.umd.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
  • 当我让WebPack做它的事情时,程序包运行正常但只有几MB,因为它不利用预先构建的bundle或分离出Angular 2"vendor"代码.
  • 当我使用Angular 2 WebPack建议书时,例如:plugins: [ new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.bundle.js") ],我的应用程序包很小,但我手动构建一个单独的,唯一的1MB包,其中包含大部分Angular 2框架,每个版本.此文件根据我的应用程序稍微改变每个版本,并且在我的应用程序或各种应用程序的版本之间不可移植,并且没有"CDN"的好处.当然,我必须包含此文件才能运行我的应用程序.
  • 当我使用IgnorePlugin进行过滤时@angular|rxjs,例如plugins: [ new webpack.IgnorePlugin(/\@angular|rxjs/) ],它会排除供应商文件,但会在应用程序包的顶部插入硬编码异常/抛出错误.
  • 当我使用WebPack外部时,例如externals: ['@angular/core', ...,我function(module, exports) { module.exports = @angular/core; },在我的应用程序包中输出,这显然不起作用.WebPack文档并不是非常明确,但我想我可以指定一个libraryTarget或引用的resolve函数,它将指示WebPack在模块加载中进行编译.
  • 当我完全抛弃WebPack并使用TypeScript编译器捆绑器(根据本指南,它使用UMD捆绑包)时,我会System.register()调用我所期望的NPM命名空间,例如System.register("myapp/boot", ['@angular/core', ...,但我仍在使用SystemJS配置调用UMD的.另外,相对于WebPack生成的文件,此文件的大小为25%.
  • 如果我在前面的项目中使用SystemJS,我希望在构建期间或作为并行进程进行此编译,而不是作为文件保存的一部分.我猜SystemJS-Builder(请参阅此处此处的相关问题)是否可以这样做?也许这也会产生较小的文件大小,即Typescript集成的"bundler".

如何构建不依赖于唯一重新打包的Angular 2包的应用程序包?

我目前正在建立对抗RC3.我的进程目前是WebPack,如上所述,但我会转移到另一个工具集,如果这使它更容易.

做了一些研究,我想我被WebPack的"Loader"术语误导了.我必须使用模块加载器,它看起来不像WebPack有一个适用于此的工具.

要分配UMD包模块名称空间(以及连接依赖项),不能在脚本标记中加载它们.相反,它们必须使用给定的this上下文进行评估,以充当模块引用.这意味着即使我希望它们全部同步加载,我仍然需要配置其他类似SystemJS的东西来加载它们,因此它们的上下文被控制/包装.

这个Angular 2 plunker接近我正在寻找的东西.它使用Angular 2 UMD捆绑包,但不使用RxJs捆绑包,尽管如果我想要整个RxJs库,这看起来很容易改变.

sha*_*non 2

我的问题中不止一种方法会起作用。有些不会,有些目前由于 Angular 2 的缺陷而不会。这是我目前使用的方法:


WebPack + require.js

angular2-webpack-config.js

var config = {
    entry: {
        app: inputFile
    },
    externals: [
        /^@angular\//,
        /^rxjs\//
    ],
    output: {
        libraryTarget: "amd",
        path: __dirname,
        filename: './' + outputName
    },
    plugins: [
        new require('webpack').optimize.UglifyJsPlugin()
    ]
};
Run Code Online (Sandbox Code Playgroud)

我只告诉它是什么externals以及什么伪标准机制将通过libraryTarget(AMD/RequireJS、CommonJs/node、UMD)在运行时加载它们。我的设置只是导致外部库引用被包装在define().

请注意,我没有对 WebPack 中的路径执行任何操作。在我的软件中,node_modules文件夹中的任何内容在我的软件和第三方模块内部都有类似的参考机制。我的代码和第三方库都希望在rxjs(例如,而不是../rxjs“node_modules/rxjs”)中找到 RxJS。在运行时,两者都需要映射,但由于我们不允许 WebPack 访问第三方模块(我们使用预构建的 UMD),因此 WebPack 不是进行映射的地方。它只会映射我的代码。相反,我们应该在运行时加载器中执行此操作:

索引.htm

<script src="https://npmcdn.com/core-js/client/shim.min.js"></script>
<script src="https://npmcdn.com/zone.js@0.6.12/dist/zone.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reflect-metadata/0.1.3/Reflect.min.js"></script>
<script>
    var require = (function(){
        var versions = {
            'router-deprecated': '@@2.0.0-rc.2',
            'forms': '@@0.1.1',
            'angular': '@@2.0.0-rc.4',
            'rxjs': '@@5.0.0-beta.10'
        }

        var paths = {
            'rxjs': "https://npmcdn.com/rxjs" + versions.rxjs + "/bundles/Rx.umd.min"
        };
        [
            'core',
            'http',
            'common',
            'compiler',
            'platform-browser',
            'router-deprecated',
            'platform-browser-dynamic'
        ].forEach(function (submodule) {
            var module = '@@angular/' + submodule
            paths[module] = 'https://npmcdn.com/' + module + (versions[submodule] || versions.angular) + '/bundles/' + submodule + '.umd.min';
        });

        var rxmap = {};
        [
            'Rx',
            'Observable',
            'Subject',
            'observable/PromiseObservable',
            'operator/toPromise'
        ].forEach(function (submodule) {
            rxmap['rxjs/' + submodule] = 'rxjs';
        })

        return {
            paths: paths,
            map: {
                '*': rxmap
            }
        };
    })();
</script>
<script data-main="../assets/compiled/a2.webpack.js" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

另外,如果您使用 WebPack 和 UMD,您可能会关心生成的文件大小和时间。这个子应用程序的 Angular 2 构建过程从大约 24 秒缩短到 1 秒。它的发布大小从超过 2MB 增加到大约 100k。

以下是缓存依赖项的线路负载大小以供参考。奇怪的是,目前UMD 版本中的它们比集成的、WebPack 修剪的捆绑包的线大小增加小了几 KB 。

 KB
27.5 shim
 6.8 zone
 8.0 require
 3.3 platform-browser-dynamic
36.8 http
 8.7 core
20.8 common
16.5 router
98.5 compiler
27.9 platform-browser
39.0 Rx
Run Code Online (Sandbox Code Playgroud)

显然,更新后我的公共站点加载时间大大减少(从大约 10-20 秒减少到 1 秒),但这些数字根据连接情况变化很大。