You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Emitted files should be added as assets to the compilation #813
Currently, if the checker emits files to the webpack outputPath, setting { output: { clean: true } } will remove them. The reason is because Webpack does not know that emitted files, such as declarations and declaration maps, should be treated as assets generated by the bundle.
At a minimum, it would be nice if the set of emitted files was available in a tapable hook that runs before the compilation finishes. It looks like you can sort of get this by tapping the issues hook and then globbing the output folder, but it seems like this hook fires too late. In Webpack 5, you'll get
(node:98113) [DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated.
BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.
(Use `node --trace-deprecation ...` to show where the warning was created)
Feature description
It would be nice if the plugin just did this out of the box, but at a minimum, it would be nice to add a new hook that runs during the emit/processAsset phase and passes in the list of emitted files to the tap.
Feature implementation
Here's an example that uses the existing hooks, as well as fast-glob to grab the set of generated files and add them as assets. The problem is that it runs too late and throws deprecation warnings in Webpack 5.
I think you can use regular webpack hooks to do that. In the example, you don't use data emitted by the plugin, so you can simply tap into webpack's hooks :)
Ah, you want to wait for the new version of files to be emitted, right? In that case, you will have to set async: false in plugin options. This way webpack will wait for the plugin to finish type checking. The issues hook is called on afterCompile in async: false mode
Hi @piotr-oles sorry for necroing this. I'm trying this path again and am still having deprecation warnings. It looks like afterCompile is too late. In Webpack 4 you can modify the emitted assets at this hook, but in Webpack 5+ it is now an error to do so (I assume in Webpack 6 it will be blocked entirely). There is now an earlier hook, compilation.hooks.processAssets that is meant for modifying the set of emitted assets. Ideally it would be great if async: false tapped this hook.
ts-loader replaced with esbuild-loader to speedup build
d.ts generation delegated from ts-loader to ForkTsCheckerWebpackPlugin
Workaround
For now, I have come up with the following workaround:
Configure types to be emitted into a separate folder (so, it's easier to control them)
Use CleanWebpackPlugin to clean build assets
Skip cleanup of types
Clean types only once at the init phase using a custom plugin
const{ CleanWebpackPlugin }=require('clean-webpack-plugin');const{ rmSync, existsSync }=require('fs');// Custom plugin that cleanup only definition filesclassDefinitionsCleanupPlugin{apply(compiler){constoutputPath=compiler.options.output.path;if(!outputPath){thrownewError('[DefinitionsCleanupPlugin]: No output path provided');}compiler.hooks.initialize.tap('DefinitionsCleanupPlugin',()=>{consttypesPath=`${outputPath}/types`;if(existsSync(typesPath)){rmSync(typesPath,{force: true,recursive: true});}});}}...plugins: [newForkTsCheckerWebpackPlugin({typescript: {mode: 'write-dts',},}),newDefinitionsCleanupPlugin(),newCleanWebpackPlugin({// Skip cleanup of typescleanOnceBeforeBuildPatterns: ['**/*','!types/**/*','!types'],}),]
Cons:
In watch mode, definitions are not cleaned during rebuilds (probably can be tuned by tapping other hooks in custom plugin, but it's ok for my scenario)
It still would be better to have some beforeEmit hook in the ForkTsCheckerWebpackPlugin itself and tap into it to perform a cleanup
Activity
piotr-oles commentedon May 15, 2023
I think you can use regular webpack hooks to do that. In the example, you don't use data emitted by the plugin, so you can simply tap into webpack's hooks :)
piotr-oles commentedon May 15, 2023
Ah, you want to wait for the new version of files to be emitted, right? In that case, you will have to set
async: falsein plugin options. This way webpack will wait for the plugin to finish type checking. Theissueshook is called onafterCompileinasync: falsemodesgarfinkel commentedon May 15, 2023
Cool, thanks! I'll close the issue then.
sgarfinkel commentedon Dec 27, 2023
Hi @piotr-oles sorry for necroing this. I'm trying this path again and am still having deprecation warnings. It looks like
afterCompileis too late. In Webpack 4 you can modify the emitted assets at this hook, but in Webpack 5+ it is now an error to do so (I assume in Webpack 6 it will be blocked entirely). There is now an earlier hook,compilation.hooks.processAssetsthat is meant for modifying the set of emitted assets. Ideally it would be great ifasync: falsetapped this hook.mishani0x0ef commentedon Dec 28, 2023
I have faced a similar issue.
Use case
ts-loaderreplaced withesbuild-loaderto speedup buildd.tsgeneration delegated fromts-loadertoForkTsCheckerWebpackPluginWorkaround
For now, I have come up with the following workaround:
typesto be emitted into a separate folder (so, it's easier to control them)CleanWebpackPluginto clean build assetstypestypesonly once at theinitphase using a custom pluginCons:
watchmode, definitions are not cleaned during rebuilds (probably can be tuned by tapping other hooks in custom plugin, but it's ok for my scenario)beforeEmithook in theForkTsCheckerWebpackPluginitself and tap into it to perform a cleanup