Unable to configure svgo-loader (webpack) - javascript

I'm using svgo-loader to optimize the svg images and its using the default configuration for this. I want to add some custom configuration like I dont want to remove the viewBox from svg as it makes defining the dimensions of svg really hard.
I found the following solutions from internet... but none of them are working, and I always get the viewBox removed from svg.
{
loader: 'svgo-loader',
options: {
plugins: [{
removeViewBox: false
}]
}
}
{
loader: 'svgo-loader',
options: {
externalConfig: "svgo-config.yml"
}
}
{
loader: 'svgo-loader',
options: {
configFile: './svgo.config.js'
}
}
Content of config.yml file
plugins:
- removeTitle: false
- remoViewBox: false
Content of svgo.config.js
const { extendDefaultPlugins } = require('svgo');
module.exports = {
plugins: extendDefaultPlugins([
{
name: 'removeTitle',
active: false
},
{
name: 'removeViewBox',
active: false
},
])
};
For the configFile solution, I feel like it's just not picking the given file, because if I will provide the wrong file location (or some file location that doesnt exists) it works exactly same as the default case (my expectation was to have an error smething like ...wrong file supplied).

Using svgo-loader v3.0.0 (with svgo v2.4.0 or newer):
create svgo.config.js in root project folder with following content:
module.exports = {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false,
},
},
},
],
};
in webpack.config.js
{
test: /\.svg$/i,
use: [
{
loader: 'file-loader',
},
{
loader: 'svgo-loader',
},
]
},

There is no need to pass any options for the svgo-loader in the webpack config. Just passing the default config under the root directory with the required options for fine-tuning the loader worked for me.
Make sure its named svgo.config.js as this is this file that will be picked by the svgo for loading in options...much like how we pass config files for other things like prettier, ts, and so on.
webpack.config.js
{
test: /\.svg$/i,
use: [
{
loader: 'file-loader',
},
{
loader: 'svgo-loader',
},
]
},
And this is my svgo.config.js, since I just need to preserve the viewBox attribute on my SVG I have added that...you can use this complete list for your reference.
const { extendDefaultPlugins } = require('svgo');
module.exports = {
plugins: extendDefaultPlugins([
{
name: 'removeViewBox',
active: false
},
])
};
Thanks for the help #trySound!

Related

Webpack is not displaying my img but only alt attribute text

as a recruitment task I have to copy layout using HTML/CSS and Vanilla JS. I've got a starter pack as a webpack bundle and according to recruiter documentation i have to just install all dependencies using npm install. After creating some layout in css i had to use img tag and here my problem start. First I had error that I'm missing img-loader, so I installed it. Now i can't see image but only alt attribute text.
this is my webpack.config.js for file-loader and img-loader:
{
test: /\.(jp?g|png|gif|svg)$/i,
use: [
{
loader: "file-loader",
options: {
name: "img/[name].[ext]",
},
},
{
loader: "img-loader",
options: {
enabled: isProduction,
gifscale: {
interlaced: false,
},
mozjpeg: {
progressive: true,
arithmetic: false,
},
optipng: false,
pngquant: {
floyd: 0.5,
speed: 2,
},
svgo: {
plugins: [{ removeTitle: true }, { covertPathData: false }],
},
},
},
],
},
here is file structure: file structure
I tried installing all dependencies step by step, changing config and I searched internet across. Unfortunately i couldn't find any solution.

VueJS loading SVG file depending on variable in for loop using v-html giving [object Module] instead

