Laravel 8 FontAwesome Incorrect Directory - font-awesome

I've just tried to add FontAwesome to one of my Laravel 8 projects (using TailwindCSS). I've installed it using
npm install #fortawesome/fontawesome-free
Then added it to ./resources/css/app.css (with my TailwindCSS imports)
#tailwind base;
#tailwind components;
#tailwind utilities;
#import '~#fortawesome/fontawesome-free/css/fontawesome.css';
#import '~#fortawesome/fontawesome-free/css/regular.css';
#import '~#fortawesome/fontawesome-free/css/solid.css';
#import '~#fortawesome/fontawesome-free/css/brands.css';
Then applied the build with
npm run production
However it is giving me a 404 Error regarding the font files. They are correctly sitting inside the ./public/fonts directory but the compiled css file is looking for them in the web servers root directory.
If I manually change the compiled css file to replace
src: url(/fonts/vendor/#fortawesome/fontawesome-free/webfa-regular-400.eot?08f9891a6f44d9546678133ab121fc54);
with
src: url(../fonts/vendor/#fortawesome/fontawesome-free/webfa-regular-400.eot?08f9891a6f44d9546678133ab121fc54);
Then it works fine, how can I specify the FontAwesome dir so that I don't have to do this manual edit?
UPDATE
After some digging I found the file ./node_modules/laravel-mix/src/config.js which has the following code
fileLoaderDirs: {
images: 'images',
fonts: 'fonts'
},
This seems to be where FontAwesome is getting it's dir from but is there any way to override it?

You don't have to go so far to get it working, at least I didn't have to.
This was my config laravel mix config file after installing tailwindcss, since tail wind uses postcss. This are steps you take after you install tailwindcss and font-awesome.
mix.js('resources/js/app.js', 'public/js').postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
]);
After adding installing font-awesome, I just added this line
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer')
])
.sass('resources/sass/app.scss', 'public/css') // transpiling app.scss
.copy( // copying fonts directory
'node_modules/#fortawesome/fontawesome-free/webfonts',
'public/webfonts'
).sourceMaps();
then I had a sass file in resoures/sass/app.scss with the font-awesome import, since font-awesome is added using sass.
// Fontawesome
#import "~#fortawesome/fontawesome-free/scss/fontawesome";
#import "~#fortawesome/fontawesome-free/scss/regular";
#import "~#fortawesome/fontawesome-free/scss/solid";
#import "~#fortawesome/fontawesome-free/scss/brands"
My app.css file inside resources/css/app.css looks like this
#import 'tailwindcss/base';
#import 'tailwindcss/components';
#import 'tailwindcss/utilities';
after that just run the npm command to compile
npm run dev

I wasn't able to get FontAwesome to work with PostCSS but I was able to get it to work with SASS.
I have seen that there are a few different ways to setup SASS with Laravel 8 but I am just posting the method that worked for me in case it can help someone else.
First change css into scss
mv ./resources/css ./resources/sass
mv ./resources/sass/app.css ./resources/sass/app.scss
Then add TailwindCSS and FontAwesome imports to app.scss
#tailwind base;
#tailwind components;
#tailwind utilities;
$fa-font-path: "../webfonts"; // this might be the missing piece that doesn't work without SASS
#import "~#fortawesome/fontawesome-free/scss/fontawesome";
#import "~#fortawesome/fontawesome-free/scss/solid";
#import "~#fortawesome/fontawesome-free/scss/brands";
#import "~#fortawesome/fontawesome-free/scss/regular";
Change webpack.mix.js to the following
const mix = require('laravel-mix');
const tailwindcss = require('tailwindcss');
mix
.js('resources/js/app.js', 'public/js')
.copy('node_modules/#fortawesome/fontawesome-free/webfonts', 'public/webfonts')
.sass('resources/scss/app.scss', 'public/css')
.options ({
processCssUrls: false,
postCss: [ tailwindcss('./tailwind.config.js') ]
});
Compile with npm run production

