angular4 aot throw require is not defined 错误
angular4 aot throw require is not defined error
我花了一些时间用 angular 4 做 AOT,总是出现这个错误:
未捕获的 ReferenceError:未定义要求
我收到此错误是因为我在我的应用程序中使用 jquery,并且在应用程序中,我有以下代码:
var jQuery = require('jquery');
jQuery("xxxx").val()
如果我删除它,整个 AOT 就像一个魅力。
我的 tsconfig-aot.json:
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"lib": ["es5", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},
"files": [
"src/app/app.module.ts",
"src/main.ts"
],
"angularCompilerOptions": {
"genDir": "aot",
"skipMetadataEmit" : true
}
}
我的汇总配置:
import rollup from 'rollup'
import nodeResolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify'
export default {
entry: 'src/main.js',
dest: 'public/build.js', // output a single application bundle
sourceMap: false,
format: 'iife',
onwarn: function(warning) {
// Skip certain warnings
// should intercept ... but doesn't in some rollup versions
if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
// intercepts in some rollup versions
if ( warning.indexOf("The 'this' keyword is equivalent to 'undefined'") > -1 ) { return; }
// console.warn everything else
console.warn( warning.message );
},
plugins: [
nodeResolve({jsnext: true, module: true}),
commonjs({
include: [ 'node_modules/rxjs/**','node_modules/jquery/**']
}),
uglify()
]
}
这是否意味着,如果您在 ng4 应用程序中使用 require(),那么 AOT 将不起作用?
感谢并希望听到您的建议。
我试着用这个:
从 'jquery' 导入 * 作为 jQuery;
然后它和 require 一样工作,在 JIT 模式下,它工作得很好。而且, ngc 包很好。但是当我使用汇总时,输出有这个错误:
Cannot call a namespace ('jQuery')
src/app/app.component.js (14:8)
12: }
13: AppComponent.prototype.ngOnInit = function () {
14: jQuery('h1').html('New Content');
^
15: };
16: return AppComponent;
这是更新后的代码:
import * as jQuery from 'jquery';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./scss/app.component.scss']
})
export class AppComponent implements OnInit{
ngOnInit(){
jQuery('h1').html('New Content');
}
}
有什么想法吗?
您不能将 require
与 --module es2015
一起使用。
会导致TypeScript编译错误。它没有的唯一原因是你使用的是 var..require
形式而不是正确的,在 TypeScript 中,import..require
形式。
这不会引发编译错误的唯一原因是在某个地方有一个环境声明 require
,比如在 @types 包中。
它仍然不太可能工作,因为 require 不是点火模块语法的一部分,并且由于您使用的是 Rollup,它肯定不会被识别,至少不会添加一堆插件和配置。
尝试
import jQuery from 'jquery';
如果以上在 运行 时抛出 jQuery 未定义,请尝试
import * as jQuery from 'jquery';
查看您更新后的问题,我发现您收到了错误
Cannot call a namespace ('jQuery')
Which is actually the correct spec compliant behavior when using the form
import * as ns from 'module';
从分配给 module.exports
的 CommonJS 模块导入(TypeScript 中的 export =)以导出其值。
与 CommonJS 模块的互操作应该使 module.exports
的值在 default
导出下可用,这将转换为模块命名空间的 default
属性 object 即导入。也就是说形式
import jQuery from 'jquery';
实际上只是shorthand for
import {default as jQuery} from 'jquery';
不幸的是,许多环境、转译器、加载器和打包器以不同的方式处理它,因此互操作远非顺畅。
NodeJS 本身甚至没有实现它。
这是一个极其罕见的领域,TypeScript 会做绝对错误的事情。它根本不处理这种情况。而是推荐
import * as ns from 'module';
在
的规范兼容环境中会失败的表单
ns()
因为导入的模块命名空间 object 没有 [[Call]] 插槽。
幸运的是,您可以像您目前所做的那样,通过使用 TypeScript 输出 es2015
模块并使用其他工具(例如 Rollup)处理它们来避免这种行为。
另一种选择是使用 TypeScript 的 system
模块选项和 SystemJS。
这可能看起来有点过于详细,同时也有点手忙脚乱,但我认为重要的是要认识到互操作实际上有多糟糕,以便我们有一天可以修复它(我希望)。
更新:
The TypeScript team is actively looking into the 问题,看来语法正确
import jQuery from 'jquery';
TypeScript 最终将支持它,而不需要另一个转译层。
有一天,您的 children 将能够编写 Web 应用程序而不必知道这个陷阱!
我花了一些时间用 angular 4 做 AOT,总是出现这个错误: 未捕获的 ReferenceError:未定义要求
我收到此错误是因为我在我的应用程序中使用 jquery,并且在应用程序中,我有以下代码:
var jQuery = require('jquery');
jQuery("xxxx").val()
如果我删除它,整个 AOT 就像一个魅力。
我的 tsconfig-aot.json:
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"lib": ["es5", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},
"files": [
"src/app/app.module.ts",
"src/main.ts"
],
"angularCompilerOptions": {
"genDir": "aot",
"skipMetadataEmit" : true
}
}
我的汇总配置:
import rollup from 'rollup'
import nodeResolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify'
export default {
entry: 'src/main.js',
dest: 'public/build.js', // output a single application bundle
sourceMap: false,
format: 'iife',
onwarn: function(warning) {
// Skip certain warnings
// should intercept ... but doesn't in some rollup versions
if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
// intercepts in some rollup versions
if ( warning.indexOf("The 'this' keyword is equivalent to 'undefined'") > -1 ) { return; }
// console.warn everything else
console.warn( warning.message );
},
plugins: [
nodeResolve({jsnext: true, module: true}),
commonjs({
include: [ 'node_modules/rxjs/**','node_modules/jquery/**']
}),
uglify()
]
}
这是否意味着,如果您在 ng4 应用程序中使用 require(),那么 AOT 将不起作用?
感谢并希望听到您的建议。
我试着用这个: 从 'jquery' 导入 * 作为 jQuery; 然后它和 require 一样工作,在 JIT 模式下,它工作得很好。而且, ngc 包很好。但是当我使用汇总时,输出有这个错误:
Cannot call a namespace ('jQuery')
src/app/app.component.js (14:8)
12: }
13: AppComponent.prototype.ngOnInit = function () {
14: jQuery('h1').html('New Content');
^
15: };
16: return AppComponent;
这是更新后的代码:
import * as jQuery from 'jquery';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./scss/app.component.scss']
})
export class AppComponent implements OnInit{
ngOnInit(){
jQuery('h1').html('New Content');
}
}
有什么想法吗?
您不能将 require
与 --module es2015
一起使用。
会导致TypeScript编译错误。它没有的唯一原因是你使用的是 var..require
形式而不是正确的,在 TypeScript 中,import..require
形式。
这不会引发编译错误的唯一原因是在某个地方有一个环境声明 require
,比如在 @types 包中。
它仍然不太可能工作,因为 require 不是点火模块语法的一部分,并且由于您使用的是 Rollup,它肯定不会被识别,至少不会添加一堆插件和配置。
尝试
import jQuery from 'jquery';
如果以上在 运行 时抛出 jQuery 未定义,请尝试
import * as jQuery from 'jquery';
查看您更新后的问题,我发现您收到了错误
Cannot call a namespace ('jQuery') Which is actually the correct spec compliant behavior when using the form
import * as ns from 'module';
从分配给 module.exports
的 CommonJS 模块导入(TypeScript 中的 export =)以导出其值。
与 CommonJS 模块的互操作应该使 module.exports
的值在 default
导出下可用,这将转换为模块命名空间的 default
属性 object 即导入。也就是说形式
import jQuery from 'jquery';
实际上只是shorthand for
import {default as jQuery} from 'jquery';
不幸的是,许多环境、转译器、加载器和打包器以不同的方式处理它,因此互操作远非顺畅。
NodeJS 本身甚至没有实现它。
这是一个极其罕见的领域,TypeScript 会做绝对错误的事情。它根本不处理这种情况。而是推荐
import * as ns from 'module';
在
的规范兼容环境中会失败的表单ns()
因为导入的模块命名空间 object 没有 [[Call]] 插槽。
幸运的是,您可以像您目前所做的那样,通过使用 TypeScript 输出 es2015
模块并使用其他工具(例如 Rollup)处理它们来避免这种行为。
另一种选择是使用 TypeScript 的 system
模块选项和 SystemJS。
这可能看起来有点过于详细,同时也有点手忙脚乱,但我认为重要的是要认识到互操作实际上有多糟糕,以便我们有一天可以修复它(我希望)。
更新:
The TypeScript team is actively looking into the 问题,看来语法正确
import jQuery from 'jquery';
TypeScript 最终将支持它,而不需要另一个转译层。
有一天,您的 children 将能够编写 Web 应用程序而不必知道这个陷阱!