Angular 2 AoT汇总失败,未定义' {39}

时间:2017-02-01 12:07:28

标签: javascript angular angular2-aot rollupjs

我有和我编译的Angular2应用程序一起运行AoT。 我已经解决了实际编译中遇到的问题,并且我也能够从头到尾运行Rollup而没有错误(尽管有很多警告,我认为这是预期的)。

但是,在运行应用程序时,浏览器始终在app.bundle.js上声明require is not defined

我做错了什么?

这是我的功能性非AoT示例代码/配置: https://plnkr.co/edit/oCAaeXUKWGyd34YKgho9?p=info

这是我的功能性AoT示例配置抛出require错误: https://plnkr.co/edit/Y1C5HaQS3ddCBrbRaaoM?p=info

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

据我所知,浏览器无法使用require,但不应该参与其中吗?

最好的问候

2 个答案:

答案 0 :(得分:1)

所以,最终我能够解决这个问题。

代码中有一个流氓const _ = require("lodash")。 一旦我删除了它,它一直没有问题。

值得一提的两件事:

  1. 由于node.js(1.7GB内存)的内存限制,ngc命令与node --max-old-space-size=8192 ./node_modules/.bin/ngc -p tsconfig-aot.json一起运行
  2. 同样,出于同样的原因,rollupnode --max-old-space-size=8192 ./node_modules/.bin/rollup -c rollup-config.js
  3. 一起运行

    您可能可以使用--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 :(得分:1)

我对此问题的解决方案如下:

我跟踪了系统想要的内容:模块 fs 事件计时器。所有这些都在zone.js中引用。

我在之前的尝试中发现一些入侵我的代码的zone.js导入量为5M。

我删除后,问题就消失了。

对于具有类似问题的未来的googlers:

问题的原因是你的npm模块在内部使用require()。您必须更新它或重新编译它,但这次作为ES6包(它不使用require(),它使用import)。如果require非常硬编码(例如,它在.js中并使用require),那么你必须修改它的来源。

附加扩展名:

看来,汇总无法正确处理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,或者最好是谷歌闭包编译器)。