I am using Laravel Mix in a project without Laravel and I was having this problem with Font Awesome. After several hours of searching, I was able to solve the issue (I think):
webpack.mix.js
let mix = require("laravel-mix");
mix.options({
fileLoaderDirs: {
images: 'dist/images',
fonts: 'dist/fonts'
}
});
mix
.postCss("assets/css/app.css", "dist")
.js("assets/js/app.js", "dist")
.sourceMaps();

Related

How to use font awesome 5 installed via NPM

I am not finding any docs for what to do next, I installed into my project via npm,
$ npm install --save #fortawesome/fontawesome-free-webfonts
But now what? Can anyone point me to how to actually import or use it now?
Thank you.
First install it using NPM :
npm install #fortawesome/fontawesome-free --save-dev
Now you have two ways, one way is to embed the absolute URL within your HEAD section or if you working with something like SASS(SCSS), You can import it in your custom.scss file like this :
1- first set an absolute path for webfonts (It has to be set before the fontawesome.scss) :
$fa-font-path: "node_modules/#fortawesome/fontawesome-free/WebFonts" !default;
2- Then import fontawesome.scss :
#import "node_modules/#fortawesome/fontawesome-free/scss/fontawesome";
3- Finally import regular, solid or light(pro version) of icon types :
#import "node_modules/#fortawesome/fontawesome-free/scss/regular";
After all you can assign font-family to these classes to work :
.fa,.fas,.far,.fal,.fab {
font-family: "Font Awesome 5 Free";
}
by Gulp
in a SCSS file
#import "../../../node_modules/#fortawesome/fontawesome-free/scss/fontawesome";
#import "../../../node_modules/#fortawesome/fontawesome-free/scss/brands";
#import "../../../node_modules/#fortawesome/fontawesome-free/scss/regular";
#import "../../../node_modules/#fortawesome/fontawesome-free/scss/solid";
#import "../../../node_modules/#fortawesome/fontawesome-free/scss/v4-shims";
in gulpfile.js
gulp.task('icons', function() {
return gulp.src('node_modules/#fortawesome/fontawesome-free/webfonts/*')
.pipe(gulp.dest(dist+'/assets/webfonts/'));
});
Something like this
// ------------ FONT-AWESOME --------------------//
$fa-font-path: $fonts_path + 'font-awesome';
#import
'../../node_modules/#fortawesome/fontawesome-free-webfonts/scss/fontawesome';
#import
'../../node_modules/#fortawesome/fontawesome-free-webfonts/scss/fa-brands';
#import
'../../node_modules/#fortawesome/fontawesome-free-webfonts/scss/fa-regular';
#import
'../../node_modules/#fortawesome/fontawesome-free-webfonts/scss/fa-solid';
To use an npm module on your front-end you'll need to be doing some sort of transpiling with webpack, gulp, or grunt most likely.
Then at the entry point of your application before you write html/jsx/some other html-esque code you'll need to require or import the css file from the font-awesome npm module.
// es6/babel import
import 'font-awesome/css/font-awesome.min.css';
// browserify require statement if not using babel/es6
require('font-awesome/css/font-awesome.min.css');
For example heres a react app I made with webpack/babel and on the entry point file I import the css file from font-awesome: https://github.com/AkyunaAkish/akyuna_akish/blob/master/client/index.js
FYI:
I used
npm install --save font-awesome
Instead of the command you used. You may need to adjust the import/require statement file path to point to the main css file in your font-awesome node_module package if we have slightly different packages.

How to import bootstrap 4 sass/scss from node_modules using gulp

