Lib remove defs, linearGradient tag while using with webpack
I am using svg-sprite-loader on react app which use webpack. the problem is that it removes the <linearGradient> tags,
package.json
{
...
"devDependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0",
"@babel/preset-stage-0": "^7.0.0",
"@babel/register": "^7.5.5",
"babel-eslint": "^10.0.2",
"babel-loader": "^8.0.6",
"babel-plugin-inline-react-svg": "^1.1.0",
"babel-plugin-istanbul": "^5.2.0",
"babel-plugin-transform-runtime": "^6.23.0",
"chai": "^4.2.0",
"chai-sinon": "^2.8.1",
"copy-webpack-plugin": "^5.0.4",
"cross-env": "^5.1.4",
"css-hot-loader": "^1.4.4",
"css-loader": "^3.2.0",
"cssnano": "^4.1.10",
"eslint": "^6.1.0",
"eslint-config-airbnb": "^17.1.1",
"eslint-config-standard": "^13.0.1",
"eslint-import-resolver-webpack": "^0.11.1",
"eslint-loader": "2.2.1",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-standard": "^4.0.0",
"espree": "^6.0.0",
"estree-walk": "^2.2.0",
"file-loader": "^4.2.0",
"fs": "^0.0.1-security",
"gettext-loader2": "^0.3.0",
"gh-pages": "^2.1.1",
"json-loader": "^0.5.7",
"md5-file": "^4.0.0",
"mini-css-extract-plugin": "^0.8.0",
"mkdirp": "^0.5.1",
"mobx": "^5.13.0",
"mobx-react": "5.2.3",
"mocha": "^6.2.0",
"node-sass": "^4.12.0",
"nyc": "^14.1.1",
"path": "^0.12.7",
"po-loader": "^0.5.0",
"po2json": "^1.0.0-alpha",
"postcss-import": "^12.0.1",
"postcss-inline-svg": "^4.1.0",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0",
"postcss-svgo": "^4.0.2",
"raw-loader": "^3.1.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-transition-group": "^4.2.2",
"regenerator-runtime": "^0.13.3",
"resize-observer-polyfill": "^1.5.1",
"rimraf": "^2.6.3",
"sass-loader": "^7.0.1",
"sinon": "^7.4.1",
"style-loader": "^1.0.0",
"stylelint": "^10.1.0",
"stylelint-no-unsupported-browser-features": "^3.0.2",
"stylelint-webpack-plugin": "^0.10.5",
"svg-sprite-loader": "^4.1.6",
"svg-url-loader": "^3.0.0",
"svgo": "^1.3.0",
"svgo-loader": "^2.2.1",
"url-loader": "^2.1.0",
"webpack": "^4.39.1",
"webpack-bundle-analyzer": "^3.4.1",
"webpack-cli": "^3.3.6",
"webpack-dev-server": "^3.7.2"
},
"dependencies": {
"@welldone-software/why-did-you-render": "^3.3.8",
"event-emitter-es6": "^1.1.5",
"lodash.debounce": "^4.0.8",
"moment": "^2.24.0",
"prop-types": "^15.7.2",
"react-tabs": "^3.0.0",
"tt-react-custom-scrollbars": "4.2.1-tt2",
"url-search-params-polyfill": "^7.0.0"
},
"peerDependencies": {
"@babel/polyfill": "^7.0.0",
"mobx": "^5.0.3",
"mobx-react": "^5.1.2",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-transition-group": "^2.5.0"
},
"resolutions": {
"js-yaml": "^3.13.1"
}
}
webpack.config.js
module.exports = {
devtool: 'source-map',
entry: path.resolve(__dirname, './src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'MyLib.js',
chunkFilename: '[name]-[chunkhash:6].MyLib.js',
libraryExport: 'default',
library: 'MyLib',
libraryTarget: 'umd',
hashDigestLength: 6,
},
devServer: {
publicPath: '/dist/',
},
module: {
rules: [
{
test: /\.svg$/,
use: [
{
loader: 'svg-sprite-loader',
options: {
extract: true,
spriteFilename: 'sprite-[hash:6].MyLib.svg',
esModule: false,
},
},
{
loader: 'svgo-loader',
options: {
plugins: [
{ removeUselessStrokeAndFill: false },
{ removeUnknownsAndDefaults: false },
],
},
},
],
},
{
test: /\.(s*)css$/,
use: [
'css-hot-loader',
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { sourceMap: true },
}, {
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: loader => [
require('postcss-import')({ root: loader.resourcePath }),
require('postcss-preset-env')(),
require('postcss-inline-svg'),
require('postcss-svgo'),
],
},
}, {
loader: 'sass-loader',
options: {
sourceMap: true,
data: '@import "sass/_variables.scss";@import "sass/_themes.scss";',
includePaths: [
path.resolve(__dirname, './src'),
],
},
}],
},
{ parser: { amd: false } },
{
test: /\.(js|jsx)$/,
exclude: [
/node_modules/,
],
loader: 'eslint-loader',
enforce: 'pre',
options: { fix: true },
},
{
test: /\.(js|jsx)$/,
// exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.po$/,
loader: [path.resolve('./loaders/translation-loader.js'), 'json-loader', 'po-loader'],
},
{
test: /\.pot$/,
loader: [path.resolve('./loaders/pot-loader.js'), 'json-loader', 'po-loader'],
},
{
include: path.resolve(__dirname, 'src/utils/ga.js'),
use :[{
loader: path.resolve('./loaders/exclude-block-loader.js'),
options: {
start:`@START-EXCLUDE: '${BUILD_MODE}'`,
end: '@END-EXCLUDE',
},
}],
},
],
},
plugins: [
new MiniCssExtractPlugin({ filename: 'MyLib.css' }),
new StyleLintPlugin(),
new SpriteLoaderPlugin(),
],
externals: {
mobx: 'mobx',
react: {
root: 'React',
commonjs: 'react',
commonjs2: 'react',
},
'react-dom': {
commonjs: 'react-dom',
commonjs2: 'react-dom',
root: 'ReactDOM',
},
'mobx-react': {
commonjs: 'mobx-react',
commonjs2: 'mobx-react',
root: 'mobxReact',
},
'babel-polyfill': 'babel-polyfill',
'react-transition-group': {
commonjs: 'react-transition-group',
commonjs2: 'react-transition-group',
root: 'ReactTransitionGroup',
},
moment: {
root: 'moment',
commonjs: 'moment',
commonjs2: 'moment',
},
},
};
and here how I use the Icon
import MySvg from './path-to/my-icon.svg';
const Wrapper = SvgLogo => () => {
const vb = SvgLogo.viewBox.split(' ').slice(2);
return (
<svg width={vb[0]} height={vb[1]}>
<use xlinkHref={__webpack_public_path__ + SvgLogo.url} />
</svg>
);
};
const MySvgIcon = Wrapper(MySvg);
// then use it this way
<MySvgIcon />
everything goes well and it works, but as it remove those tags, the svg file not properly loaded. Also should notice I have check other issues, but none of them fix my problem. I made a sample repo here https://github.com/shayan-binary-2/svg-sprite-loader-sample
I also met,As shown
linearGradient、mask

@shayan-binary-2 actually svg-sprite-loader doesn't remove <linearGradient /> or other tags, if you open http://localhost:8080/sprite-c642ba.mylib.svg#normal-usage in your demo, you can see that gradient is on place:

The problem is in browsers: unfortunately they have weird support of referencing external SVGs via <use xlink:href>. I suggest you to use extract-svg-sprite-webpack-plugin and refer to SVG from CSS. It the most bulletproof solution :)