Búsqueda de sitios web

Webpack y TypeScript: la vigilancia no funciona para las interfaces exportadas


ACT.

Tengo dos carpetas, frontend y shared, que se empaquetan con webpack usando ts-loader.

El problema es que los cambios en las interfaces exportadas desde la carpeta compartida no se detectan.

Si agrego en IThemes.ts una exportación como

export const x = 2

que los cambios se detectan nuevamente incluso para cambios en la interfaz.

ejemplo de IThemes.ts exportado:

export interface IGeneralTheme {
  isDay: boolean
  day: ITheme
  night: ITheme
}

ejemplo de uso de interfaz 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>>({})

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

tsconfig.json en la carpeta frontend:

{
  "extends": "../configs/tsconfig.base.json",
  "include": [
    "**/*",
    "../shared/**/*"
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@shared": [
        "../shared/index"
      ],
      "@frontend": [
        "index"
      ]
    },
    "jsx": "react",
    "target": "es2015"
  }
}

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/)]
}

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
    })
  ]
})

Ejecutado por comando desde la carpeta de configuraciones: npx webpack --config webpack.dev.js

Respuesta #1

Encontré la respuesta a mi propia pregunta después de ver que no funciona solo para la interfaz:

Me encontré con un problema similar. Lo que lo solucionó para mí fue cambiar los nombres de archivo de los archivos que solo contienen interfaces de *.ts a *.d.ts.

Aparentemente, el ts-loader genera salida solo para archivos que producen salida en JavaScript y archivos de definición de TypeScript. Luego, el output es leído por el observador de webpack, y webpack se actualiza si uno de estos archivos cambia.

En su caso, tiene archivos que no generan salida de JavaScript y no son archivos de definición de TypeScript. Por lo tanto, no se generará salida a partir de ellos, y el observador de webpack no notará cuando cambien.

La alternativa es awesome-typescript-loader que parece funcionar bien.

Respuesta #2

Tienes que habilitar la opción del compilador de TS importsNotUsedAsValues, consulta: https://github.com/TypeStrong/ts-loader/issues/1138

Artículos relacionados