我有和我编译的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,但不应该参与其中吗?
最好的问候
答案 0 :(得分:1)
所以,最终我能够解决这个问题。
代码中有一个流氓const _ = require("lodash")
。
一旦我删除了它,它一直没有问题。
值得一提的两件事:
ngc
命令与node --max-old-space-size=8192 ./node_modules/.bin/ngc -p tsconfig-aot.json
一起运行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 :(得分: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,或者最好是谷歌闭包编译器)。