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

2024-03-28

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

<script src="https://npmcdn.com/@angular/[email protected] /cdn-cgi/l/email-protection/bundles/core.umd.min.js"></script>
<script src="https://npmcdn.com/@angular/[email protected] /cdn-cgi/l/email-protection/bundles/common.umd.min.js"></script>
<script src="https://npmcdn.com/@angular/comp[email protected] /cdn-cgi/l/email-protection/bundles/compiler.umd.min.js"></script>
  • 当我让 WebPack 做它的事情时,包运行良好,但只有几 MB,因为它没有利用预构建的捆绑包或分离出 Angular 2“供应商”代码。
  • 当我使用Angular 2 WebPack 建议 https://angular.io/docs/ts/latest/guide/webpack.html, e.g.: plugins: [ new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.bundle.js") ],我的应用程序包很小,但每次构建时我都会手动构建一个单独的、独特的 1MB 包,其中包含大部分 Angular 2 框架。该文件根据我的应用程序的不同在每个版本中都会略有变化,并且不能在我的应用程序版本或各种应用程序之间移植,并且不具备“CDN”的优势。当然,我必须包含此文件才能运行我的应用程序。
  • 当我使用 IgnorePlugin 进行过滤时@angular|rxjs, e.g. plugins: [ new webpack.IgnorePlugin(/\@angular|rxjs/) ],它排除了供应商文件,但在我的应用程序包的顶部插入了硬编码的异常/抛出错误。
  • 当我使用WebPack 外部组件 https://webpack.github.io/docs/library-and-externals.html, e.g. externals: ['@angular/core', ..., I get function(module, exports) { module.exports = @angular/core; },我的应用程序包中的输出,这显然不起作用。 WebPack 文档并不是很出炉,但我想我可以指定一个libraryTarget或引用的解析函数,它将指示 WebPack 在模块加载中进行编译。
  • 当我完全放弃 WebPack 并使用 TypeScript 编译器捆绑器时(根据本指南 http://blog.angular-university.io/how-to-run-angular-2-in-production-today/,它使用 UMD 包),我得到System.register()引用我期望的 NPM 命名空间的调用,例如System.register("myapp/boot", ['@angular/core', ...,但我仍在研究 SystemJS 配置以调用 UMD。附带说明一下,相对于 WebPack 生成的文件,该文件的大小额外增加了 25%。
  • 如果我像前一项一样使用 SystemJS,我希望此编译在构建期间发生,或者作为并行过程,而不是作为文件保存的一部分。我猜SystemJS-Builder https://www.npmjs.com/package/systemjs-builder(参见相关问题here https://stackoverflow.com/questions/34614743/how-to-prepare-release-version-with-systemjs-and-gulp and here https://stackoverflow.com/questions/35867660/build-angular2-html-and-typescript-to-a-single-file/35868706#35868706)会是这样做的方法吗?也许这也会产生比 Typescript 集成的“捆绑程序”更小的文件大小。

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

我目前正在针对 RC3 进行构建。如上所述,我的流程目前是 WebPack,但如果这样更容易的话,我会转向另一个工具集。

做了更多研究,我认为我被 WebPack 的“Loader”术语误导了。我必须使用模块加载器,但 WebPack 似乎没有一个可以用于此目的的模块加载器。

要分配 UMD 包模块命名空间(并连接依赖项),它们无法加载到脚本标记中。相反,必须使用给定的值来评估它们this上下文作为模块引用。这意味着即使我希望它们全部同步加载,我仍然必须配置其他东西(例如 SystemJS)来通过网络加载它们,以便控制/包装它们的上下文。

This Angular 2 笨蛋 https://stackoverflow.com/questions/38013221/where-can-i-find-angular-2-rc3-bundles靠近我要找的东西。它使用 Angular 2 UMD 捆绑包,但不使用 RxJs 捆绑包,尽管如果我想要整个 RxJs 库,这看起来很容易更改。


我的问题中不止一种方法会起作用。有些不会,有些目前由于 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()
    ]
};

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

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

索引.htm

<script src="https://npmcdn.com/core-js/client/shim.min.js"></script>
<script src="https://npmcdn.com/[email protected] /cdn-cgi/l/email-protection/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>

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

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

 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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 UMD 捆绑包捆绑 Angular 2 应用程序(不构建供应商捆绑包) 的相关文章

随机推荐