Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 组合requirejs捆绑包和requirejs优化器时的模块注入问题_Javascript_Requirejs_Grunt Contrib Requirejs - Fatal编程技术网

Javascript 组合requirejs捆绑包和requirejs优化器时的模块注入问题

Javascript 组合requirejs捆绑包和requirejs优化器时的模块注入问题,javascript,requirejs,grunt-contrib-requirejs,Javascript,Requirejs,Grunt Contrib Requirejs,我目前正试图提高一个相当大的角度JS应用程序的性能,从一大块javascript文件转移到3-4块更小的文件,甚至可能是延迟加载的 我正在使用以下npm软件包和版本: grunt-contrib-requirejs: 1.0.0 grunt: 0.4.5 requirejs: 2.3.0 最初,有一个grunt任务,它使用requirejs优化器将所有必需的javascript文件都包含到一个文件中,因为有一个主配置文件main.js,其中定义了所有特定包的所有路径和垫片(如果需要,我可以发布

我目前正试图提高一个相当大的角度JS应用程序的性能,从一大块javascript文件转移到3-4块更小的文件,甚至可能是延迟加载的

我正在使用以下npm软件包和版本:

grunt-contrib-requirejs: 1.0.0
grunt: 0.4.5
requirejs: 2.3.0
最初,有一个grunt任务,它使用requirejs优化器将所有必需的javascript文件都包含到一个文件中,因为有一个主配置文件
main.js
,其中定义了所有特定包的所有路径和垫片(如果需要,我可以发布示例配置等)

现在的想法是从拥有一个大文件开始,将应用程序模块化为3-4个较小的javascript文件,以缩短加载时间(因为并行加载4个小文件比加载1个大文件快)

为此,我们使用grunt requirejs中的modules选项和bundles选项来定义所有模块及其内容

项目结构如下:

/src/
  ./Gruntfile.js
  ./scripts/
    ./app.js
    ./vendor.js
    ./app_mini.js
    ./features/
      ./test.service.js
/dist/
grunt任务的定义如下:

requirejs: {
    bundle: {
      options: {
        baseUrl: '/src',
        mainConfigFile: '/src/scripts/app.js',
        bundlesConfigOutFile: 'scripts/app.js',
        findNestedDependencies: true,
        dir: '/dist',
        modules: [
          {
            name: 'scripts/vendor',
            exclude: [],
            override: {
              {
                paths: {
                  'angular': 'bower/angular/angular',
                  'jquery': 'bower/jquery/dist/jquery'
                },
                bundles: {
                } 
              },
            }
          },

          {
            name: 'scripts/app',
            exclude: ['scripts/vendor'],
            override: {
              {
                paths: {
                  'vendor': 'scripts/vendor',
                  'app_mini': 'scripts/app_mini',
                  'testservice': 'scripts/features/test.service'
                },
                bundles: {
                  'vendor': ['angular', 'jquery']
                }
              } 
           }
        ]
      }
    }
  } 
/dist/
  ./scripts/
    ./app.js
    ./vendor.js
define('app',
  [
    'angular', 
    'app_mini',
    'testservice'
   ],
   function(
     angular,
     app_mini,
     testservice) {}
);

require([
  'angular',
  'app_mini',
  'testservice'
], function (
  angular,
  app_mini,
  testservice
) {
  // entry to app


}, function(err) {
  console.log('error loading module: ' + err.requireModules);
};
require.config({
  bundles: {
    'scripts/vendor': [
      'angular',
      'jquery'
    ],
    'scripts/app': [
      'testservice',
      'app_mini',
      'app'
    ]
  }
});
执行requirejs:bundle后的dist文件夹如下所示:

requirejs: {
    bundle: {
      options: {
        baseUrl: '/src',
        mainConfigFile: '/src/scripts/app.js',
        bundlesConfigOutFile: 'scripts/app.js',
        findNestedDependencies: true,
        dir: '/dist',
        modules: [
          {
            name: 'scripts/vendor',
            exclude: [],
            override: {
              {
                paths: {
                  'angular': 'bower/angular/angular',
                  'jquery': 'bower/jquery/dist/jquery'
                },
                bundles: {
                } 
              },
            }
          },

          {
            name: 'scripts/app',
            exclude: ['scripts/vendor'],
            override: {
              {
                paths: {
                  'vendor': 'scripts/vendor',
                  'app_mini': 'scripts/app_mini',
                  'testservice': 'scripts/features/test.service'
                },
                bundles: {
                  'vendor': ['angular', 'jquery']
                }
              } 
           }
        ]
      }
    }
  } 
/dist/
  ./scripts/
    ./app.js
    ./vendor.js
define('app',
  [
    'angular', 
    'app_mini',
    'testservice'
   ],
   function(
     angular,
     app_mini,
     testservice) {}
);

require([
  'angular',
  'app_mini',
  'testservice'
], function (
  angular,
  app_mini,
  testservice
) {
  // entry to app


}, function(err) {
  console.log('error loading module: ' + err.requireModules);
};
require.config({
  bundles: {
    'scripts/vendor': [
      'angular',
      'jquery'
    ],
    'scripts/app': [
      'testservice',
      'app_mini',
      'app'
    ]
  }
});
因此,
app\u mini
testservice
包含在
app.js
中,
angular
jquery
包含在
vendor.js

src文件夹中的My
app.js
大致如下所示:

requirejs: {
    bundle: {
      options: {
        baseUrl: '/src',
        mainConfigFile: '/src/scripts/app.js',
        bundlesConfigOutFile: 'scripts/app.js',
        findNestedDependencies: true,
        dir: '/dist',
        modules: [
          {
            name: 'scripts/vendor',
            exclude: [],
            override: {
              {
                paths: {
                  'angular': 'bower/angular/angular',
                  'jquery': 'bower/jquery/dist/jquery'
                },
                bundles: {
                } 
              },
            }
          },

          {
            name: 'scripts/app',
            exclude: ['scripts/vendor'],
            override: {
              {
                paths: {
                  'vendor': 'scripts/vendor',
                  'app_mini': 'scripts/app_mini',
                  'testservice': 'scripts/features/test.service'
                },
                bundles: {
                  'vendor': ['angular', 'jquery']
                }
              } 
           }
        ]
      }
    }
  } 
/dist/
  ./scripts/
    ./app.js
    ./vendor.js
define('app',
  [
    'angular', 
    'app_mini',
    'testservice'
   ],
   function(
     angular,
     app_mini,
     testservice) {}
);

require([
  'angular',
  'app_mini',
  'testservice'
], function (
  angular,
  app_mini,
  testservice
) {
  // entry to app


}, function(err) {
  console.log('error loading module: ' + err.requireModules);
};
require.config({
  bundles: {
    'scripts/vendor': [
      'angular',
      'jquery'
    ],
    'scripts/app': [
      'testservice',
      'app_mini',
      'app'
    ]
  }
});
很抱歉文件内容太长,但是如果没有它,就无法描述问题:) 所以,问题是,我希望有一个中心位置来为优化器和应用程序本身放置整个Requirejs配置。但是,显然,优化器的路径是相对于grunfile路径的,而正在运行的应用程序的路径是相对于相应的文件的

由于bundle配置是由requirejs自动生成的(因为bundleConfigOutFile),因此我不能对其中使用的名称做太多的处理,因为它们是从modules选项中提取出来的

生成并包含在app.js中的bundles配置如下所示:

requirejs: {
    bundle: {
      options: {
        baseUrl: '/src',
        mainConfigFile: '/src/scripts/app.js',
        bundlesConfigOutFile: 'scripts/app.js',
        findNestedDependencies: true,
        dir: '/dist',
        modules: [
          {
            name: 'scripts/vendor',
            exclude: [],
            override: {
              {
                paths: {
                  'angular': 'bower/angular/angular',
                  'jquery': 'bower/jquery/dist/jquery'
                },
                bundles: {
                } 
              },
            }
          },

          {
            name: 'scripts/app',
            exclude: ['scripts/vendor'],
            override: {
              {
                paths: {
                  'vendor': 'scripts/vendor',
                  'app_mini': 'scripts/app_mini',
                  'testservice': 'scripts/features/test.service'
                },
                bundles: {
                  'vendor': ['angular', 'jquery']
                }
              } 
           }
        ]
      }
    }
  } 
/dist/
  ./scripts/
    ./app.js
    ./vendor.js
define('app',
  [
    'angular', 
    'app_mini',
    'testservice'
   ],
   function(
     angular,
     app_mini,
     testservice) {}
);

require([
  'angular',
  'app_mini',
  'testservice'
], function (
  angular,
  app_mini,
  testservice
) {
  // entry to app


}, function(err) {
  console.log('error loading module: ' + err.requireModules);
};
require.config({
  bundles: {
    'scripts/vendor': [
      'angular',
      'jquery'
    ],
    'scripts/app': [
      'testservice',
      'app_mini',
      'app'
    ]
  }
});
首先,我遇到了一个问题,RequireJs希望通过路径
scripts/scripts/vendor.js

为了解决这个问题,我在
app的
require.config
中加入了
baseUrl='/'

但是现在我遇到了一个问题,
testservice
无法注入
app\u mini
angular
,因此它在那里抛出了一个错误,因为这两个模块都未定义

dist文件夹中的优化app.js如下所示,也许您可以发现问题:

(function(){


define(
    'testservice',[
        'angular',
        'app_mini'
    ], function(
        angular,
        app_mini
    ) {
        'use strict';
 
        app_mini.factory('testservice', TestService);
 
        function TestService() {
            var service = {
                test: test
            };
            return service;
        };
 
        var test = function() {
            console.log("testservice::test()");
        };
});
 
define('app_mini',
    [
        'angular',
        'testservice'
    ],
 
    function (
        angular,
        testservice
    ) {
        'use strict';
 
 
        var module = angular.module(‘some.project’, []);
 
        module.run(AppRun);
 
        AppRun.$inject = [
            '$rootScope',
            'testservice'
        ];
        function AppRun($rootScope, testservice) {
            console.log(“yay, it works”);
 
            testservice.test();
        }
 
        return module;
    }
);
 
require.config({
    bundles: {
        'scripts/vendor.bundle': [
            'angular',
            'jquery'
        ],
        'scripts/app.bundle': [
            'testservice',
            'app_mini',
            'app'
        ]
    }
});
 
require.config({
    baseUrl: '/'
});
 
 define(‘app’,
    [
        'angular',
        'app_mini',
        'testservice'
    ], function(
        angular,
        app_mini,
        testservice
){});
 
require([
        'angular',
        'app_mini',
        'testservice'
    ], function (
        angular,
        app_mini,
        testservice
    ) {
 
    angular.element().ready(function () {
        var $html = angular.element(document.getElementsByTagName('html')[0]);
        angular.bootstrap($html, [app_mini['name']]);
    });
 
}, function (err) {
    'use strict';
 
    console.log('Error loading requirejs-module: ' + err.requireModules);
});
 
define("scripts/app.bundle", function(){});
 
})();

好吧,我想可能没有人会通读所有这些,我只是注意到我本可以更好地指出真正的问题。(当app_mini和angular被注入testservice时,它们还没有定义)

所以问题是我完全没有传递shim配置,它允许require js将angular和jquery封装到AMD模块中。因为它丢失了,angular永远也找不到了,这破坏了app_mini和testservice,因此也破坏了整个应用程序

因此,通过添加垫片,我相应地编辑了供应商模块配置:

modules: [
      {
        name: 'scripts/vendor',
        exclude: [],
        override: {
          {
            paths: {
              'angular': 'bower/angular/angular',
              'jquery': 'bower/jquery/dist/jquery'
            },
            shim: {
              angular: {
                exports: 'angular',
                deps: ['jquery']
              }
            },
            bundles: {
            } 
          },
        }
      },