'How to load a Font from node_modules with Vite?
I'm trying to load a company font from a node_modules
folder which only includes fonts and icons, it was working locally. At first, I thought it was because Vite/Rollup don't have the ~
by default, so I added an alias in vite config, but actually what I think really happens is that Rollup simply disregard (doesn't include) my node_modules/@company
because I'm not importing any JS/TS code from it (it's just fonts/icons), so I assume that Rollup is probably skipping or ignoring that in the tree shaking process during the prod build because the only time it's reference is through the @import
in my scss file which is probably not enough.
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [
Vue({
reactivityTransform: true,
template: { transformAssetUrls },
}),
],
resolve: {
alias: {
'~@company': path.resolve(__dirname, 'node_modules/@company'),
'@': `${path.resolve(__dirname, './src')}`,
},
},
}
this only works locally, it doesn't work from a build (I get 404)
/* scss file */
@font-face {
font-family: 'comp-icon';
src: url('~@company/icons/fonts/comp-icon.woff2') format('woff2'), url('~@company/icons/fonts/comp-icon.woff') format('woff');
font-weight: normal;
font-style: normal;
}
So like I said, I think Rollup is ignoring my node_modules/@company
folder completely during the prod build tree shaking process.
I looked for why it doesn't work and came across this post in a similar issue, that person used rollup-plugin-copy
lib to copy the font into the public assets folder and that seems to work for me but is not ideal since it copies font from one place to another on every build.
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [
Vue({
reactivityTransform: true,
template: { transformAssetUrls },
}),
copy({
targets: [{ src: './node_modules/@company/icons/fonts/**/*', dest: 'public/assets/fonts'
}],
}),
],
resolve: {
alias: {
'~@company': path.resolve(__dirname, 'node_modules/@company'),
'@': `${path.resolve(__dirname, './src')}`,
},
},
}
and using it with
/* scss file */
@font-face {
font-family: 'comp-icon';
src: url('fonts/comp-icon.woff2') format('woff2'), url('fonts/comp-icon.woff') format('woff');
font-weight: normal;
font-style: normal;
}
It seems to work but I think it's just an ugly patch, I don't really wish to keep this copy process unless I really have to. My project is a Vue 3 + Vite + Vitest, however I assume that my problem is stricly a Vite/Rollup problem.
What is the correct way to load custom company fonts from a node_modules
that I believe gets excluded from Rollup at the tree shaking process? What do I need to do to get this working and expect Rollup to include all my fonts files (woff, woff2, ttf) in my final prod build?
EDIT
Creating an alias like this SO that was provided in the comments did help with my use case. However in my case I wanted to keep @
as an alias to src
so I added a ~
alias, it's similar to how it works in WebPack except that I need to add a trailing slash after the tilda, it would be nice to find how to make it the same as WebPack (path.join
is suppose to help but that didn't work) but for now it's acceptable
resolve: {
alias: {
'~': path.resolve(__dirname, './node_modules'),
'@': `${path.resolve(__dirname, './src')}`,
},
},
@font-face {
font-family: 'se-icon';
src: url('~/@company/icons/fonts/se-icon.woff2') format('woff2'), url('~/@company/icons/fonts/se-icon.woff') format('woff');
font-weight: normal;
font-style: normal;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|