使用UMD捆绑包捆绑Angular 2应用程序(不构建供应商捆绑包) [英] Bundle Angular 2 app using UMD bundles (not building vendor bundle)

查看:93
本文介绍了使用UMD捆绑包捆绑Angular 2应用程序(不构建供应商捆绑包)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前将Angular 2应用与WebPack捆绑在一起.我们仍在快速旋转,因此,我们希望包括变化不大的Angular 2 UMD CDN准备好的捆绑软件,而不是增加构建和应用程序加载过程的延迟,例如:

I'm currently bundling my Angular 2 app with WebPack. We are still spinning rapid cycles, so rather than adding delays to our build and application load process, we want to include the rarely-changing Angular 2 UMD CDN prepared bundles, e.g.:

<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>

  • 当我只让WebPack做事时,该程序包运行良好,但只有几个MB,因为它没有利用预构建的包或单独的Angular 2供应商"代码.
  • 当我使用 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"更小的文件大小.
    • When I just let WebPack do its thing, the package runs fine but is a few MB, because it doesn't leverage pre-built bundles or separate out Angular 2 "vendor" code.
    • When I use the Angular 2 WebPack Recommendations, e.g.: plugins: [ new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.bundle.js") ], my app bundle is small, but I manually build a separate, unique 1MB bundle containing most of the Angular 2 framework in it, every build. This file changes slightly each build depending on my application, and is not portable between versions of my applications or various applications, and doesn't have the benefit of "CDN". Of course I have to include this file for my app to run.
    • When I use the IgnorePlugin to filter @angular|rxjs, e.g. plugins: [ new webpack.IgnorePlugin(/\@angular|rxjs/) ], it excludes the vendor files, but inserts hard-coded exceptions / throws errors at the top of my application bundle.
    • When I use WebPack externals, e.g. externals: ['@angular/core', ..., I get function(module, exports) { module.exports = @angular/core; }, output in my app bundle, which obviously isn't functional. The WebPack documentation isn't terribly forthcoming, but I think I may be able to either specify a libraryTarget or quoted resolve function, which would instruct WebPack to compile in module loading.
    • When I ditch WebPack altogether and use instead the TypeScript compiler bundler (as per this guide, which uses the UMD bundles), I get System.register() calls referring to the NPM namespaces I expected, e.g. System.register("myapp/boot", ['@angular/core', ..., but I'm still working on SystemJS configuration to call the UMDs. As a side note, this file is an extra 25% in size relative to what WebPack is generating.
    • If I use SystemJS as in the prior item, I want this compilation to occur during build, or as a parallel process, rather than as part of file save. I guess SystemJS-Builder (see related questions here and here) would be the way to do this? Perhaps this also would produce smaller file sizes that the Typescript-integrated "bundler".
    • 如何构建不依赖于唯一重新包装的Angular 2捆绑软件的应用捆绑软件?

      How can I build an application bundle that doesn't depend on a uniquely-repackaged Angular 2 bundle?

      我目前正在针对RC3进行构建.如上所述,我的流程目前是WebPack,但是如果这样做更方便,我将转到另一个工具集.

      I'm currently building against RC3. My process is currently WebPack, as mentioned above, but I would move to another toolset if that makes it easier.

      做更多的研究,我认为我已经被WebPack的"Loader"术语误导了.我必须使用模块加载器,但看起来WebPack并没有一个可以使用的模块加载器.

      Doing some more research, I think I've been misled by WebPack's "Loader" terminology. I have to use a module loader, and it doesn't look like WebPack has one that will work for this.

      要分配UMD捆绑软件模块名称空间(和关联依赖关系),不能将它们加载到脚本标签中.相反,必须使用给定的this上下文对其进行评估,以用作模块引用.这意味着即使我希望它们全部都同步加载,我仍然必须配置诸如SystemJS之类的东西才能通过网络加载它们,以便控制/包装它们的上下文.

      To assign UMD bundles module namespaces (and wire up dependents) they can't be loaded in script tags. Instead they have to be evaluated with a given this context to act as the module reference. That means that even if I want them all loaded synchronously, I still have to configure something else like SystemJS to load them over the wire, so their context is controlled/wrapped.

      这个 Angular 2塞子靠近我我在寻找.它使用Angular 2 UMD捆绑软件,但不使用RxJs捆绑软件,尽管如果我想要整个RxJs库,看起来很容易更改.

      This Angular 2 plunker is near what I'm looking for. It uses the Angular 2 UMD bundles, but doesn't use an RxJs bundle, although that looks easy enough to change if I want the entire RxJs library.

      推荐答案

      在我的问题中,不止一种方法可行.有些不会,有些不是由于Angular 2的缺陷而导致的.这是我目前正在使用的方法:

      More than one of the approaches in my question will work. Some will not, some do not currently due to defects in Angular 2. Here's the approach I'm currently using:

      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/node,UMD)加载它们.我的设置只是导致将外部库引用包装在define()中.

      I only tell it what are externals and what pseudo-standard mechanism will load them at runtime via libraryTarget (AMD/RequireJS, CommonJs/node, UMD). My setting simply causes external library references to be wrapped in define().

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

      Note that I don't do anything with paths in WebPack. In my software, anything in the node_modules folder has a similar reference mechanism both in my software and in third party modules, internally. Both my code and third-party libraries expect to find RxJS at rxjs (e.g. rather than ../rxjs or 'node_modules/rxjs`). At runtime, both need to be mapped, but since we aren't allowing WebPack to reach into third party modules (we're using pre-built UMD's), WebPack isn't the place to do that mapping. It would only map my code. Instead, we should do that in our runtime loader:

      index.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>
      

      此外,由于如果您使用的是WebPack和UMD,那么您可能会担心生成的文件大小和时间.此子应用程序的Angular 2构建过程从大约24秒缩短到1秒.它发布的更改大小从2MB以上增加到10万左右.

      Also, since if you are using WebPack and UMDs you probably care about resulting file sizes and times. This sub-app's Angular 2 build process went from about 24 seconds to 1 second. Its publish changed-size went from over 2MB to about 100k.

      这里是缓存的依赖项的线路负载大小,以供参考.奇怪的是,与集成的WebPack修剪后的捆绑软件相比,它们在UMD版本中的体积要小几分.

      Here are wire load sizes of the cached dependencies for reference. Strangely they are currently a few KB smaller in the UMD version than the wire-size increase of an integrated, WebPack pruned, bundle.

       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秒),但是这些数字根据连接情况而变化很大.

      Obviously my public site load times after updates are drastically reduced (down to 1 second from about 10-20 seconds), but those numbers are pretty variable based on connection.

      这篇关于使用UMD捆绑包捆绑Angular 2应用程序(不构建供应商捆绑包)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