Angular 2的AoT Rollup失败,提示'require is not defined'。

3
我有一个Angular2应用程序,我正在编译它以使用AoT运行。 我已经解决了实际编译过程中遇到的问题,并且我也能够从头到尾运行Rollup而没有错误(虽然有很多警告,但我认为这是可以预期的)。
然而,在运行应用程序时,浏览器总是在我的app.bundle.js上声明require未定义
我做错了什么?
这里是我的功能性非AoT示例代码/配置: https://plnkr.co/edit/oCAaeXUKWGyd34YKgho9?p=info 这是我的功能性AoT示例配置,会抛出require错误: https://plnkr.co/edit/Y1C5HaQS3ddCBrbRaaoM?p=info

有人发现这里有任何错误吗,特别是当比较非AoT system.js配置和AoT rollup配置时?为什么我会遇到这个错误?

我知道浏览器无法使用require,但rollup不应该解决这个问题吗?

最好的问候


@joh04667 我个人正在使用 Angular2 2.4.4。 - Zed_Blade
另外一个问题……你尝试过安装 source-map-explorer 并通过 Angular 文档检查你的 build.js 文件吗?在我的版本(2.4.5)中,我注意到编译器仍然是捆绑包的一部分,而它不应该是。 - joh04667
另外,你的 index.html 文件是否可以访问 shim.min.js 和 zone.min.js?我看到了 script 标签,但它们默认情况下没有被复制到 aot/node_modules(或者在你的情况下是 app/node_modules)中。 - joh04667
我的 index.html 引用了 core-js shim 和 zone,没有问题,我相信(来自根目录 node_modules)。 - Zed_Blade
感谢您回复我! - joh04667
显示剩余3条评论
2个回答

1

最终,我成功解决了问题。

代码中有一个不受控制的const _ = require("lodash"),一旦我删除它,问题就迎刃而解。

值得一提的是:

  1. 由于node.js内存限制(1.7GB RAM),ngc命令使用node --max-old-space-size=8192 ./node_modules/.bin/ngc -p tsconfig-aot.json运行
  2. 同样地,为了同样的原因,rollup使用node --max-old-space-size=8192 ./node_modules/.bin/rollup -c rollup-config.js运行

根据您的项目大小和计算机内存大小,您可以尝试使用--max-old-memory=4096来解决问题。

至于我的rollup-config.js文件,虽然我不确定这里是否真的需要所有内容,但以下是对我有效的内容:

import builtins from 'rollup-plugin-node-builtins';
import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify';

export default {
    entry: 'app/app.aot.js',
    dest: 'www/bundle.js', // output a single application bundle
    sourceMap: false,
    format: 'iife',
    plugins: [
        nodeResolve({
            jsnext: true,
            module: true,
            browser: true
        }),
        commonjs({
            // non-CommonJS modules will be ignored, but you can also
            // specifically include/exclude files
            include: [
                'node_modules/**',
                'node_modules/primeng/**',
                'node_modules/moment/**',
                'node_modules/rxjs/**',
                'node_modules/lodash/**'
            ], // Default: undefined
            exclude: ['node_modules/ws/**'], // Default: undefined

            // search for files other than .js files (must already
            // be transpiled by a previous plugin!)
            extensions: ['.js'], // Default: [ '.js' ]

            // if true then uses of `global` won't be dealt with by this plugin
            ignoreGlobal: false, // Default: false

            namedExports: {
                // left-hand side can be an absolute path, a path
                // relative to the current directory, or the name
                // of a module in node_modules
                'node_modules/primeng/primeng.js': [
                    'PanelModule',
                    'InputSwitchModule',
                    'InputMaskModule',
                    'ProgressBarModule',
                    'DropdownModule',
                    'CalendarModule',
                    'InputTextModule',
                    'DataTableModule',
                    'DataListModule',
                    'ButtonModule',
                    'DialogModule',
                    'AccordionModule',
                    'RadioButtonModule',
                    'ToggleButtonModule',
                    'CheckboxModule',
                    'SplitButtonModule',
                    'ToolbarModule',
                    'SelectButtonModule',
                    'OverlayPanelModule',
                    'TieredMenuModule',
                    'GrowlModule',
                    'ChartModule',
                    'Checkbox',
                    'Dropdown',
                    'Calendar',
                    'DataGridModule',
                    'DataTable',
                    'MultiSelectModule',
                    'TooltipModule',
                    'FileUploadModule',
                    'TabViewModule',
                    'AutoCompleteModule'
                ],
                'node_modules/ng2-uploader/index.js': ['Ng2Uploader']
            },

            // if false then skip sourceMap generation for CommonJS modules
            sourceMap: false, // Default: true
        }),
        builtins(),
        uglify()
    ]
}
rollup 仍然会抱怨某些包中的默认导入,可以通过使用命名导出来解决(如果您真的想要),但即使有这些警告,一切似乎都在运行。
至于我的“最终” tsconfig.json:
{
    "compilerOptions": {
        "lib": ["es2015", "dom"],
        "target": "es5",
        "module": "es2015",
        "moduleResolution": "node",
        "declaration": false,
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": true,
        "noImplicitAny": false,
        "watch": false,
        "skipLibCheck": true,
        "allowSyntheticDefaultImports": true,
        "suppressImplicitAnyIndexErrors": true,
        "baseUrl": ".",
        "typeRoots": [
            "./node_modules/@types",
            "./node_modules"
        ],
        "types": [
            "node",
            "lodash",
            "jasmine",
            "bluebird",
            "socket.io-client"
        ]
    },
    "compileOnSave": false,
    "buildOnSave": false,
    "files": [
        "app/app.module.ts",
        "app/app.aot.ts"
    ],
    // "exclude": [
    //  "node_modules"

        // ],
        "angularCompilerOptions": {
            "genDir": "compiled",
            "skipMetadataEmit": true
        }
}

最后,这两个链接也有助于理解幕后发生了什么: 希望这能帮助到某些人。

1
我的解决方案如下:
我追踪了系统想要的内容:模块 fs、events 和 timer。它们都在 zone.js 中被引用。
我在之前尝试将其缩小到 5M 时,在我的代码中发现了一些 zone.js 的导入被篡改了。
在我移除它们后,问题消失了。
对于未来遇到类似问题的谷歌用户:
问题的原因是你的 npm 模块在内部使用了 require()。你必须更新它或重新编译它,但这次作为 ES6 包(不使用 require(),而是使用 import)。如果 require 确实被深度硬编码到其中(例如,在 .js 中使用 require),那么你必须修改其源代码。

额外的扩展:

似乎,Rollup不能正确处理非普通的导入,例如import 'Zone.js';等!它只能处理类似于import { something } from 'Anything';的导入!

所有问题的根源在于Angular要求以这种方式导入zonejs,此外任何TypeScript装饰器都需要reflect-metadata包,也是以这种方式导入的。

但实际上这并不是问题。之前看起来是这样的,比如

<script src="...zone.js"></script>

或者使用一个

标签。

import 'zone.js';

在源代码(或HTML)中,不应该再存在"

"标签。相反,您需要在没有它们的情况下编译源代码,然后将它们简单地连接到源代码开头。在我的情况下,我使用以下Grunt规则:

    concat: {
        dev: {
          src: [ "node_modules/zone.js/dist/zone.js", "node_modules/reflect-metadata/Reflect.js", "target/MyApp-core.js" ],
          dest: "target/MyApp.js"
        }
    },

这是 grunt-contrib-concat Grunt 包的一部分。

生成的 target/MyApp.js 可以被任何其他工具进一步处理(如uglify,或者最好的是Google Closure Compiler)。


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