使用多个webpack配置分别加载Angular 2及其依赖库

时间:2017-01-27 14:20:37

标签: angular webpack webpack-2

我目前有一个使用webpack 2构建的角度2应用程序。我忽略了任何角度或任何第三方库,因为我的意图是将它们分别加载/维护在不同的webpack捆绑进程中(不同的webpack配置)比我的应用程序配置)。我想这样做,以便可以更新这些库,而无需在我的应用程序或使用这些库的任何其他应用程序上重新运行webpack。我目前使用webpack DLL工作,但我仍然有一个问题,如果我更新该webpack DLL,应用程序仍然需要重新捆绑以与新模块ID“重新同步”自己。许多应用程序指向这个“核心”捆绑包,你可以想象这将是乏味的。我不希望这些经常改变,但我希望有它的自由。

当我运行应用程序时,我得到错误,因为我的应用程序代码无法在角度库中找到诸如“输出”,“输入”等等的东西。有谁知道如何包括angular,rxjs,zone,core-js等等。在脚本标签,单独的webpack包或其他一些方法,并让应用程序webpack包能够知道这些库并使用它们?像lodash这样的东西工作正常,因为它们被加载为全局变量,但是使用角度2我无法以同样的方式完成工作。

我尝试创建一个webpack“vendor”包,其中只包含angular 2库及其依赖项,例如zone和rxjs。我在输出中设置了library属性,并尝试在应用程序webpack配置中使用libraryTargetexternals属性。仅使用应该存在的特定代码创建捆绑包,但应用程序找不到此“供应商”捆绑包中的任何模块。似乎应用程序代码中的import语句无法在此“vendor”包中找到模块。

如果有人想查看我的webpack配置文件中的部分,请随意询问。

1 个答案:

答案 0 :(得分:0)

我设法弄明白了。对于任何想要做同样事情的人来说,这是需要发生的事情。

您需要为角度库及其依赖项中的每个umd模块添加脚本标记,或者执行我所做的操作并创建gulp任务以按正确顺序连接这些库并创建一个包含代码的供应商文件在脚本标记中引用它。

加载umd模块后,您可以告诉webpack配置忽略特定模块,并使用externals配置属性将它们委托给全局变量:

externals: [
    {
        'hammerjs': 'Hammer',
        'lodash': '_',

        'core-js/es6': 'core',
        'core-js/es7/reflect': 'core',

        'zone.js/dist/zone': 'Zone',

        '@angular/core': 'ng.core',            
        '@angular/compiler': 'ng.compiler',
        '@angular/common': 'ng.common',
        '@angular/platform-browser': 'ng.platformBrowser',
        '@angular/platform-browser-dynamic': 'ng.platformBrowserDynamic',            
        '@angular/http': 'ng.http',
        '@angular/router': 'ng.router',
        '@angular/forms': 'ng.forms',

        '@angular/flex-layout': 'ng.flexLayout',
        '@angular/material': 'ng.material'            
    },
    function(context, request, callback) {
        if (/^rxjs/.test(request)) {
            return callback(null, 'Rx');
        }

        callback();
    }
],

这样做是告诉webpack,只要遇到其中一个导入,就使用全局变量来引用它。现在存在全局变量,因为我们使用umd文件并单独加载它们。其中的函数用于rxjs,并且每当遇到以“rxjs”开头的import语句时都使用Rx全局变量。

如果有人不知道这个,那么下面列出了umd文件。这些文件可以在各种模块加载器中导入,也可以通过全局变量访问:

// Third party JavaScript libs
'./node_modules/hammerjs/hammer.min.js', // Required by @angular/material
'./node_modules/lodash/lodash.min.js',

// Polyfills (required by @angular/*)
'./node_modules/core-js/client/shim.min.js',
'./node_modules/zone.js/dist/zone.min.js',

// RxJS
'./node_modules/rxjs/bundles/Rx.min.js', // Required by @angular/*

// Angular Framework (order matters)
'./node_modules/@angular/core/bundles/core.umd.min.js',
'./node_modules/@angular/common/bundles/common.umd.min.js',
'./node_modules/@angular/compiler/bundles/compiler.umd.min.js', // Don't need this if using AoT...
'./node_modules/@angular/platform-browser/bundles/platform-browser.umd.min.js', // Used for AoT
'./node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js', // Used for JiT
'./node_modules/@angular/http/bundles/http.umd.min.js',    
'./node_modules/@angular/forms/bundles/forms.umd.min.js',
'./node_modules/@angular/router/bundles/router.umd.min.js',

// Third party Angular libraries
'./node_modules/@angular/flex-layout/bundles/flex-layout.umd.js',
'./node_modules/@angular/material/bundles/material.umd.js'

此过程允许您更改“供应商”javascript包,而无需在依赖于它的每个应用程序上运行webpack。当然,如果需要新功能,你需要在应用程序上运行webpack,但只需更新角度或任何其他外部库而不会破坏更改,那么这将非常有效。唯一的缺点是供应商代码现在无法实现树摇动......但它仍然适用于使用webpack的应用程序。