Hvordan tvinger man TypeScript til ikke at kompilere til JS, når jeg har en fejl, med Webpack Encore sat op
Jeg bruger Webpack Encore i mit projekt til at kompilere TypeScript til JavaScript. Opsætningen fungerer perfekt, men jeg vil gerne have, at min watch/build-kommando stopper, når jeg har en fejl i min TypeScript-kode. Nu ved jeg, at i et TS-projekt skulle jeg sætte "noEmitOnError": true i mit tsconfig.json's compilerOptions-objekt.
Lige nu ser min webpack.config.js sådan ud.
const Encore = require('@symfony/webpack-encore');
const babelLoader = {
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"corejs": {version: 3, proposals: true}
},
]
]
}
};
Encore
.setOutputPath('public/build/')
.copyFiles({
from: './assets/images',
to: 'images/[path][name].[hash:8].[ext]'
})
.setPublicPath('/build')
.cleanupOutputBeforeBuild()
.enableVersioning()
.enableSourceMaps()
.addEntry('app', './assets/ts/app.ts')
.addEntry('admin', './assets/ts/admin/app.ts')
.enableTypeScriptLoader()
.enableForkedTypeScriptTypesChecking()
.addLoader(babelLoader)
.enablePostCssLoader()
.enableSassLoader((options) => {
options.outputStyle = 'compressed';
})
.enableSingleRuntimeChunk()
.splitEntryChunks();
const config = Encore.getWebpackConfig();
// needed for Vagrant VM for watch mode to work correctly
config.watchOptions = {
poll: true
};
module.exports = config;
Linjerne, der er ansvarlige for TS-kompilering, er
.enableTypeScriptLoader()
.enableForkedTypeScriptTypesChecking()
Ifølge WebPack Encores dokumentation skal metoden enableForkedTypeScriptTypesChecking få Encore til at bruge min tsconfig.json.
Min tsconfig.json ser sådan ud:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true,
"noEmitOnError": true
},
"files": [
"core.ts",
"sys.ts",
"types.ts",
"scanner.ts",
"parser.ts",
"utilities.ts",
"binder.ts",
"checker.ts",
"emitter.ts",
"program.ts",
"commandLineParser.ts",
"tsc.ts",
"diagnosticInformationMap.generated.ts"
]
}
Så jeg har "noEmitOnError": true i mine compilerindstillinger. Men når jeg så laver en bevidst fejl i min TS-kode (f.eks.: fjerner et argument fra et funktionskald) - som også korrekt bliver markeret i mit IDE som en fejl - og derefter kører enten encore dev eller encore production, så går mit build igennem, og jeg ser de kompilerede, bundtede JS-filer i min build-mappe.
Jeg har også sat compilationsmålet til ES6, men når jeg kigger i mine kompilerede bundter, ser jeg, at alle mine let og const variabeldeklarationer blev transpileret til ES5-kompatible var-udsagn.
Så det ser ud til, at TS-kompilatoren ignorerer, hvad jeg fortæller den i tsconfig.json. I min mappestruktur har jeg tsconfig.json, webpack.config.js og package.json alle ved siden af hinanden i rodmappen.
Også når jeg bruger console.log på resultatet af Encore.getWebpackConfig() i min webpack.config.js, ser jeg, at compilerOptions er et tomt objekt. Så spørgsmålet er egentlig; hvorfor får TypeScript-kompilatoren ikke min konfiguration?
Svar #1
Da du bruger TS med webpack, skal du fortælle selve webpack, at den skal stoppe ved fejl, ikke kun TS:
https://webpack.js.org/configuration/optimization/#optimizationnoemitonerrors
At tilføje config.optimization.noEmitOnErrors=true; før du eksporterer din konfiguration skulle gøre tricket, jeg tror ikke, der er en specifik indstilling for dette gennem Encore.
Der bør heller ikke være behov for .enableForkedTypeScriptTypesChecking(), hvis det blot er for at hente tsconfig.json - dette burde også blive gjort af .enableTypeScriptLoader(), som også tillader en brugerdefineret konfiguration.
Baseret på dine addEntry-kald er din files TS-konfiguration sandsynligvis forkert og ikke nødvendig forresten.