I'm trying to #import some bootstrap 4 sass files from node_modules but my gulp watcher isn't picking up any changes to those node_modules bootstrap files.
In my main sass file I'm importing bootstrap via:
#import "bootstrap-grid";
#import "bootstrap-reboot";
#import "custom";
Then I also import some "local" sass files (outside of node_modules):
#import "some-file";
#import "some-other-file";
etc.
These local sass files are watched fine, I get recompilation when I do my edits/file save.
My sass gulp task looks like this:
//compile sass
gulp.task('sass', function() {
return gulp.src('src/css/scss/**/*.scss')
.pipe(sass({
includePaths: ['node_modules/bootstrap/scss/']
}))
.pipe(gulp.dest('src/css/'));
});
The key part for me to pick up the bootstrap files was to use the includePaths part.
I am getting the bootstrap grid and what I'm wanting to do is update the node_modules/bootstrap/scss/_custom.scss (which I'm importing) to place bootstrap overrides in.
I'm not quite sure how to get the bootstrap to recompile when I edit/save any node_modules bootstrap files.
I tried updating the includePaths to:
includePaths: ['node_modules/bootstrap/scss/**/*.scss']
But that throws an error, "file to import not found" (bootstrap-grid) which also seems odd to me because it seems like it should be adding/watching sass files (and any sub-directories) down in bootstrap/scss.
My file structure at this point is very simple:
root
|
| node_modules
| bootstrap
| scss
| src
| css
| scss
gulpfile.js
Try adding the sass files from the node_modules to gulp.watch:
gulp.watch([
'node_modules/bootstrap/scss/**/*.scss',
'src/css/scss/**/*.scss'
], ['sass']);
Hope that helps.

Gulp SASS Sourcemap sources are incorrect

I am struggling to get my SASS sourcemaps to work correctly. The problem seems to be the "sources" attribute within the sourcemap and how my SASS files are nested.
I have a Gulp task that compiles SASS to CSS. Here is an example of that
var paths = {
styles: {
src: './Stylesheets/SCSS/',
files: './Stylesheets/SCSS/**/*.scss',
dest: './Stylesheets/CSS/'
}
}
gulp.task('compile-sass', function (){
return gulp.src(paths.styles.files)
.pipe(sourcemaps.init())
.pipe(sass({
outputStyle: 'compressed',
includePaths : [paths.styles.src]
}))
.pipe(prefix({
browsers: ['last 2 Chrome versions'],
cascade: false
}))
.pipe(sourcemaps.write('../Maps/', {
includeContent: false,
sourceRoot: '../SCSS'
}))
.pipe(gulp.dest(paths.styles.dest));
});
The above works for everything else - writing maps to disk, prefixing etc. I am using latest nodejs, gulpjs and relevant npm packages.
An example of folder/asset structure from within my Stylesheets folder:
SCSS/print.scss
SCSS/sectionA/style.scss
SCSS/sectionA/partial/_partialA.scss
SCSS/sectionA/partial/_partialB.scss
SCSS/sectionB/... etc
For SASS files in the root of SCSS/ the sourcemaps work properly. Chrome will show where the source styles are.
For SASS files in a subfolder within SCSS/ the sourcemaps do not work. The problem is the "sources": attribute has the wrong file listed in it.
The print.scss map for example will correctly have "sources":["print.scss"]. But sectionA/style.scss map will have "sources":["style.css"] instead of "sources":["partial/_partialA.scss", "partial/_partialB.scss"] as I would expect.
I have confirmed moving /SCSS/sectionA/style.scss to /SCSS/style.scss and amending any import paths does solve the issue. But I need it to be nested, not in the root of /SCSS.
If I can provide more detail please let me know. I have tried the answer from Path to source map is wrong and it does not solve my issue. I have also tried manipulating mapSources with no avail.
# Update 2019-05-24
My answer talks about using CSSNext. CSSNext was deprecated. The theory in my answer is still applicable using postcss-preset-env.
# Update 2017-03-08
After experimenting with PostCSS, I have used CSSNext to process the CSS after SASS has converted it. CSSNext auto-prefixes and doing it this way retains the connection to the original scss files in the sourcemap.
See my GitHub repo for an example.
After following Mark's feedback and investigating the gulp-autoprefixer module I believe this issue raised on the GitHub repo for gulp-autoprefixer is related to the incorrect sourceroot problem.
Using a variation of the hack from ByScripts I am able to get sourcemaps with the correct sourceroot for nested scss files. The hack used in the ByScripts gulpfile inits the sourcemaps function twice. Once before prefixing, and once after.
I have created a GitHub repo to try and illustrate a reduced test case and a workaround. Inspecting the css produced by the workaround shows the correct relationship back to the source scss.

Use Gulp to copy all bower package font files to build directory