I'm trying to load SVGs saved in separate files depending on the content in a loop. When the page loads, I see this:
Hey, Here's my code:
<div
v-for="(rec, index) in stats"
:key="index"
>
<div class="iconForeground align-self-center" v-html="require(`../../../assets/svg/dashboard/attributes/${rec.icon}.svg`)">
</div>
</div>
Here's the data function, I've omitted the whole thing for brevity:
data() {
return {
stats: [{name: "Leadership", percent: "75", top: "5", icon: "leadership"},
{name: "Innovation", percent: "25", icon: "genius-ideas"}] as Array<Record<string, string>>
}
}
How can I accomplish this?
EDIT
Here's my vue.config.js:
const path = require("path");
module.exports = {
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: [
"./src/styles/global.scss"
]
},
configureWebpack: {
module: {
rules: [{
test: /\.svg$/,
loader: 'vue-svg-loader'
}]
}
}
}
}
EDIT 2 It seems even after installing url-loader and following the advice, I still cannot load the image, here's my updated vue.config.js:
const path = require("path");
module.exports = {
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: [
"./src/styles/global.scss"
]
},
configureWebpack: {
module: {
rules: [
{
test: /\.svg$/,
loader: 'vue-svg-loader'
},
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
esModule: false,
},
},
],
}]
}
}
}
}
and my html:
<div class="d-flex flex-column justify-content-center" :style="{marginRight: '24px'}">
<div class="purpleDot"></div>
<div class="iconForeground align-self-center">
<img :src="require(`../../../assets/svg/dashboard/attributes/${rec.icon}.svg`)" />
</div>
</div>
The answer is to use dynamic components such as this
<template>
div
v-for="(m, i) in modules"
:key="i">
<component :is="m.image"></component>
</div>
</template>
import PraiseIcon from "#/assets/svg/navigation-bar/Praise-Icon.svg";
components: {
'Praise-Icon': PraiseIcon
},
data() {
return {
modules: [
{
name: "Praise",
image: "Praise-Icon",
}
] as Array<Record<string, string>>
}
}
remove your svg loader
{
test: /\.svg$/,
loader: 'vue-svg-loader'
},
add svg to your url-loader
test: /\.(png|jpg|gif|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
esModule: false,
},
},
],
}
this normally because your webpack loader settings
try set the esModule option in url-loader to false.
this should fix your issue.
you don't need to follow content below.
and another issue, even if you fixed your loader, you still can't load it.
for the image you should use img tag to load it.
<img :src=`require(...)`/>
v-html will only loads it's path string.

Not able to add favicon in gatsby config file

Even after adding favicon to gatsby hello world starter project in gatsby config file, its not working.
I tried googling and searched in stackoverflow for similar question, How do i add favicon gatsby-config.js?. But that doesn't help or i maybe wrong somewhere.
Please correct me!!
GATSBY CONFIG.JS
/**
* Configure your Gatsby site with this file.
*
* See: https://www.gatsbyjs.org/docs/gatsby-config/
*/
module.exports = {
/* Your site config here */
siteMetadata: {
title: "xxxxxxx",
author: "Subin",
},
plugins: [
"gatsby-plugin-react-helmet",
{
resolve: "gatsby-source-contentful",
options: {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
},
},
"gatsby-plugin-sass",
// this plugin will pull all the files in our project system
{
resolve: "gatsby-source-filesystem",
options: {
name: "src",
path: `${__dirname}/src/`,
icon: `../src/images/favicon-32x32.png`,
},
},
"gatsby-plugin-sharp",
// REMARK plugin needed to extract the markdown files and parses
{
resolve: "gatsby-transformer-remark",
options: {
plugins: [
"gatsby-remark-relative-images",
{
resolve: "gatsby-remark-images",
options: {
maxWidth: 750,
linkImagesOriginal: false,
},
},
],
},
},
],
}
PROJECT DIRECTORY IMAGE
Image : Tree hierarchy of my project structure
To display your favicon, you need to have the gatsby-plugin-manifest installed, it doesn't come with the hello world starter.
npm install --save gatsby-plugin-manifest
And here is your gatsby-config.js with some default settings to this plugin:
/**
* Configure your Gatsby site with this file.
*
* See: https://www.gatsbyjs.org/docs/gatsby-config/
*/
module.exports = {
/* Your site config here */
siteMetadata: {
title: "xxxxxxx",
author: "Subin"
},
plugins: [
"gatsby-plugin-react-helmet",
{
resolve: "gatsby-source-contentful",
options: {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN
}
},
"gatsby-plugin-sass",
// this plugin will pull all the files in our project system
{
resolve: "gatsby-source-filesystem",
options: {
name: "src",
path: `${__dirname}/src/`,
icon: `../src/images/favicon-32x32.png`
}
},
"gatsby-plugin-sharp",
// REMARK plugin needed to extract the markdown files and parses
{
resolve: "gatsby-transformer-remark",
options: {
plugins: [
"gatsby-remark-relative-images",
{
resolve: "gatsby-remark-images",
options: {
maxWidth: 750,
linkImagesOriginal: false
}
}
]
}
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: "xxx",
short_name: "xxxx",
start_url: "/",
background_color: "#6b37bf",
theme_color: "#6b37bf",
// Enables "Add to Homescreen" prompt and disables browser UI (including back button)
// see https://developers.google.com/web/fundamentals/web-app-manifest/#display
display: "standalone",
icon: "src/images/favicon-32x32.png" // This path is relative to the root of the site.
}
}
]
};
Remember to stop your development server and start a brand new one when modifying gatsby-config.js in order to see your changes.
Can you try this and let me know if it works as intended?

