使用了fork-ts-checker-webpack-plugin后,页面没有实时报错信息怎么办?

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

clipboard.png

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

阅读 1.5k
评论 更新于 2019-07-14
    1 个回答
    荒山
    • 1.1k

    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的转译等待时间。这就要看怎么选择了

    欢迎关注我,跟我交流。

    评论 赞赏 2019-07-15
      撰写回答

      登录后参与交流、获取后续更新提醒