I'm writing a library to import into other projects, to share custom components and styles.
Problem is with font files, .woff/.ttf/etc.
//_fonts.scss
$woff_path: '~/woff';
$ttf_path: '~/ttf';
#font-face {
font-family: "MyOpensans";
src: url($woff_path + "opensans-regular-webfont.woff2") format("woff2");
src: url($woff_path + "opensans-regular-webfont.woff") format("woff");
src: url($woff_path + "OpenSans-Regular.ttf") format("font-type");
font-style: normal;
...
}
$testfont: "MyOpensans", wingdings;
When I use $testfont in my scss, the url uses relative path, which of course doesn't work when imported into other projects. So, my thought was just use base64:
src: url(data:application/x-font-woff;charset=utf-8;base64;XXXX);
Works fine if I run the .woff files through a base64 convertor, and paste into _fonts.scss. But, I'd like webpack to do it for me. I've tried both base64-inline-loader and url-loader. Neither have worked.
A bit more digging with url-loader. if I import "#/assets/woff/opensans-regular.webfont.woff2"; in my main.ts, I can see it does base64 it into a variable in the main source, but my _fonts.scss of course has no idea of this, and my _fonts.scss still has src as the relative path. It seems as though url-loader does nothing with url() inside scss.
Am I missing something? Is there a way I can get webpack to turn my url(file path) into url(data:xxx) for me? Or some other way to get custom fonts to work when compiled to a library?
You might want to look into using something like base64-inline-loader
As per the example on that page:
rules: [
{
test: /\.(jpe?g|png|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
use: ['base64-inline-loader']
}
]
Related
I have global sass being included in my project and i cant find an efficient way to add it to the project.
there seems to be 2 popular ways to add css in your project.
vite: {
plugins: [svgLoader()],
css: {
preprocessorOptions: {
scss: {
additionalData: `
#import "~/assets/styles/main.scss";
`,
},
},
},
using vite seems to work but it also seems to inject itself into every component i use, so when i generate my project, i can see my css is repeated multiple times, some files as much as 300 times. the issue is found here on vites side https://github.com/vitejs/vite/issues/4448
css: ["#/assets/styles/main.scss"],
the above option seems to not do it for every component, but normal scoped sass in .vue files doesnt pick up sass variables and mixins on compilation using this method
using additionalData adds it to every page. this item is only meant for mixns and vars, which dont translate into permanent css when built.
basically use only vars in mixins in additionalData then use your global.scss in in css
i've set up a plain vanilla js Vite installation and changed the folder structure to include all my "working" files inside a "src" folder.
With the following rollup Option inside my vite.config.js file, the build process mimic my folder structure inside the dist folder as well.
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
let extType = assetInfo.name.split('.')[1];
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
extType = 'img';
}
if (/woff|woff2|ttf/i.test(extType)) {
extType = 'fonts';
}
return `assets/${extType}/[name]-[hash][extname]`;
},
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
},
},
Build process works as intended: all files are inside their specified folders and all links inside html & css files are rewritten correctly.
But as soon as i set 'base' to './' or '' inside my vite.config.js file and build the project the url links inside css files are corrupted. They are missing the path. Only base + filename are written. All urls inside html files are build correctly.
If i set the base to something like '/somename/' all urls (html&css) are build correctly.
How can i fix this? :)
Here is a stackblitz example, where the body background image shows this behaviour. https://stackblitz.com/edit/vitejs-vite-j6xd8y?file=dist/assets/css/index-1e183c12.css
This seems to be a bug in Vite 2 (as of 2.9.12). I recommend reporting the issue.
As a workaround, switch to Vite 3 (currently 3.0.0-beta.2), which has refactored the base configuration code and avoids the problem you observed:
npm i -D vite#beta
demo
I have an application that uses UIkit, Less for local styling, and Vite for frontend tooling (bundling and whatnot). I'm not sure that this is relevant, but this is a Vue 2/Webpack application that I'm upgrading to Vue 3/Vite.
Per UIkit's Less documentation, we import UIkit's uikit.theme.less file in our project's base less file. UIkit's stylesheets have some relative paths to SVG files that get run through less's data-uri function (examples below). That worked fine with Webpack, but with Vite it's not quite working. As I understand it, for small files, data-uri will UTF-8 encode the asset and essentially inline it--at least that's what we got in our Webpack bundles. But with our Vite build, it seems these relative image paths aren't being resolved, data-uri hence falls back to a url(), and we get 404s for the images.
For example, in UIkit's code the relative path to a spinner image is defined here; it's used in a select.uk-select. And here that path is passed to a .svg-fill mixin (here). When we bundle the code using Vite, or run a local dev server, the result is:
background-image: url(../../images/backgrounds/form-select.svg);
That, of course, doesn't load because the "images" directory is relative to the form.less file. In Webpack, the output was as expected:
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='24' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23001c30' d='M12 1 9 6h6zM12 13 9 8h6z'/%3E%3C/svg%3E");
For this type of question, I would normally include an HTML/CSS/JS snippet; however, I don't think SO supports Vite. As such, I'm including a small Stackblitz that minimally demonstrates the issue: https://stackblitz.com/edit/vite-esqmqc?file=main.js Please see main.js, style.less, and note that there's a 404 error in the console complaining about the aforementioned form-select.svg file.
In case the question isn't clear, how can I get Vite to resolve images which are relative to a dependency in node_modules?
Thanks in advance.
A workaround is to configure resolve.alias to point ../../images to uikit/src/images (which resolves to the uikit package under node_modules/). This tells Vite how to resolve the problematic relative image paths.
The resolve.alias config is passed to #rollup/plugin-alias as entries. Each entry can have a custom resolver that can be used to only replace imports from UIKit. However, it requires that the import of uikit.theme.less be in its own file so that the custom resolver can correctly identify the importer in order to determine when to replace the import.
Put the import of uikit.theme.less in its own file, and import that from main.js (not from style.less):
// style.less
// #import './node_modules/uikit/src/less/uikit.theme.less'; ❌ move to own file
// my-uikit.less
#import './node_modules/uikit/src/less/uikit.theme.less';
// main.js
import './style.less';
import './my-uikit.less';
Create vite.config.js with the following configuration:
// vite.config.js
import { defineConfig } from 'vite';
import { fileURLToPath } from 'url';
import { basename } from 'path';
export default defineConfig({
resolve: {
alias: [
{
find: '../../images',
replacement: '',
customResolver(updatedId, importer, resolveOptions) {
// don't replace if importer is not our my-uikit.less
if (basename(importer) !== 'my-uikit.less') {
return '../../images';
}
return fileURLToPath(
new URL(
'./node_modules/uikit/src/images' + updatedId,
import.meta.url
)
);
},
},
],
},
})
demo
I tried basic primary color change in Spartacus 4.0.1 but it seems to be overwritten by the default styling. Followed the guide: https://sap.github.io/spartacus-docs/css-architecture/
Is there a work around for this or is it fixed in newer versions?
Here's my code
mystore/src/styles.scss:
$primary: green;
$font-weight-normal: 600;
$styleVersion: 4.0;
#import "~#spartacus/styles/index";
:root {
--cx-color-primary: green;
}
screenshot showing my style is being overwritten
I've had the same problem today. Have a look inside your angular.json file inside the root folder. There is a section that defines the styles that are loaded. For me this looked something like this:
"styles": [
"src/styles.scss"
"src/styles/spartacus/user.scss",
"src/styles/spartacus/organization.scss",
"src/styles/spartacus/checkout.scss",
"src/styles/spartacus/cart.scss",
],
I noticed that inside the user.scss and all other imports the standard #spartacus/styles library is imported at the top. So everything you do in your styles.scss is overwritten again by these imports.
My approach for now was to put the styles.scss at the end. So nothing is overwritten.
"styles": [
"src/styles/spartacus/user.scss",
"src/styles/spartacus/organization.scss",
"src/styles/spartacus/checkout.scss",
"src/styles/spartacus/cart.scss",
"src/styles.scss"
],
To me it seems like a bug that the order is like this. Might report it later.
The easiest and recommended way to override basic primary colors, as of version 4.0, is by changing the compiled values of the CSS variables. But change them inside a CSS body selector, instead of a :root selector.
Example of storefrontapp/src/styles.scss file:
$useLatestStyles: true;
#import '#spartacus/styles';
#import '#spartacus/styles/scss/theme/santorini';
body {
--cx-color-primary: #a7fff6;
--cx-color-seconday: #8aa39b;
--cx-color-text: #5c6f68;
--cx-color-background: #95d9c3;
--cx-color-dark: #a4f9c8;
}
I have a webpack project:
main.js
project.scss
In my project root I also have a custom NPM package called my-package. Im this are fonts and a SASS file which uses them:
my-package/fonts/font.woff
my-package/fonts/font.woff2
my-package/fonts.scss
In fonts.scss:
#font-face {
font-family: $myfont;
src:
url('./fonts/font.woff2') format('woff2'),
url('./fonts/font.woff') format('woff');
}
Ive tried importing fonts.scss into project.scss:
In project.scss
#include "./my-package/fonts.scss";
However the path to the fonts are wrong. As its just a SASS include the paths are taken relative to project.scss, so it would need to be this to work:
#font-face {
font-family: $myfont;
src:
url('./my-package/fonts/font.woff2') format('woff2'),
url('./my-package/fonts/font.woff') format('woff');
}
Can I make webpack import the SASS file so thats its variables etc are available, but also have it correct the paths to the font files? The custom module is my own so I can change the code for it but I don't want to change it to something nonsensical.
I had the same issue. What you could do is create a your-font.scss file to accompany your font and import the your-font.scss file once in a base file in your app and not import it in another .scss again. That way your URL will be correct.