2

vue+ts 使用了fork-ts-checker-webpack-plugin后,语言检查出错时,页面没有实时报错信息怎么办(编辑器的控制台是有的)

clipboard.png

已经将fork-ts-checker的等待异步结果关掉
clipboard.png
(以github上的某项目做的例子https://github.com/TypeStrong...

Shanny 416
6月21日提问
1 个回答
2

2019/7/15更新:

首先总结一下webpack转译Typescript现有方案吧:

进程
单进程方案(类型检查和转译在同一个进程) ts-loader(transpileOnly为false) awesome-typescript-loader
多进程方案 ts-loader(transpileOnly为true) + fork-ts-checker-webpack-plugin awesome-typescript-loader + 自带的CheckerPlugin babel + fork-ts-checker-webpack-plugin

综合考虑性能和扩展性,目前比较推荐的是babel+fork-ts-checker-webpack-plugin方案

用实例解释一下吧。

首先是单进程方案:

module.exports = {
  mode: 'development',
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use:{
          loader: 'ts-loader', // 🔴 单进程,只使用ts-loader进行'转译'和‘类型检查’
          options: {
          }
        }
      }
    ]
  },
  devServer: {
    contentBase: './dist',
    overlay: true,
  },
  plugins: [
    new HtmlWebpackPlugin(),
  ]
}

单进程因为是同步所以webpack可以收集错误信息,并通过dev-server反馈到浏览器:

图片描述


现在试试多进程方案:

module.exports = {
  mode: 'development',
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use:{
          loader: 'ts-loader',
          options: {
            transpileOnly: true  // 🔴 关闭类型检查,即只进行转译
          }
        }
      }
    ]
  },
  devServer: {
    contentBase: './dist',
    overlay: true,
  },
  plugins: [
    new HtmlWebpackPlugin(),
    new ForkTsCheckerWebpackPlugin({ // 🔴 fork一个进程进行检查,并设置async为false,将错误信息反馈给webpack
      async: false,
      eslint: false
    })
  ]
}

Ok,同样可以工作:

图片描述

对于babel还是atl,配置方式同理, 只是把ts-loader替换而已。

不过答主还是推荐使用vue-cli或create-react-app这些方案,自己折腾比较浪费时间。

更新分割线

谢邀。

没猜错的话,你使用的应该是vue-cli的Typescript插件? 先解释一下fork-ts-checker-webpack-plugin的原理:

fork-ts-checker-webpack-plugin,顾名思义就是创建一个新进程,专门来运行Typescript类型检查。这么做的原因是为了利用多核资源来提升编译的速度. 所以大多数CLI都是这样子配置的:

    addLoader({
      loader: 'ts-loader',
      options: {
        // 🔴 禁用Typescript类型检查,只做转译。这里面速度就可以很快了,因为转译不过是删除掉类型注释。
        // 现在ts-loader基本已经被babel(babel7支持Typescript)取代了
        transpileOnly: true,
        appendTsSuffixTo: ['\\.vue$'],
        // https://github.com/TypeStrong/ts-loader#happypackmode-boolean-defaultfalse
        happyPackMode: useThreads
      }
    })
    
    // ...
          config
        .plugin('fork-ts-checker')
          // 🔴 引进fork-ts-checker-webpack-plugin专门在一个进程中进行类型检查
          .use(require('fork-ts-checker-webpack-plugin'), [{
            vue: true,
            tslint: options.lintOnSave !== false && fs.existsSync(api.resolve('tslint.json')),
            formatter: 'codeframe',
            // https://github.com/TypeStrong/ts-loader#happypackmode-boolean-defaultfalse
            checkSyntacticErrors: useThreads
          }])

再回到题目本身。因为fork-ts-checker-webpack-plugin是在单独的进程跑的,所以它的错误或警告信息是异步回传给到webpack进程的。而当webpack自己处理完转译任务后,会将结果同步报告给浏览器去显示。所以就造成题目说的现象。

解决的办法也有,官方文档已经说的很明白:

图片描述

将async设置为false后,就要求webpack等待fork-ts-checker-webpack-plugin进程返回信息。不过这样做也可能会拖慢整个webpack的转译等待时间。这就要看怎么选择了

欢迎关注我,跟我交流。

撰写答案

推广链接