Reputation: 36876
UPD.
I have two folders frontend and shared that get bundled by webpack using ts-loader.
Problem is that change of exported interfaces from shared folder don't get detected.
If i add in IThemes.ts export like
export const x = 2
than changes are detected again even for interface change.
example of exported IThemes.ts:
export interface IGeneralTheme {
isDay: boolean
day: ITheme
night: ITheme
}
example of interface use 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 in frontend folder:
{
"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
})
]
})
Runned by command from configs folder: npx webpack --config webpack.dev.js
Upvotes: 4
Views: 3152
Reputation: 862
You have to enable TS compiler option importsNotUsedAsValues
, see: https://github.com/TypeStrong/ts-loader/issues/1138
Upvotes: 1
Reputation: 36876
Found answer to my own question after i saw that it's not working only for interface:
I encountered a similar issue. What solved it for me was to change the filenames of files that contain only interfaces from *.ts to *.d.ts.
Apparently, the ts-loader generates output only for files that give JavaScript output, and typescript definition files. The output is then read by the webpack watcher, and webpack updates if one of these files changes.
In your case, you have files that generate no JavaScript output and are not typescript definition files. So no output will be generated from them, and the webpack watcher won't notice when they change.
Alternative is awesome-typescript-loader that seems work fine.
Upvotes: 6