Closed borm closed 2 years ago
Not really possible at the moment and it doesn't really sound like something that I think should be supported either but if there's some more context I'm open to discuss on that.
I'd look into a separate plugin (maybe event-hooks-webpack-plugin
fits the bill) that allows you to execute some custom logic, parse the SVG and generate the JSON file. But I'm afraid the bigger problem will be that you want all of that in the same compilation step; so it needs to generate the SVG, parse it, write a JSON file while at the same time your TS (which needs this JSON file) is already being compiled in parallel.
Another option would be to hijack the sprite.prefix
option, specify a function which will receive the path and generate some JSON structure from there, but I think you'll still run into the same compilation step problem described before.
To work around the compilation step/parallelism issue you can also create the JSON based on the files in your src/icons/
directory (thinking outside of the box here as you don't need to use this plugin to generate the JSON), if you do this before compilation starts the file should always be available and the TS compiler should be happy. Maybe webpack-manifest-plugin
can help you in some way as it generates a JSON manifest already.
Looking at the expected result, most projects I've seen use something like this to type their SVG files, does that not solve your problem?
declare module '*.svg' {
const content: string;
export default content;
}
I'm closing this ticket for now, as I said I don't think this should be a responsibility of this plugin but feel free to comment/discuss further!
@cascornelissen okay, seems i understood the problem what u described, my temporary solution now, dont know how to do that better, but looks it works fine
import { Compiler } from 'webpack';
const path = require('path');
const fs = require('fs');
export default class IconListPlugin {
apply(compiler: Compiler) {
const pluginName = IconListPlugin.name;
compiler.hooks.done.tap(pluginName, () => {
fs.readdir(
path.resolve(__dirname, 'src/assets/icons'),
(err: NodeJS.ErrnoException, icons: Array<string>) => {
if (err) {
throw err;
}
fs.writeFile(
path.resolve(__dirname, 'src/assets/icons.json'),
JSON.stringify(
icons.reduce(
(acc, name) => ({
...acc,
[name.replace(/\.[^/.]+$/, '')]: name,
}),
{}
),
null,
2
),
() => {
//
}
);
}
);
});
}
}
import icons from 'assets/icons.json';
export interface IconProps {
name: keyof typeof icons;
}
Thanks for reporting back with a solution! That definitely works and is similar to what I was suggesting with event-hooks-webpack-plugin
as that could be set up in such a way:
new EventHooksPlugin({
eventName: () => {
fs.readdir(...) // Your logic
}
})
Input
Expected result
icons.json