Webp images doesn't render correct

I have the problem with webpack build webp images. There is SSR react project.
Example of react code:
import slotroulette from './slotroulette.png';
import slotrouletteWebp from './slotroulette.webp';
...
return (
...
<picture>
<source srcSet={slotrouletteWebp} type="image/webp" />
<img
css={{ width: '200px' }}
src={slotroulette}
alt="slot-roulette"
/>
</picture>
...
)
);
};
Example webpack config file:
{
test: /\.(jpe?g|gif|svg|ico|png)$/,
use: [
{
loader: 'file-loader',
options: {
hash: 'sha512',
digest: 'hex',
publicPath: `${CDN_HOST}/pub/`,
outputPath: 'pub/',
name: '[hash].[ext]',
},
},
{
loader: 'image-webpack-loader',
query: {
mozjpeg: {
progressive: true,
},
gifsicle: {
interlaced: false,
},
svgo: {
plugins: [
{
removeViewBox: false,
},
],
},
webp: {
quality: 80,
},
},
},
],
},
In this case i have next error:
ERROR in .../slotroulette.webp
Module parse failed: Unexpected character '' (1:6)
You may need an appropriate loader to handle this file type.
In case I add 'webp' to the 'test'( test: /.(jpe?g|gif|svg|ico|png|webp)$/,) I will get next problem webpack convert webp to png that can't be opened.
This is how I formatted my jsx.
JSX
<picture>
<source srcSet={`${baseUrl.public}img/rsgis-logo.webp`} type="image/webp" />
<source srcSet={`${baseUrl.public}img/rsgis-logo.png`} type="image/png" />
<img src={`${baseUrl.public}img/rsgis-logo.png`} className="rsgis-logo" alt="RS&GIS Logo" />
</picture>
Webpack
I did my webpack a little different. The webp-loader worked well for me except for the fact that it did not transfer the png to the output directory.
With the webp-loader:
loaders: [
{
test: /\.(jpe?g|png)$/i,
loaders: [
'file-loader',
'webp-loader?{quality: 80}'
]
}
]
The webp-loader will convert the images into the webp format. Then place the images in the output/img directory (I didn't specify the output location above as I dont have the code on my person right now)
Then to get the pngs to the output directory, I used the webpack plugin CopyWebpackPlugin. This takes a directory and places it in the output directory.
plugins: [
...,
new CopyWebpackPlugin([
{ from: "./src/images/png", to: "./img" }
]),
...
],
After I did this implementation, I decided to do the reverse.
I did not like the web-loader. I ended up converting my images via CLI using the webp tool and used the CopyWebpackPlugin to move the webp files to the output directory. I then had webpack process my images normally using the file-loader
{
test: /\.(svg|gif|jpe?g|png)$/i,
use: [{
loader: "file-loader",
options: {
name: "/img/[name].[ext]"
}
}]
},
plugins: [
...,
new CopyWebpackPlugin([
{ from: "./src/images/webp", to: "./img" }
]),
...
],
Hopefully this helps a little!

Dojo 1.10 Custom Build output directory location wrong

I am trying to implement the general example illustrated in:
https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/
where my directory structure does not match the "default".
/
index.html
js/
lib/
dojo/
dijit/
dojox/
my/
When I run against the development directories, everything works great! Using this config at runtime:
<script>
var dojoConfig = {
baseUrl: "/lib/_site/js/",
tlmSiblingsofDojo: false,
async: 1,
hasCache: {
// these are the values given above, not-built client code may test for these so they need to be available
"dojo-built": 1,
"dojo-loader": 1,
"dojo-undef-api": 0,
dom: 1,
"host-browser": 1,
// Disable deferred instrumentation by default in the built version.
"config-deferredInstrumentation": 0,
// Dojo loader has built-in "has" api. Since dojoConfig is used
// by Dojo loader, we can set the default here.
"dojo-has-api": 1,
// default
"config-selectorEngine": "lite",
"esri-featurelayer-webgl": 0,
"esri-promise-compatibility": 0,
"esri-promise-compatibility-deprecation-warnings": 1
},
packages: [
{
name: "dojo",
location: "lib/dojo"
},
{
name: "dijit",
location: "lib/dijit"
},
{
name: "dojox",
location: "lib/dojox"
},
{
name: "dstore",
location: "lib/dstore"
},
{
name: "dgrid",
location: "lib/dgrid"
},
{
name: "esri",
location: "lib/esri"
},
{
name: "moment",
location: "lib/moment",
main: "moment"
},
{
name: "my",
location: "my",
main: "app"
}
]
};
</script>
<script src="~/lib/_site/dist/js/lib/dojo/dojo.js"></script>
Dojo correctly locates "my" and the other "libs". But if I try to do an optimized custom build for production, everything works the same except the "my" directory is copied to the "lib" directory, but dojo is still looking for it where it should be?
The output directories look like:
/
index.html
js/
lib/
dojo/
dijit/
dojox/
my/
I am using this profile to build the optimized package..
*
* Based on the dojo-boilerplate
* https://github.com/csnover/dojo-boilerplate
* and https://github.com/tomwayson/esri-slurp-example
*
* Please refer to the Dojo Build tutorial for more details
* http://dojotoolkit.org/documentation/tutorials/1.10/build/
* Look to `util/build/buildControlDefault.js` for more information on available options and their default values.
*/
var profile = {
optimizeOptions: {
languageIn: "ECMASCRIPT6",
languageOut: "ECMASCRIPT5"
},
// `basePath` is relative to the directory containing this profile file; in this case, it is being set to the
// src/ directory, which is the same place as the `baseUrl` directory in the loader configuration.
basePath: "./js/",
tlmSiblings:false,
action: "release",
optimize: "closure", // requires Java 6 or later: http://code.google.com/p/closure-compiler/wiki/FAQ
layerOptimize: "closure",
useSourceMaps: false,
cssOptimize: "comments",
copyTests: false,
internStrings: true,
mini: true,
// The default selector engine is not included by default in a dojo.js build in order to make mobile builds
// smaller. We add it back here to avoid that extra HTTP request. There is also an "acme" selector available; if
// you use that, you will need to set the `selectorEngine` property in index.html, too.
selectorEngine: "lite",
// Strips all calls to console functions within the code. You can also set this to "warn" to strip everything
// but console.error, and any other truthy value to strip everything but console.warn and console.error.
// This defaults to "normal" (strip all but warn and error) if not provided.
stripConsole: "none",
// dojoBootText: "require.boot && require.apply(null, require.boot);",
insertAbsMids: 0,
// If present and truthy, instructs the loader to consume the cache of layer member modules
noref: true,
// A list of packages that will be built. The same packages defined in the loader should be defined here in the
// build profile.
packages: [
// "app" is a sample path for your application
// set this accordingly
{
name: "my",
location: "my"
},
{
name: "dojo",
location: "lib/dojo"
},
{
name: "dijit",
location: "lib/dijit"
},
{
name: "dojox",
location: "lib/dojox"
},
{
name: "dstore",
location: "lib/dstore"
},
{
name: "dgrid",
location: "lib/dgrid"
},
{
name: "esri",
location: "lib/esri"
},
{
name: "moment",
location: "lib/moment",
main: "moment",
trees: [
// don"t bother with .hidden, tests, min, src, and templates
[".", ".", /(\/\.)|(~$)|(test|txt|src|min|templates)/]
],
resourceTags: {
amd: function (filename, mid) {
return /\.js$/.test(filename);
}
}
}
],
// Any module in an application can be converted into a "layer" module, which consists of the original module +
// additional dependencies built into the same file. Using layers allows applications to reduce the number of HTTP
// requests by combining all JavaScript into a single file.
layers: {
// This is the main loader module. It is a little special because it is treated like an AMD module even though
// it is actually just plain JavaScript. There is some extra magic in the build system specifically for this
// module ID.
"dojo/dojo": {
// By default, the build system will try to include `dojo/main` in the built `dojo/dojo` layer, which adds
// a bunch of stuff we do not want or need. We want the initial script load to be as small and quick to
// load as possible, so we configure it as a custom, bootable base.
boot: true,
customBase: true,
include: [
"dojo/domReady",
/** enforce some modules loading */
/** not included because dom is -1 */
"dojo/_base/browser",
"esri/core/request/script",
// esri stuff for 3D maps
"esri/portal/support/layersCreator",
"esri/views/3d/layers/VectorTileLayerView3D"
]
// You can define the locale for your application if you like
// includeLocales: ["en-us"]
},
"esri/identity/IdentityManager": {
include: [
"esri/identity/IdentityManager"
]
},
"esri/views/MapView": {
include: [
"esri/views/MapView",
"esri/views/2d/layers/GraphicsLayerView2D",
"esri/views/2d/layers/FeatureLayerView2D",
"esri/views/2d/layers/TiledLayerView2D"
],
exclude: [
"esri/widgets/support/widget"
]
},
"esri/views/SceneView": {
include: [
"esri/views/SceneView",
"esri/layers/graphics/controllers/I3SOnDemandController",
"esri/layers/SceneLayer",
"esri/views/3d/layers/ElevationLayerView3D",
"esri/views/3d/layers/FeatureLayerView3D",
"esri/views/3d/layers/SceneLayerView3D",
"esri/views/3d/layers/TiledLayerView3D"
],
exclude: [
"esri/widgets/support/widget"
]
},
"esri/WebMap": {
include: [
"esri/WebMap"
]
},
"esri/WebScene": {
include: [
"esri/WebScene"
]
},
"esri/layers/VectorTileLayer": {
include: [
"esri/layers/VectorTileLayer"
]
},
"esri/views/2d/layers/VectorTileLayerView2D": {
include: [
"esri/views/2d/layers/VectorTileLayerView2D"
],
exclude: ["esri/views/MapView"]
},
"esri/views/2d/layers/support/FeatureLayerView2DWebGL": {
include: [
"esri/views/2d/layers/support/FeatureLayerView2DWebGL"
],
exclude: ["esri/views/MapView"]
},
"esri/core/workers/WorkerConnection": {
include: [
"esri/core/workers/WorkerConnection"
]
},
"esri/views/vectorTiles/WorkerTileHandler": {
include: [
"esri/views/vectorTiles/WorkerTileHandler"
]
},
"esri/widgets/support/widget": {
include: [
"esri/widgets/support/widget"
]
}
}
I just can't figure out why! I have tried 10thteen variations. I have not tried to copy the "my" directory back to its proper location, as I shouldn't have to!! If I can't figure it out and manual copying does work, I will just add a copy after the dojo build in the process. BTW-Using NPM and grunt.
Any ideas? Your time and expertise are greatly appreciated!!
Cheers!
BTW-Using NPM and grunt.
EDIT: Here is the grunt stuff used to run the custom build.
A quick note on the custom build. I was trying to "bake" a default
profile into the build by defining a "defaultConfig in the build
profile, as it didn't seem to be working. So I hardwired the
dojoConfig as illustrated above. See the Application Build Profile
section of:
https://dojotoolkit.org/documentation/tutorials/1.10/build/index.html
So the contents of my grunt file that matter:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
options: {
force: true
},
any: {
src: ''
}
},
dojo: {
dist: {
options: {
releaseDir: '../dist/js/lib',
}
},
options: {
profile: 'site.profile.js',
dojo: './js/lib/dojo/dojo.js',
load: 'build',
cwd: './',
basePath: './js/'
}
}
});
require('load-grunt-tasks')(grunt, { scope: 'devDependencies' });
require('time-grunt')(grunt);
grunt.registerTask('none', function () { });
grunt.registerTask('default', 'dist');
grunt.registerTask('my-dojo', function () {
grunt.config('clean.any.src', ['./dist/js/lib']);
grunt.task.run('clean:any');
grunt.task.run('dojo');
grunt.config('clean.any.src', ['./dist/js/lib/**/*.uncompressed.js']);
grunt.task.run('clean:any');
});
};
As mentioned it copies everything to the releaseDir, including "my", where it should end up in ./dist/js.

Categories

Resources