即使有TSlint TS错误,我也可以在开发模式下运行Angular v8应用程序(下面仅显示了几处)。但是,当我尝试为生产而构建时,它以npm ERR! code ELIFECYCLE npm ERR! errno 2
失败。我有许多TSlint TS错误,有没有一种方法可以在不解决这些错误的情况下进行生产?
ERROR in src/main/webapp/app/home/home.component.ts:16:3 - error TS2564: Property 'closeResult' has no initializer and is not definitely assigned in the constructor.
16 closeResult: string;
~~~~~~~~~~~
ERROR in src/main/webapp/app/module/home/search.component.ts:24:40 - error TS2339: Property 'kendoDatePicker' does not exist on type 'JQuery<any>'.
24 $(this.datePickerEl.nativeElement).kendoDatePicker({
~~~~~~~~~~~~~~~
src/main/webapp/app/module/home/search.component.ts:25:16 - error TS7006: Parameter 'e' implicitly has an 'any' type.
25 change: (e) => {
~
src/main/webapp/app/module/home/search.component.ts:74:43 - error TS2532: Object is possibly 'undefined'.
74 console.log("type :" + JSON.stringify(this.model.selectedRefIdObj.id));
~~~~~~~~~~~~~~~~~~~~~~~~~~~
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] webpack: `node --max_old_space_size=4096 node_modules/webpack/bin/webpack.js "--config" "webpack/webpack.prod.js" "--profile"`
更新:
感谢htn为jQuery提供解决方案。经测试是否有效。另一个解决方案是
declare const $: any;
FYI,我正在使用JHipster 6.7.1,这是我的tsconfig.json
:
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"strict": false,
"strictPropertyInitialization": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true,
"outDir": "target/classes/static/app",
"lib": ["es7", "dom"],
"typeRoots": ["node_modules/@types"],
"baseUrl": "./",
"paths": {
"app/*": ["src/main/webapp/app/*"]
},
"importHelpers": true,
"allowJs": true
},
"include": ["src/main/webapp/app", "src/test/javascript/"],
"exclude": ["node_modules", "src/main/webapp/app/module/webrtc/"]
}
这里是我的tsconfig-aot.json
:
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"strict": false,
"strictPropertyInitialization": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"suppressImplicitAnyIndexErrors": true,
"skipLibCheck": true,
"outDir": "target/classes/static/app",
"lib": ["es7", "dom"],
"typeRoots": ["node_modules/@types"],
"baseUrl": "./",
"paths": {
"app/*": ["src/main/webapp/app/*"]
},
"importHelpers": true
},
"angularCompilerOptions": {
"genDir": "target/classes/aot",
"skipMetadataEmit": true,
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true
}
}
webpack.prod.js
:
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin');
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
const path = require('path');
const utils = require('./utils.js');
const commonConfig = require('./webpack.common.js');
const ENV = 'production';
const sass = require('sass');
module.exports = webpackMerge(commonConfig({ env: ENV }), {
// Enable source maps. Please note that this will slow down the build.
// You have to enable it in Terser config below and in tsconfig-aot.json as well
// devtool: 'source-map',
entry: {
polyfills: './src/main/webapp/app/polyfills',
global: './src/main/webapp/content/scss/global.scss',
main: './src/main/webapp/app/app.main'
},
output: {
path: utils.root('target/classes/static/'),
filename: 'app/[name].[hash].bundle.js',
chunkFilename: 'app/[id].[hash].chunk.js'
},
module: {
rules: [{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
loader: '@ngtools/webpack'
},
{
test: /\.scss$/,
use: ['to-string-loader', 'css-loader', 'postcss-loader', {
loader: 'sass-loader',
options: { implementation: sass }
}],
exclude: /(vendor\.scss|global\.scss)/
},
{
test: /(vendor\.scss|global\.scss)/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
},
'css-loader',
'postcss-loader',
{
loader: 'sass-loader',
options: { implementation: sass }
}
]
},
{
test: /\.css$/,
use: ['to-string-loader', 'css-loader'],
exclude: /(vendor\.css|global\.css)/
},
{
test: /(vendor\.css|global\.css)/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
},
'css-loader',
'postcss-loader'
]
}]
},
optimization: {
runtimeChunk: false,
minimizer: [
new TerserPlugin({
parallel: true,
cache: true,
// sourceMap: true, // Enable source maps. Please note that this will slow down the build
terserOptions: {
ecma: 6,
ie8: false,
toplevel: true,
module: true,
compress: {
dead_code: true,
warnings: false,
properties: true,
drop_debugger: true,
conditionals: true,
booleans: true,
loops: true,
unused: true,
toplevel: true,
if_return: true,
inline: true,
join_vars: true,
ecma: 6,
module: true
},
output: {
comments: false,
beautify: false,
indent_level: 2,
ecma: 6
},
mangle: {
module: true,
toplevel: true
}
}
}),
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'content/[name].[contenthash].css',
chunkFilename: 'content/[id].css'
}),
new MomentLocalesPlugin({
localesToKeep: [
'en',
'ar-ly',
'zh-cn',
'ta'
// jhipster-needle-i18n-language-moment-webpack - JHipster will add/remove languages in this array
]
}),
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
// Webpack statistics in target folder
reportFilename: '../stats.html'
}),
new AngularCompilerPlugin({
mainPath: utils.root('src/main/webapp/app/app.main.ts'),
tsConfigPath: utils.root('tsconfig-aot.json'),
sourceMap: true
}),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true,
exclude: [/swagger-ui/]
})
],
mode: 'production'
});
webpack.common.js
:
const webpack = require('webpack');
const { BaseHrefWebpackPlugin } = require('base-href-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin");
const utils = require('./utils.js');
module.exports = (options) => ({
resolve: {
extensions: ['.ts', '.js'],
modules: ['node_modules'],
mainFields: [ 'es2015', 'browser', 'module', 'main'],
alias: utils.mapTypescriptAliasToWebpackAlias()
},
stats: {
children: false
},
module: {
rules: [
{
test: /\.html$/,
loader: 'html-loader',
options: {
minimize: true,
caseSensitive: true,
removeAttributeQuotes:false,
minifyJS:false,
minifyCSS:false
},
exclude: /(src\/main\/webapp\/index.html)/
},
{
test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
loader: 'file-loader',
options: {
digest: 'hex',
hash: 'sha512',
name: 'content/[hash].[ext]'
}
},
{
test: /manifest.webapp$/,
loader: 'file-loader',
options: {
name: 'manifest.webapp'
}
},
// Ignore warnings about System.import in Angular
{ test: /[\/\\]@angular[\/\\].+\.js$/, parser: { system: true } },
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: `'${options.env}'`,
BUILD_TIMESTAMP: `'${new Date().getTime()}'`,
// APP_VERSION is passed as an environment variable from the Gradle / Maven build tasks.
VERSION: `'${process.env.hasOwnProperty('APP_VERSION') ? process.env.APP_VERSION : 'DEV'}'`,
DEBUG_INFO_ENABLED: options.env === 'development',
// The root URL for API calls, ending with a '/' - for example: `"https://www.jhipster.tech:8081/myservice/"`.
// If this URL is left empty (""), then it will be relative to the current context.
// If you use an API server, in `prod` mode, you will need to enable CORS
// (see the `jhipster.cors` common JHipster property in the `application-*.yml` configurations)
SERVER_API_URL: `''`
}
}),
new CopyWebpackPlugin([
{ from: './node_modules/swagger-ui-dist/*.{js,css,html,png}', to: 'swagger-ui', flatten: true, ignore: ['index.html'] },
{ from: './node_modules/axios/dist/axios.min.js', to: 'swagger-ui' },
{ from: './src/main/webapp/swagger-ui/', to: 'swagger-ui' },
{ from: './src/main/webapp/content/', to: 'content' },
{ from: './src/main/webapp/favicon.ico', to: 'favicon.ico' },
{ from: './src/main/webapp/manifest.webapp', to: 'manifest.webapp' },
// jhipster-needle-add-assets-to-webpack - JHipster will add/remove third-party resources in this array
{ from: './src/main/webapp/robots.txt', to: 'robots.txt' }
]),
new MergeJsonWebpackPlugin({
output: {
groupBy: [
{ pattern: "./src/main/webapp/i18n/en/*.json", fileName: "./i18n/en.json" },
{ pattern: "./src/main/webapp/i18n/ar-ly/*.json", fileName: "./i18n/ar-ly.json" },
{ pattern: "./src/main/webapp/i18n/zh-cn/*.json", fileName: "./i18n/zh-cn.json" },
{ pattern: "./src/main/webapp/i18n/ta/*.json", fileName: "./i18n/ta.json" }
// jhipster-needle-i18n-language-webpack - JHipster will add/remove languages in this array
]
}
}),
new HtmlWebpackPlugin({
template: './src/main/webapp/index.html',
chunks: ['polyfills', 'main', 'global'],
chunksSortMode: 'manual',
inject: 'body'
}),
new BaseHrefWebpackPlugin({ baseHref: '/' })
]
});
utils.js
:
const path = require('path');
const tsconfig = require('../tsconfig.json');
module.exports = {
root,
mapTypescriptAliasToWebpackAlias
};
const _root = path.resolve(__dirname, '..');
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
}
function mapTypescriptAliasToWebpackAlias(alias = {}) {
const webpackAliases = { ...alias };
if (!tsconfig.compilerOptions.paths) {
return webpackAliases;
}
Object.entries(tsconfig.compilerOptions.paths)
.filter(([key, value]) => {
// use Typescript alias in Webpack only if this has value
return Boolean(value.length);
})
.map(([key, value]) => {
// if Typescript alias ends with /* then remove this for Webpack
const regexToReplace = /\/\*$/;
const aliasKey = key.replace(regexToReplace, '');
const aliasValue = value[0].replace(regexToReplace, '');
return [aliasKey, root(aliasValue)];
})
.reduce((aliases, [key, value]) => {
aliases[key] = value;
return aliases;
}, webpackAliases);
return webpackAliases;
}
不是TSLint错误,而是打字稿编译错误。对于此错误,您应该在strictPropertyInitialization
(和false
)中将tsconfig.json
设置为tsconfig.app.json
?
编辑:不好,但是您也可以将strict
等其他标志禁用为false。绝对不要这样做,但是如果有帮助,可以使用:@ts-ignore
忽略错误。但是,如果您必须忽略太多错误,请停止使用Angular
对于$(this.datePickerEl.nativeElement).kendoDatePicker
,正确的方法是为jQuery声明kendoDatePicker
方法。以及忽略错误的快速方法:
($(this.datePickerEl.nativeElement) as any).kendoDatePicker(...)
您可以将$
声明为任意值,但是您将失去jQuery的类型==>您不再具有使用Typescript的好处。无论如何,在Angular项目中使用jQuery通常是不好的...
仅当noImplicitAny
标志设置为true时,这是一个错误。我在您的tsconfig.json中看不到它。无论如何,尝试添加noImplicitAny: false
src/main/webapp/app/module/home/search.component.ts:25:16 - error TS7006: Parameter 'e' implicitly has an 'any' type.
25 change: (e) => {
仅当strictNullChecks
标志设置为true时,这是一个错误。我在您的tsconfig.json中看不到它。无论如何,尝试添加strictNullChecks: false
src/main/webapp/app/module/home/search.component.ts:74:43 - error TS2532: Object is possibly 'undefined'.
74 console.log("type :" + JSON.stringify(this.model.selectedRefIdObj.id));
您也可以尝试将fullTemplateTypeCheck
设置为false。
无论如何,禁用这些标志,尝试学习打字稿并编写简洁的代码是很糟糕的。