Skip to content

Commit 4f78039

Browse files
authored
Merge branch 'master' into master
2 parents 2b09f09 + 8376efa commit 4f78039

File tree

6 files changed

+86
-20
lines changed

6 files changed

+86
-20
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ For example, the following code...
88
import React from 'react';
99
import CloseSVG from './close.svg';
1010

11-
const MyComponent = () => <CloseSvg />;
11+
const MyComponent = () => <CloseSVG />;
1212
```
1313

1414
will be transformed into...
@@ -17,7 +17,7 @@ will be transformed into...
1717
import React from 'react';
1818
const CloseSVG = () => <svg>{/* ... */}</svg>;
1919

20-
const MyComponent = () => <CloseSvg />;
20+
const MyComponent = () => <CloseSVG />;
2121
```
2222

2323
## Installation

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "babel-plugin-inline-react-svg",
3-
"version": "0.5.0",
3+
"version": "0.5.2",
44
"description": "A babel plugin that optimizes and inlines SVGs for your react components.",
55
"main": "lib/index.js",
66
"scripts": {
@@ -31,6 +31,7 @@
3131
"babel-cli": "^6.14.0",
3232
"babel-core": "^6.14.0",
3333
"babel-preset-airbnb": "^2.0.0",
34+
"babel-preset-react": "^6.24.1",
3435
"eslint": "^3.5.0",
3536
"eslint-config-airbnb": "^11.1.0",
3637
"eslint-plugin-import": "^1.15.0",

src/index.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import template from 'babel-template';
44
import traverse from 'babel-traverse';
55
import { parse } from 'babylon';
66
import resolveFrom from 'resolve-from';
7+
78
import optimize from './optimize';
89
import escapeBraces from './escapeBraces';
910
import transformSvg from './transformSvg';
@@ -22,31 +23,46 @@ let ignoreRegex;
2223

2324
export default ({ types: t }) => ({
2425
visitor: {
26+
Program: {
27+
enter({ scope, node }, { file }) {
28+
if (!scope.hasBinding('React')) {
29+
const reactImportDeclaration = t.importDeclaration([
30+
t.importDefaultSpecifier(t.identifier('React')),
31+
], t.stringLiteral('react'));
32+
33+
file.set('ensureReact', () => { node.body.unshift(reactImportDeclaration); });
34+
} else {
35+
file.set('ensureReact', () => {});
36+
}
37+
},
38+
},
2539
ImportDeclaration(path, state) {
40+
const importPath = path.node.source.value;
2641
const { ignorePattern, caseSensitive, root, alias } = state.opts;
27-
42+
const { file } = state;
43+
2844
if (ignorePattern) {
2945
// Only set the ignoreRegex once:
3046
ignoreRegex = ignoreRegex || new RegExp(ignorePattern);
3147
// Test if we should ignore this:
32-
if (ignoreRegex.test(path.node.source.value)) {
48+
if (ignoreRegex.test(importPath)) {
3349
return;
3450
}
3551
}
3652
// This plugin only applies for SVGs:
37-
if (extname(path.node.source.value) === '.svg') {
53+
if (extname(importPath) === '.svg') {
3854
// We only support the import default specifier, so let's use that identifier:
3955
const importIdentifier = path.node.specifiers[0].local;
40-
const iconPath = state.file.opts.filename;
56+
const iconPath = file.opts.filename;
4157

42-
const aliasMatch = alias[path.node.source.value.split('/')[0]];
58+
const aliasMatch = alias[importPath.split('/')[0]];
4359
let svgPath;
4460
if (aliasMatch) {
4561
const resolveRoot = resolve(process.cwd(), root || './');
4662
const aliasedPath = resolve(resolveRoot, aliasMatch);
47-
svgPath = aliasedPath + path.node.source.value.replace(aliasMatch, '');
63+
svgPath = aliasedPath + importPath.replace(aliasMatch, '');
4864
} else {
49-
svgPath = resolveFrom(dirname(iconPath), path.node.source.value);
65+
svgPath = resolveFrom(dirname(iconPath), importPath);
5066
if (caseSensitive && !fileExistsWithCaseSync(svgPath)) {
5167
throw new Error(`File path didn't match case of file on disk: ${svgPath}`);
5268
}
@@ -101,6 +117,7 @@ export default ({ types: t }) => ({
101117
const svgReplacement = buildSvg(opts);
102118
path.replaceWith(svgReplacement);
103119
}
120+
file.get('ensureReact')();
104121
}
105122
},
106123
},

test/fixtures/test-no-react.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import MySvg from './close.svg';
2+
3+
export function MyFunctionIcon() {
4+
return MySvg;
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import './path/to.jpg';
2+
import './code.js';
3+
4+
export default class Foo {
5+
}

test/sanity.js

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,65 @@
11
import { transformFile } from 'babel-core';
22

3+
function assertReactImport(result) {
4+
const match = result.code.match(/import React from 'react'/);
5+
if (!match) {
6+
throw new Error('no React import found');
7+
}
8+
if (match.length !== 1) {
9+
throw new Error('more or less than one match found');
10+
}
11+
}
12+
313
transformFile('test/fixtures/test.jsx', {
4-
presets: ['airbnb'],
14+
babelrc: false,
15+
presets: ['react'],
516
plugins: [
617
'../../src/index',
718
],
819
}, (err, result) => {
920
if (err) throw err;
10-
console.log(result.code);
21+
assertReactImport(result);
22+
console.log('test/fixtures/test.jsx', result.code);
1123
});
1224

13-
transformFile('test/fixtures/test-case-sensitive.jsx', {
14-
presets: ['airbnb'],
25+
transformFile('test/fixtures/test-no-react.jsx', {
26+
babelrc: false,
27+
presets: ['react'],
1528
plugins: [
16-
['../../src/index',
17-
{
18-
"caseSensitive": true
19-
}]
29+
'../../src/index',
2030
],
2131
}, (err, result) => {
32+
if (err) throw err;
33+
console.log('test/fixtures/test-no-react.jsx', result.code);
34+
assertReactImport(result);
35+
});
36+
37+
transformFile('test/fixtures/test-case-sensitive.jsx', {
38+
babelrc: false,
39+
presets: ['react'],
40+
plugins: [
41+
['../../src/index', {
42+
caseSensitive: true,
43+
}],
44+
],
45+
}, (err) => {
2246
if (err && err.message.indexOf('match case') !== -1) {
23-
console.log("Test passed: Expected case sensitive error was thrown");
47+
console.log('test/fixtures/test-case-sensitive.jsx', 'Test passed: Expected case sensitive error was thrown');
2448
} else {
2549
throw new Error("Test failed: Expected case sensitive error wasn't thrown");
2650
}
27-
});
51+
});
52+
53+
transformFile('test/fixtures/test-no-svg-or-react.js', {
54+
babelrc: false,
55+
presets: [],
56+
plugins: [
57+
'../../src/index',
58+
],
59+
}, (err, result) => {
60+
if (err) throw err;
61+
console.log('test/fixtures/test-no-svg-or-react.js', result.code);
62+
if (/React/.test(result.code)) {
63+
throw new Error('Test failed: React import was present');
64+
}
65+
});

0 commit comments

Comments
 (0)