如何使用 Webpack Encore 设置在出现错误时强制 TypeScript 不编译为 JS

How to force TypeScript to not compile to JS when I have an error, with Webpack Encore setup

我在项目中使用 Webpack Encore 将 TypeScript 编译为 JavaScript。设置工作正常,但是当我的 TypeScript 代码出现错误时,我希望我的 watch/build 命令中断。 现在我知道在 TS 项目中我必须在我的 tsconfig.json 中设置 "noEmitOnError": true 编译器选项 对象。

现在我的 webpack.config.js 看起来像这样。

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;

负责TS编译的行是

.enableTypeScriptLoader()
.enableForkedTypeScriptTypesChecking()

根据 WebPack Encore's docs enableForkedTypeScriptTypesChecking 方法应该让 Encore 使用我的 tsconfig.json.

我的 tsconfig.json 看起来像这样:

{
  "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"
  ]
}

所以我的编译器选项中有 "noEmitOnError": true。但是当我在我的 TS 代码中故意犯错误时(例如:从函数调用中删除一个参数) - 这也在我的 IDE 中正确突出显示为错误 - 然后我 运行 或者 encore devencore prodcution 然后我的构建通过,我在我的构建目录中看到编译的、捆绑的 JS 文件。

我也将编译目标设置为 ES6,但是当我查看我的编译包时,我发现我所有的 letconst 变量声明被转译为兼容 ES5 的 var 语句。

所以 TS 编译器似乎忽略了我在 tsconfig.json 中告诉它的内容。 在我的文件夹结构中,我有 tsconfig.jsonwebpack.config.jspackage.json根目录下都是相邻的

另外当我 console.log Encore.getWebpackConfig() 的结果在我的 webpack.config.js我看到 compilerOptions 是一个空对象。所以问题本质上是;为什么 TypeScript 编译器不获取我的配置?

因为你在 webpack 中使用 TS,所以你需要告诉 webpack 自己停止错误,而不仅仅是 TS:

https://webpack.js.org/configuration/optimization/#optimizationnoemitonerrors

在导出配置之前添加 config.optimization.noEmitOnErrors = true; 应该可以解决问题,我认为通过 Encore 没有针对此的特定设置。

如果只是为了拾取 tsconfig.json 也应该不需要 .enableForkedTypeScriptTypesChecking() - 这也应该由 .enableTypeScriptLoader() 完成,它允许 custom configuration 作为嗯。

根据您的 addEntry 调用,您的 files TS 配置可能不正确并且不需要。