Closed FredKSchott closed 4 years ago
I found a way to support svg react component, which needs to extend the source code a little.
Adding the following code at https://github.com/pikapkg/snowpack/blob/master/src/commands/build-util.ts#L153 (neglecting a bit changes in function params syntax...)
for (const plugin of plugins) {
const { wrapEsmProxyResponse } = plugin;
if ("function" === typeof wrapEsmProxyResponse) {
const customProxyResponse = wrapEsmProxyResponse({
url,
code,
ext,
hasHmr,
config,
});
if (customProxyResponse) {
return customProxyResponse;
}
}
}
which makes the plugin control proxy response.
thus, we can add a svg plugin maybe sth like this:
const { transformAsync, createConfigItem } = require('@babel/core');
const svgo = require('@svgr/plugin-svgo').default;
const jsx = require('@svgr/plugin-jsx').default;
const convert = require('@svgr/core').default;
const presetReact = require('@babel/preset-react');
const presetEnv = require('@babel/preset-env');
const pluginTransformReactConstantElements = require('@babel/plugin-transform-react-constant-elements');
const babelOptions = {
babelrc: false,
configFile: false,
presets: [
createConfigItem(presetReact, { type: 'preset' }),
createConfigItem([presetEnv, { modules: false }], { type: 'preset' }),
],
plugins: [createConfigItem(pluginTransformReactConstantElements)],
};
module.exports = function createPlugin(_, pluginOptions) {
return {
async transform({ urlPath, contents, isDev }) {
// console.log(urlPath, contents, isDev);
if (!urlPath.endsWith('.svg')) {
return;
}
const code = await convert(contents, pluginOptions, {
caller: {
name: '@svgr/snowpack',
defaultPlugins: [svgo, jsx],
},
urlPath,
});
const { code: result } = await transformAsync(code, babelOptions);
return {
result,
};
},
wrapEsmProxyResponse({ url, code, ext, hasHmr, config: { buildOptions } }) {
if (ext === '.svg') {
return code;
}
},
};
};
In this way, xxx.svg.proxy.js returns the react code for svg instead of export default '/path/to/svg.svg'
Hi @FredKSchott I have no idea whether this is the proper way to support svg react component. Any thoughts?
Thanks @chengcyber! The work we just merged in #567 will allow for this via something like:
{
input: [".svg"],
output: [".js"],
build() { /* run SVGR */ }
}
Or, if you only want to run this on a certain set of ".module.svg" files, you could use input: [".module.svg"]
.
This isn't quite supported yet, but the interface is now in place to support this in the near future.
Right now these two plugin methods do essentially the same thing, but with the limitation that there can only ever be one
build()
per file type (and that build is able to transform file types).We should combine these two into a single method (
build()
,transform()
, or something else entirely) with the following qualities:code
/filename
strings.foo.svg
->foo.js
orfoo.svg.js
orfoo-svg.js
(entirely up to the plugin, although we can provide recommendations)