babel-plugin-svg-react
Version:
Transpile SVG documents into React component modules with only Babel.
73 lines (57 loc) • 1.59 kB
JavaScript
const { extname } = require("path");
const reactSvgPlugin = require("babel-plugin-react-svg");
const SVG_EXT = ".svg";
/**
* @param {string} importPath
*/
function hasSvgExtension(importPath) {
return extname(importPath) === SVG_EXT;
}
/**
* @param {any} state
*/
function isSvg(state) {
const importPath = state.file.opts.filename;
if (typeof importPath !== "string") {
throw new TypeError("Unable to determine import path.");
}
return hasSvgExtension(importPath);
}
function alterImportPath(path, state) {
const { node } = path;
if (isSvg(state) || !node.source || node.specifiers.length === 0) {
return;
}
const importPath = node.source.value;
if (hasSvgExtension(importPath)) {
node.source.value = importPath.replace(SVG_EXT, "");
}
}
/**
* @param {import("@babel/core")} babel
*/
module.exports = function reactSvgStandalonePlugin(babel) {
const { visitor: reactSvgVisitor } = reactSvgPlugin(babel);
/** @type {import("@babel/core").Visitor} */
const reactSvgVisitorWrapper = Object.keys(reactSvgVisitor).reduce(
(result, type) => {
result[type] = function() {
if (isSvg(this)) {
reactSvgVisitor[type].apply(this, arguments);
}
};
return result;
},
{}
);
/** @type {import("@babel/core").Visitor} */
const jsxVisitor = {
ImportDeclaration: alterImportPath,
ExportNamedDeclaration: alterImportPath
};
/** @type {import("@babel/core").Visitor} */
const visitor = Object.assign({}, reactSvgVisitorWrapper, jsxVisitor);
return {
visitor
};
};