Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix transformer-svg-react not finding .svgrrc's #7741

Merged
merged 14 commits into from Nov 27, 2022
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -166,7 +166,7 @@ and Parcel adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
- Fix hoisting for optional chaining member expressions - [Details](https://github.com/parcel-bundler/parcel/pull/8121)
- Fix issues with web extensions - [Details](https://github.com/parcel-bundler/parcel/pull/8000)
- Reload the closest package.json to an asset if it's a package entry to fix `sideEffects` - [Details](https://github.com/parcel-bundler/parcel/pull/7909)
- Only emit non static import bailout warnings for variables which correspond to a * import - [Details](https://github.com/parcel-bundler/parcel/pull/8136)
- Only emit non static import bailout warnings for variables which correspond to a \* import - [Details](https://github.com/parcel-bundler/parcel/pull/8136)

## [2.5.0] - 2022-04-21

Expand Down
@@ -0,0 +1,3 @@
{
"floatPrecision": 0
}
@@ -0,0 +1,4 @@
{
"icon": true,
"jsxRuntime": "classic-preact"
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1 @@
<img src="icon.svg" />
@@ -0,0 +1,5 @@
{
"dependencies": {
"preact": "*"
}
}
@@ -0,0 +1,4 @@
const { h } = require('preact');
const PreactIcon = require('./icon.svg');

module.exports = <PreactIcon />;
20 changes: 20 additions & 0 deletions packages/core/integration-tests/test/svg-react.js
Expand Up @@ -19,6 +19,7 @@ describe('svg-react', function () {
assert(file.includes('const SvgIcon ='));
assert(file.includes('_react.createElement("svg"'));
});

it('should support transforming SVGs to typescript react components', async function () {
let b = await bundle(
path.join(__dirname, '/integration/svg-react-typescript/react.ts'),
Expand All @@ -36,4 +37,23 @@ describe('svg-react', function () {
assert(file.includes('react.createElement("svg"'));
assert(types.includes('const Icon: SVGRComponent'));
});

it('should find and use a .svgrrc and .svgorc config file', async function () {
let b = await bundle(
path.join(__dirname, '/integration/svg-react-config/react.js'),
{
defaultConfig: path.join(
__dirname,
'integration/custom-configs/.parcelrc-svg-react',
),
},
);

let file = await outputFS.readFile(b.getBundles()[0].filePath, 'utf-8');
assert(!file.includes('inkscape'));
assert(!/\d\.\d/.test(file));
assert(file.includes('const SvgIcon ='));
assert(file.includes('(0, _preact.h)("svg"'));
assert(file.includes('width: "1em"'));
});
});
3 changes: 1 addition & 2 deletions packages/transformers/svg-react/package.json
Expand Up @@ -23,7 +23,6 @@
"@parcel/plugin": "2.8.0",
"@svgr/core": "^6.2.0",
"@svgr/plugin-jsx": "^6.2.0",
"@svgr/plugin-svgo": "^6.2.0",
"camelcase": "^6.3.0"
"@svgr/plugin-svgo": "^6.2.0"
}
}
50 changes: 35 additions & 15 deletions packages/transformers/svg-react/src/SvgReactTransformer.js
Expand Up @@ -3,41 +3,61 @@
import {Transformer} from '@parcel/plugin';

import path from 'path';
import camelcase from 'camelcase';
import svgoPlugin from '@svgr/plugin-svgo';
import jsxPlugin from '@svgr/plugin-jsx';
import {transform} from '@svgr/core';

function getComponentName(filePath) {
let validCharacters = /[^a-zA-Z0-9_-]/g;
let name = path.parse(filePath).name.replace(validCharacters, '');
return camelcase(name, {
pascalCase: true,
});
}

export default (new Transformer({
async loadConfig({config}) {
let conf = await config.getConfig(['.svgrrc.json', '.svgrrc']);
return conf?.contents;
let svgrResult = await config.getConfig([
'.svgrrc',
'.svgrrc.json',
'.svgrrc.js',
'.svgrrc.cjs',
'svgr.config.json',
'svgr.config.js',
'svgr.config.cjs',
]);
let svgoResult = await config.getConfig([
'.svgorc',
'.svgorc.json',
'.svgorc.js',
'.svgorc.cjs',
'svgo.config.json',
'svgo.config.js',
'svgo.config.cjs',
]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the SVG optimizer only supports svgo.config.*. Maybe we should match that here?

if (svgrResult) {
let isJavascript = path.extname(svgrResult.filePath) === '.js';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should also handle .cjs

if (isJavascript) {
config.invalidateOnStartup();
}
}
if (svgoResult) {
let isJavascript = path.extname(svgoResult.filePath) === '.js';
if (isJavascript) {
config.invalidateOnStartup();
}
}
return {svgr: svgrResult?.contents, svgo: svgoResult?.contents};
},

async transform({asset, config}) {
let code = await asset.getCode();
let componentName = getComponentName(asset.filePath);

const jsx = await transform(
code,
{},
{svgoConfig: config.svgo, ...config.svgr, runtimeConfig: false},
{
caller: {
name: '@parcel/transformer-svg-react',
defaultPlugins: [svgoPlugin, jsxPlugin],
},
filePath: componentName,
filePath: asset.filePath,
},
);

asset.type = config?.typescript ? 'tsx' : 'jsx';
asset.type = config.svgr?.typescript ? 'tsx' : 'jsx';
asset.bundleBehavior = null;
asset.setCode(jsx);

Expand Down