AngularJS和Webpack集成

9
我需要一些关于在大型AngularJS应用中使用webpack的帮助。我们使用基于功能的文件夹结构(每个功能/页面都有一个模块以及它们的控制器和指令)。我已经成功地配置了webpack,使其与Grunt配合使用,并生成了一个单一的捆绑包。由于这将是一个庞大的应用程序,我想创建块,我们希望异步加载模块(页面/功能)工件。
我正在查看一些webpack示例,以使用'code splitting'require([deps],fn )语法。然而,我无法懒加载这些块。首先,我不知道在哪里需要导入这些块,才能让AngularJS路由用户到下一个页面。我正在努力寻找明确的责任分离。
有人可以向我指出一个使用webpack在每个路由之后异步加载控制器/指令/过滤器的示例AngularJS应用程序吗?

我正在跟踪的一些链接: 在Angular 1.x中,我应该使用Browserify还是Webpack进行依赖项的懒加载 https://github.com/petehunt/webpack-howto#9-async-loading http://dontkry.com/posts/code/single-page-modules-with-webpack.html

2个回答

13

Sagar Ganatra撰写了一篇有关代码分割的有用博客文章

令人惊讶的是,Angular的模块系统并不真正支持代码分割。但是,在配置阶段保存对Angular特殊提供程序的引用可以实现代码分割。

[...] 当Angular初始化或引导应用程序时,函数 - 控制器、服务等在模块实例上可用。在此处,我们正在延迟加载组件,函数在稍后的时间点不可用;因此,我们必须使用各种提供程序函数并注册这些组件。提供者仅在config方法中可用,因此当应用程序初始化时,我们必须在config函数中存储对这些提供者的引用。

window.app.config([
    '$routeProvider',
    '$controllerProvider',
    '$compileProvider',
    '$filterProvider',
    '$provide',
    function ($routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {

        $routeProvider.when('/login', {
            templateUrl: 'components/login/partials/login.html',
            resolve: {
                load: ['$q', '$rootScope', function ($q, $rootScope) {

                    var deferred = $q.defer();

                    // lazy load controllers, etc.
                    require ([
                        'components/login/controllers/loginController',
                        'components/login/services/loginService'
                    ], function () {

                        $rootScope.$apply(function () {
                            deferred.resolve();
                        });

                    });

                    return deferred.promise;
                }]
            }
        });


        //store a reference to various provider functions
        window.app.components = {
            controller: $controllerProvider.register,
            service: $provide.service
        };

    }
]);

现在,例如,在您的loginController内编写以下内容:

app.components.controller('loginController');

为了懒加载您的新控制器,可以使用以下方法:

如果您还想懒加载模板,我建议使用ui-router。在那里,您可以指定一个templateProvider,它是用于异步加载模板的函数


谢谢,我也发现多次调用$apply不正确。https://dev59.com/e2cs5IYBdhLWcg3wlFA2 或许每个路由只调用一次应该没问题,我猜测。 - CoderTR
是的,你可能是对的。基本上,你必须决定:在调用$apply之前,是否等待每个组件加载完成,还是尽快传播更新。 - Johannes Ewald

2
这是来自https://github.com/webpack/webpack/issues/150的引用。
webpack是一个模块打包工具,而不是JavaScript加载器。它将本地磁盘上的文件打包,不会从网络中加载文件(除了自己生成的代码块)。
如果需要加载JavaScript,可以使用一个JavaScript加载器,例如script.js。
var $script = require("scriptjs");
$script("//ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js", function() {
  // ...
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接