I am using the following Gulp task to copy required fonts from the Font Awesome Bower package, this works fine and outputs files like so:
App > Build > Fonts > Font Files
gulp.task('copyfonts', function() {
gulp.src('./bower_components/components-font-awesome/fonts/**/*.{ttf,woff,eof,svg}')
.pipe(gulp.dest('./fonts'));
});
I am trying to refactor this task so that it moves the fonts from any bower package (Bootstrap, for example) using the ** wildcard.
gulp.task('copyfonts', function() {
gulp.src('./bower_components/**/fonts/**/*.{ttf,woff,eof,svg}')
.pipe(gulp.dest('./fonts'));
});
App > Build > Fonts >
Bootstrap > Fonts > Font Files
Font-Awesome > Fonts > Font Files
TL;DR
Using my second method is copying the files as shown above, copying over the package folder and moving that with a 'fonts' folder as a child. Could anyone help show me where I have gone wrong...
I'm a little late to the party here, but for anyone that stumbles upon this in the future: I believe you have a typo in your font glob: eof should be eot.
gulp.src('./bower_components/**/fonts/**/*.{ttf,woff,eof,svg}')
should be
gulp.src('./bower_components/**/fonts/**/*.{ttf,woff,eot,svg}')
Not the best idea to always rely that a package will keep fonts in specific folders, those things can change.
Possibly you're missing another /**/ before fonts (one folder level). Or why all those checks, you know what extensions fonts will have, perhaps add wildcard like **/*.{ttf,woff,eof,svg}
Have you ever tried managing it with gulp-main-bower-files? https://github.com/ck86/main-bower-files
you can test this task
i worked by it
gulp.task('copyfonts', () =>
gulp.src('./app/assets/fonts/*')
.pipe(gulp.dest('./dist/assets/fonts'))
);
I ran into this same issue. After running my gulp builds, my fonts never successfully copied to my dest/fonts folder. The issue was inside my gulp.js file on these lines:
function fonts() {
return src('app/fonts/**/*.{eot,svg,ttf,woff,woff2}')
.pipe($.if(!isProd, dest('.tmp/fonts'), dest('dist/fonts')));
};
After editing the last line, my fonts successfully copied over!
function fonts() {
return src('app/fonts/**/*.{eot,svg,ttf,woff,woff2}')
.pipe(dest('dist/fonts'));
};

Rails 4 sass application file doesn't read in css file imported

This is my application.css.sass :
#import "global.css.sass"
#import "bootstrap.css"
When I look at the source at my localhost application.css?body=1 I see this:
#import url(bootstrap.css);
#content-wrap {
width: 90%;
margin: 0 auto; }
So the global.css.sass contains this :
#content-wrap
width: 90%
margin: 0 auto
So that was imported appropriately, but not bootstrap.css file. And it works on the localhost because its on the file path locally. However in production my assets are on aws:
application-a0546f0315a891e8129e1f8e49eb7e45.css
When looking at source the content is the same as on my localhost, however there is not bootstrap on the path so that file is missing, and I wonder why isn't it all bundled in all one big application file, here are my assets related config.
Development :
config.assets.compress = false
config.assets.digest = false
Production :
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
What am I doing wrong here? Any help is appreciated
Update :
This is sample bit from my chrome console :
Request URL:http://my-bucket.s3.amazonaws.com/assets/bootstrap.css
Request Method:GET
Status Code:403 Forbidden
Have a look in the SCSS Documentation, that explains the #import function from SCSS.
#import takes a filename to import. By default, it looks for a Sass
file to import directly, but there are a few circumstances under which
it will compile to a CSS #import rule:
If the files extension is .css.
If the filename begins with http://.
If the filename is a url().
If the #import has any media queries
It's important to see the difference between the usge of #import rule from css and the #import given by SCSS.
When you write this in your scss file:
#import "somefile.css"
The file somefile.css will not be merged within your scss compiled file. SASS will just compile this to the css #import rule, causing a http request to look for somefile.css on your server.
You can either want this, and upload somefile.css to the server under the correct path, or you just rename somefile.css to somefile.scss and change the import to #import "somefile.scss". Like this SASS will merge somefile.scss to the compiled file.