在角度通用应用程序(nodejs)上集成newrelic

时间:2017-12-28 08:23:01

标签: node.js angular webpack newrelic angular-universal

我在nodejs app上集成了newrelic,用angular universal制作。我正在使用webpack进行捆绑

main.server.aot.ts

中的第一行
const newrelic = require('newrelic');

并在根目录中添加了 newrelic.js

运行构建弹出以下错误: -

ERROR in ./node_modules/@newrelic/native-metrics/lib/pre-build.js
Module not found: Error: Can't resolve '../package' in 'D:\repos\ib-mobile\node_modules\@newrelic\native-metrics\lib'
 @ ./node_modules/@newrelic/native-metrics/lib/pre-build.js 40:12-33
 @ ./node_modules/@newrelic/native-metrics/index.js
 @ ./node_modules/newrelic/lib/sampler.js
 @ ./node_modules/newrelic/lib/agent.js
 @ ./node_modules/newrelic/index.js
 @ ./src/main.server.aot.ts

ERROR in ./node_modules/node-gyp/lib/node-gyp.js
Module not found: Error: Can't resolve '../package' in 'D:\repos\ib-mobile\node_modules\node-gyp\lib'
 @ ./node_modules/node-gyp/lib/node-gyp.js 67:16-37
 @ ./node_modules/@newrelic/native-metrics/lib/pre-build.js
 @ ./node_modules/@newrelic/native-metrics/index.js
 @ ./node_modules/newrelic/lib/sampler.js
 @ ./node_modules/newrelic/lib/agent.js
 @ ./node_modules/newrelic/index.js
 @ ./src/main.server.aot.ts

ERROR in ./node_modules/newrelic/index.js
Module not found: Error: Can't resolve './package' in 'D:\repos\ib-mobile\node_modules\newrelic'
 @ ./node_modules/newrelic/index.js 13:19-39
 @ ./src/main.server.aot.ts

如果我在webpack config

中添加newrelic作为外部
module.exports = {
  entry: root('./src/main.server.aot.ts'),
  output: {
    path: root('dist_server'),
    filename: 'server.js'
  },
  target: 'node',
  externals: {
    newrelic: true
  }
};

然后我得到另一个错误

  

/home/ubuntu/ib-mobile/dist_server/server.js:79752

module.exports = newrelic;
                 ^

ReferenceError: newrelic is not defined
    at Object.<anonymous> (/home/ubuntu/ib-mobile/dist_server/server.js:79752:18)
    at __webpack_require__ (/home/ubuntu/ib-mobile/dist_server/server.js:26:30)
    at Object.module.exports (/home/ubuntu/ib-mobile/dist_server/server.js:79667:16)
    at __webpack_require__ (/home/ubuntu/ib-mobile/dist_server/server.js:26:30)
    at /home/ubuntu/ib-mobile/dist_server/server.js:91:18
    at Object.<anonymous> (/home/ubuntu/ib-mobile/dist_server/server.js:94:10)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)

Angular Version (ng -v)

Angular CLI: 1.6.3
Node: 6.11.0
OS: win32 x64
Angular: 4.4.6
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
... tsc-wrapped

@angular/cli: 1.6.3
@angular-devkit/build-optimizer: 0.0.36
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.42
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.3
@schematics/angular: 0.1.11
@schematics/schematics: 0.0.11
typescript: 2.3.4
webpack: 3.10.0

2 个答案:

答案 0 :(得分:1)

找到一种解决此问题的方法!

TLDR

基本上,所有这些操作都是将webpack配置为在server.js文件和BAM的顶部添加导入文件。

问题

因此,您所做的一切都是正确的,但是,通过告诉webpack您希望newrelic模块位于外部,则表示运行该应用程序时newrelic实例将在内存中可用。 我们显然没有这样做,这就是为什么我们收到您上面提到的错误的原因。 我认为此功能的用例是针对浏览器的,您在其中使用<script src="{http://example.com/script.js}" />包含脚本,因此您不希望Webpack自己尝试解决node_modules的依赖关系。

解决方案

我们将不使用“ externals”属性,而只是将我们的标准nodejs导入var newrelic = require('newrelic');添加到运行expressjs节点应用程序的文件中(就像人们期望的新遗物一样)。

为此,我们需要以下条件:

  • BannerWebpackPlugin
  • 我们的nodejs express应用程序正在运行哪个输出块/文件的知识。

要安装 BannerWebpackPlugin ,只需执行以下操作:npm install --save-dev banner-webpack-plugin

对于块/文件,您可以查看错误日志(从此错误代码段中可以看到其server.js块/文件):

ReferenceError: newrelic is not defined at Object.<anonymous> (/home/ubuntu/ib-mobile/dist_server/server.js:79752:18)

或者您可以查看webpack文件的“ entry”属性并找到由webpack生成的块(在我的情况下,这也是输出到server.js的“服务器”。)

现在,我们有了这些信息,我们只需要通过webpack config插件部分将横幅配置添加到块中即可。

这就是我的样子:

plugins: [
...,
    new BannerPlugin({
        chunks: {
            server:{
                beforeContent: 'var newrelic = require("newrelic");'
            }
       }
    }),
...]

此时,您应该能够运行Webpack构建并运行新的遗物!

如果您以前一直在应用程序代码中包含需求,则现在可以将其删除,并且webpack导入应该足以使newrelic代理运行。

答案 1 :(得分:1)

有更优雅的解决上述问题。您可以像功能一样设置webpack外部字段:

(context, request, callback) => {
    var regex = new RegExp(`^newrelic$`);

    if (regex.test(request)) {
        return callback(null, `commonjs ${request}`);
    }
    callback();
 }

这将告诉webpack将const newrelic = require('newrelic');保留在捆绑文件中。所有你需要的是与你的附近运行的服务器发生NewRelic的node_modules。 第二种解决方案是将output的{​​{3}}属性设置为commonjs,然后以下externals语法将起作用:

externals : {
    newrelic : {
        commonjs: 'newrelic'
    }
}