Webpack 和打字稿:观察不适用于导出的接口

RTW*_*RTW 4 typescript webpack

更新。

我有两个文件夹前端和共享,它们被 webpack 使用 ts-loader 捆绑在一起。

问题是未检测到共享文件夹中导出接口的更改。

如果我添加 IThemes.ts 导出

export const x = 2
Run Code Online (Sandbox Code Playgroud)

即使对于界面更改,也会再次检测到更改。

导出的 IThemes.ts 示例:

export interface IGeneralTheme {
  isDay: boolean
  day: ITheme
  night: ITheme
}
Run Code Online (Sandbox Code Playgroud)

接口使用 ThemeContext.tsx 的示例:

import React, { useState, useEffect } from 'react'
import { deepClone, ITheme, IGeneralTheme } from '@shared'
import { ThemeProvider, createGlobalStyle } from 'styled-components'

type ThemeContextProps = {
  theme: ITheme
  generalTheme: IGeneralTheme
  isDay: boolean
  setGeneralTheme: React.Dispatch<React.SetStateAction<IGeneralTheme>>
}

export const ThemeContext = React.createContext<Partial<ThemeContextProps>>({})
Run Code Online (Sandbox Code Playgroud)

tsconfig.base.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "sourceMap": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "removeComments": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "strictBindCallApply": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "allowJs": true,
    "strictPropertyInitialization": true
  },
  "exclude": [
    "../../node_modules"
  ]
}
Run Code Online (Sandbox Code Playgroud)

前端文件夹中的 tsconfig.json:

{
  "extends": "../configs/tsconfig.base.json",
  "include": [
    "**/*",
    "../shared/**/*"
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@shared": [
        "../shared/index"
      ],
      "@frontend": [
        "index"
      ]
    },
    "jsx": "react",
    "target": "es2015"
  }
}
Run Code Online (Sandbox Code Playgroud)

webpack.base.js:

const path = require('path')
const webpack = require('webpack')

module.exports = {
  entry: '../frontend/client.tsx',
  output: {
    path: path.resolve('../../public'),
    filename: 'react_bundle.js'
  },
  devtool: 'source-map',
  resolve: {
    extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
    alias: {
      '@frontend': path.resolve(__dirname, '../frontend/index'),
      '@shared': path.resolve(__dirname, '../shared/index')
    }
  },
  module: {
    rules: [
      {
        test: /\.ts(x?)$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'ts-loader'
          }
        ]
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        enforce: 'pre',
        test: /\.js$/,
        loader: 'source-map-loader'
      }
    ]
  },
  plugins: [new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /ru/)]
}
Run Code Online (Sandbox Code Playgroud)

webpack.dev.js:

const merge = require('webpack-merge')
const base = require('./webpack.base.js')
const webpack = require('webpack')

module.exports = merge(base, {
  mode: 'development',
  watch: true,
  plugins: [
    new webpack.DefinePlugin({
      isProd: false
    })
  ]
})
Run Code Online (Sandbox Code Playgroud)

由 configs 文件夹中的命令运行: npx webpack --config webpack.dev.js

RTW*_*RTW 5

在我看到它不仅适用于界面后,找到了我自己问题的答案:

我遇到了类似的问题。为我解决的是将仅包含接口的文件的文件名从 *.ts 更改为 *.d.ts。

显然,ts-loader 只为提供 JavaScript 输出的文件和打字稿定义文件生成输出。然后 webpack watcher 读取输出,如果这些文件之一发生变化,webpack 就会更新。

在您的情况下,您的文件不生成 JavaScript 输出并且不是打字稿定义文件。因此不会从它们生成任何输出,并且 webpack 观察者不会注意到它们何时发生变化。

另一种选择是 awesome-typescript-loader 似乎工作正常。

  • 感谢您找到该帖子。我花了两天的时间在互联网上进行搜索,并在这个问题上发现了一些令人不安的事情。当然,我认为这是一个 laravel-mix 问题。直到今天早上我才意识到它只发生在手表模式下,因此是一个 webpack 问题。再次感谢大佬。 (2认同)