I've downloaded an angular starter and I'm trying to install Bootstrap on it. They explain how to do that in the External Stylesheet section.
I've installed bootstrap:
npm i bootstrap --save
npm i bootstrap-sass --save
and then added in the top of styles.scss:
#import 'bootstrap/scss/bootstrap.scss';
But it's marked with red mentions:
Cannot resolve directory 'bootstrap'
Any help will be profoundly appreciated!
As previously mentioned, you need to add the tilde when you're importing inside your css.
#import 'bootstrap/scss/bootstrap.scss';
Second, the bootstrap css file is loading fonts along with the stylesheet, resulting in the error you're having because it's using relatives paths webpack doesn't know where to pickup.
To fix that, you could either change the path of the folder to the correct one like the following as seen from here:
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap";
#import "~bootstrap-sass/assets/stylesheets/bootstrap";
And add the fonts loader to your webpack configuration:
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'url-loader',
}
But the easiest way for you to get around the problem would be to remove the style import you are doing, remove the bootstrap-sass dependency and use the cdn instead.
#import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');
The advantage of doing this is that clients that have already downloaded bootstrap using this cdn will get the cached version. Since a lot of websites theses days use it, It's very likely they won't have to download it again, and it also saves you the trouble of hosting it or incorporating into your bundle.
Nothing exists at src/styles/bootstrap/scss/bootstrap.scss, so you can either manually copy/paste (or download) a bootstrap.scss file there OR just import bootstrap into your src/styles/styles.scss from your node_modules via:
#import "~bootstrap-sass/assets/stylesheets/bootstrap";
You'll get font-related errors until you add in a line before that so your styles.scss reads:
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
#import "~bootstrap-sass/assets/stylesheets/bootstrap";
More: https://stackoverflow.com/a/35575175/3814251
In order to let sass-loader import a sass module from mode_modules folder, prepend the module path with a ~. Otherwise the provided path is resolved like a relative one:
#import "~bootstrap/scss/bootstrap.scss";
For more info check out sass-loader docs.
Related
I want to add fontawesome 5 to my angular-cli 8.0.2 project (with scss) by copy fonts to project (not link them from internet) and without using any external plugins/projects but in direct way.
So I create project and install fontawesome (free) via npm as follows
ng n --style=scss --routing=true myproject
cd myproject
npm install --save-dev #fortawesome/fontawesome-free
I modify files:
In angular.json in key projects.myproject.architect.build.options.styles I add following value to array
"./node_modules/#fortawesome/fontawesome-free/scss/fontawesome.scss"
In styles.scss I add line:
#import "../node_modules/#fortawesome/fontawesome-free/scss/fontawesome.scss";
In src/app/app.component.html after Wellcome text I add
<i class="fas fa-sync-alt"></i>
Then I run command ng serve and go in browser to http://localhost:4200/ and see this:
I use different instructions from internet but this is best result that I get - but still doesn't work (we see square instead this icon). What to do to fix this problem?
Font Awesome now provides Font Awesome Angular component, but you can also use the following plain approach:
npm install --save #fortawesome/fontawesome-free
Load Font Awesome icons by just simply adding the following into styles.scss:
$fa-font-path: '~#fortawesome/fontawesome-free/webfonts';
#import "~#fortawesome/fontawesome-free/scss/fontawesome.scss";
#import "~#fortawesome/fontawesome-free/scss/solid.scss";
#import "~#fortawesome/fontawesome-free/scss/brands.scss";
Tested on Angular v8.2.14 and Angular CLI v8.3.19.
EDIT: The reason why the icons don't display is that you didn't specify the type of icon style. You can find a list of supported icon styles here (or listed below):
brands.scss
solid.scss
regular.scss
light.scss
Original answer
The SCSS file that FontAwesome includes in its NPM package does not set itself up for you: you're supposed to import the individual SCSS files yourself. (See the docs on the SCSS part for more info)
Instead, you should include the already compiled CSS so that you don't have to import the SCSS files manually. (Run the command below to set the style)
ng config projects.myproject.architect.build.options.styles "./node_modules/#fortawesome/fontawesome-free/css/all.css"
(Or manually add "./node_modules/#fortawesome/fontawesome-free/css/all.css" to your project's styles)
For more info on what FontAwesome includes in its package, refer to the docs.
I install icons css using npm install material-design-icons-iconfont and it is available in node modules. After i build, the below woff files available in dist
Material-design-icons.css
/* For IE6-8 */
src: local("Material Icons"), local("MaterialIcons-Regular"),
url("./fonts/MaterialIcons-Regular.woff2") format("woff2"),
url("./fonts/MaterialIcons-Regular.woff") format("woff"),
url("./fonts/MaterialIcons-Regular.ttf") format("truetype");
all the three woff files shows 404. I verified in dist folder, i can see all those files in static/fonts/.woff.
In browser console also `localhost:8000/static/fonts/.woff. All the file names and paths are correct, but still see 404 error in console.
Afetr NPM installation, why not follow the Vuetify documentation by importing it in your main.js or app.js file.
// main.js
import 'material-design-icons-iconfont/dist/material-design-icons.css'
// Ensure you are using css-loader
Vue.use(Vuetify, {
iconfont: 'md'
})
But the easiest way is just to include the CDN link:
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet">
There are multiple material icon packages flying around. There are also multiple formats, SVGs and what not. It is easy to get confused. Assuming you have a standard vuetify configuration and your goal is to have a locally installed font because you don't like injecting foreign substance to your head, then following should work:
Eliminate the external library
First edit your public/index.html and comment out the #mdi import. This line also gives us a clue to which package vuetify is expecting.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/#mdi/font#latest/css/materialdesignicons.min.css">
Install your local dependency
Then in your project folder, install the #mdi / font package.
yarn add #mdi/font
Import into Vue
Then, finally we need to get this newly download package into our application. You can import anywhere, but it's good practice to keep vuetify related things in the vuetify configuration file which is located at plugins/vuetify.js
import "#mdi/font/css/materialdesignicons.min.css";
Let Vuetify know all about it
and make sure to export material design as the preferred icon font for your vuetify project.
Inside plugins/vuetify.js
export default new Vuetify({
icons: {
iconFont: "md",
},
});
You might want need to rebuild your project. Have a great day.
P.S # points to your node_modules folder.
Have you checked you have css-loader in you webpack config?
module: {
loaders: [
{ test: /\.css$/, loader: "css-loader" }
]
}
I am facing a problem in Webpack regarding Relative Path.
Let me try to explain the scenario :
I have 2 separate project in Workspace directory :
Project-A [Bundling using Gulp] : Stable & Working
Project-B [Bundling using Webpack] : New project
As both the projects are using same Styling, so I wanted to reuse the SCSS files [consisting of standard variables, predefined layouts, modals, classes etc] of Project A into Project B.
Now, if I am trying to import Project-A index.scss in Project-B index.scss as another partial [Commenting out the Background Image URL Depency], webpack is able to generate the required CSS output file.
// Import Project A SCSS [Common Varibles, Classes, Styling etc]
#import "../../../../Project_A/assets/stylesheets/index";
But as Project-A's index.scss is further referring background images from the respective Relative-Path, the webpack build is throwing error
'File / dir not found in XYZ/Project-B/Source/Stylesheets'.
Exact Error Block :
ERROR in ./src/assets/stylesheets/index.scss
Module build failed: ModuleNotFoundError: Module not found: Error: Cannot resolve 'file' or 'diWorkSpace\Project_B\src\assets\stylesheets
screenshot :
I am not able to understand, why Webpack is not able to resolve the Relative path of assets inside Project-A and still looking inside 'Project B'.
Here is the Code-Repo URL for the simulated issue :
https://github.com/raviroshan/webpack-build-issue/tree/master/WorkSpace
Steps to reproduce.
Download the Repo.
Browse inside Project_B folder, and do a NPM install.
Run 'webpack'. It would build correctly as Relative Image
URL code is commented out.
Now put back the commented line of code : https://github.com/raviroshan/webpack-build-issue/blob/master/WorkSpace/Project_A/assets/stylesheets/index.scss#L27
So, finally after so much struggle, got a proper SOLUTION.
It turns out to be an issue with CSS-loader i.e it is not able to resolve the URL with respective to current file.
Using resolve-url-loader solved this problem.
https://www.npmjs.com/package/resolve-url-loader
// Old Loader Config in Webpack-entry
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!sass-loader?sourceMap')
// New [Fixed] Loader Config in Webpack-entry
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!resolve-url-loader!sass-loader?sourceMap')
Here is updated Code-Repo with solution : https://github.com/raviroshan/webpack-build-issue
Note : Don't omit -loader
Your Webpack.config.js should always use the long-form of the loader name (i.e. the -loader suffix).
There is another package called resolve-url which Webpack can confuse with resolve-url-loader.
It seems like it's css-loader fault and the way it resolves paths in #import and url(). It tries to resolve all paths — even those from imported stylesheets — relative to the main CSS file — which in your case is /Project_B/src/assets/stylesheets/index.scss.
Don't cry! There's a solution!
Maybe it's not perfect, but it's the best one I came with so far.
Create a global variable $assetsPath holding a path to assets relative to the current stylesheet. Then prepend this variable to all your url() values.
In your /Project_A/assets/stylesheets/index.scss you'd write:
/*/ Using !default we can override this variable even before the following line: /*/
$assetsPath: '../' !default;
.container {
/*/ ... /*/
.content-wrapper {
/*/ ... /*/
background-image: url($assetsPath + "images/content-bg.jpg");
}
}
In your /Project_B/src/assets/stylesheets/index.scss you'd write:
/*/ The following variable will override $assetsPath defined in the imported file: /*/
$assetsPath: '../../../../Project_A/assets/';
/*/ Import Project A SCSS [Common Varibles, Classes, Styling etc] /*/
#import "../../../../Project_A/assets/stylesheets/index";
The Aftermath
If you bundle Project-A with Gulp it's gonna see Project-A's code as:
/*/ ... /*/
background-image: url("../images/content-bg.jpg");
Although, when you bundle Project-B with Webpack it's gonna see Project-A's code as:
/*/ ... /*/
background-image: url("../../../../Project_A/assets/images/content-bg.jpg");
Therefore, you are saved.
Most definitely I'll look closer at this issue. All of this could be avoided if url-loader would respect a path in the #import statement and apply it to referenced assets accordingly. Either I'm missing something or it should be considered as a bug.
I hope you have a wonderful day!
~Wiktor
you need to set the publicPath as a relative path to get the relative path in file-loader.
I am working on an angular-cli project. I am using SCSS and they're getting compiled and I can observe the changes of them.
styles.css and app.component.scss in the root path are neither getting compiled nor can observe the changes.
Here it's the root folder structure. style.css is compiled to the root structure (This is done in angular-cli.json)
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"../node_modules/mdi/css/materialdesignicons.min.css",
"../node_modules/roboto-fontface/css/roboto/roboto-fontface.css",
"../node_modules/font-awesome/css/font-awesome.min.css",
"../node_modules/tinymce/skins/lightgray/skin.min.css",
"styles.css"
]
You cannot see the style.css because, it's hidden using vscode settings.
What is wrong here and how can i get the changes applied here?
What version of angular cli are you using?
I was using 1.0.0-beta.22-1 and styles.css was not properly being bundled in the prod build. Downgraded to 1.0.0-beta.19-3 and it works again. Seems to be a bug in the later cli project.
Managed to solve this.
The problem I encountered was because of initially when my project was created the default extension for styles was CSS and it has been changed by the time since styling with SCSS is much prettier.
So, the issue was the previous configuration in angular-cli.json. when the compilation happens, it doesn't detect the change in the SCSS file, but its search for a CSS
This was the answer helped me to understand the mistake - Angular2 - Angular-CLI SASS options
PS - It's where I went on the mistake.
It's there a way to use Grunt for injecting a new line like #import "my-custom-reset-for-bootstrap.less" in the end of bootstrap.less. Or other ideea how can I inject my less file from outside of bootstrap package. I want to do this to keep in original state the bootstrap package.
Thank you!
If I were you I would leave the Bootstrap file as it is and import it into your custom style file instead. The main advantage of this solution is that you can use variables, mixins and actually everything from the original Bootstrap less file in your custom style definitions.
my-custom-reset-for-bootstrap
#import "bootstrap.less";
.my-custom-class {
color: #gray-light; //var from Bootstrap variable.less file
}
In this case you won't need to do anything after upgrading Bootstrap files to newer version.