angular - 我必须在 Angular 生产构建之前修复所有 TS 错误吗?
问题描述
即使有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! ent-app@0.0.1-SNAPSHOT webpack: `node --max_old_space_size=4096 node_modules/webpack/bin/webpack.js "--config" "webpack/webpack.prod.js" "--profile"`
更新:
感谢 htn 为他提供的 jQuery 解决方案。测试工作正常。另一种解决方案是
declare const $: any;
仅供参考,我使用的是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
(and tsconfig.app.json
)?
编辑:这很糟糕,但您也可以禁用其他标志strict
,如 false。你永远不应该这样做,但如果它对你有帮助,你可以使用:@ts-ignore
忽略错误。但是,如果您必须忽略太多错误,请停止使用 Angular
对于$(this.datePickerEl.nativeElement).kendoDatePicker
,正确的方法是为 jQuery 声明kendoDatePicker
方法。以及忽略错误的快速方法:
($(this.datePickerEl.nativeElement) as any).kendoDatePicker(...)
您可以声明$
为 any,但是您正在失去 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。
无论如何,禁用这些标志是不好的,尝试学习打字稿并编写干净的代码。
推荐阅读
- python - 将小部件嵌入 QWindow
- android - 如果颤振未来构建器中的声明只接受=
- dart - ? 运算符以避免飞镖中的 NoSuchMethodError
- swift - 如何在 Swift 中将 [String] 写入文本文件?
- c# - 试图让我的事件观察程序仅在记事本的新实例打开时才启动
- reactjs - react-chartjs-2 饼图未正确呈现
- python - 在多个子图中设置不同的阈值线
- vba - ODBC 连接用户和密码持久
- javascript - 函数返回一个 Promise 但我需要一个字符串
- javascript - 如何使用 d3 在多个矩形周围获得描边(边框)?