如何使用 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 dev 或 encore prodcution 然后我的构建通过,我在我的构建目录中看到编译的、捆绑的 JS 文件。
我也将编译目标设置为 ES6,但是当我查看我的编译包时,我发现我所有的 let 和 const 变量声明被转译为兼容 ES5 的 var 语句。
所以 TS 编译器似乎忽略了我在 tsconfig.json 中告诉它的内容。
在我的文件夹结构中,我有 tsconfig.json、webpack.config.js 和 package.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 配置可能不正确并且不需要。
我在项目中使用 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 dev 或 encore prodcution 然后我的构建通过,我在我的构建目录中看到编译的、捆绑的 JS 文件。
我也将编译目标设置为 ES6,但是当我查看我的编译包时,我发现我所有的 let 和 const 变量声明被转译为兼容 ES5 的 var 语句。
所以 TS 编译器似乎忽略了我在 tsconfig.json 中告诉它的内容。 在我的文件夹结构中,我有 tsconfig.json、webpack.config.js 和 package.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 配置可能不正确并且不需要。