Responsive Design has been the biggest driving factor for SharePoint framework (SPFx) solutions. In a recent SPFx project for a customer, we developed a component using React, Bootstrap and Font-awesome icons for a responsive look and feel. While building the UI piece, we encountered many issues during the initial set up, so I am writing this blog with detail steps for future reference. One of the key fixes mentioned in this post, is for the WOFF2 font-type file which is a component in font-awesome and bootstrap.
In this blog post, I will not be detailing the technical implementation (business logic and functionality) just focusing on the UI implementation. The following steps outline how to configure SPFx React client side web parts to use Bootstrap and Font-awesome CSS styles
Steps:
- Create a SharePoint Framework project using Yeoman. Refer this link from Microsoft docs for reference.
- Next, install JQuery, Bootstrap and Font-awesome using npm so that it can be available from within node_modules
npm install jquery --save npm install @types/jquery --save-dev npm install bootstrap --save npm install @types/bootstrap --save-dev npm install jquery --save npm install @types/jquery --save-dev
Check the node_modules folder to make sure they got installed successfully
- Now locate config.json file in config folder and add the entry below for third party JS library references.
"externals": { "jquery": { "path": "node_modules/jquery/dist/jquery.min.js", "globalName": "jQuery" }, "bootstrap": { "path": "node_modules/bootstrap/dist/js/bootstrap.min.js", "globalName": "bootstrap" }
Then reference them in the .ts file in the src folder using import
import * as jQuery from "jquery"; import * as bootstrap from "bootstrap";
- For CSS reference, we can either refer to the public CDN links using SPComponentloader.loadCss() or else refer to the local version as below in the .tsx file
Note: Don’t use ‘require’ for js scripts as they are already imported in above step. If included again it will cause a component load error.require('../../../../node_modules/bootstrap/dist/css/bootstrap.css'); require('../../../../node_modules/bootstrap/dist/css/bootstrap.min.css'); require('../../../../node_modules/bootstrap/dist/css/bootstrap-theme.css'); require('../../../../node_modules/bootstrap/dist/css/bootstrap-theme.min.css'); require('../../../../node_modules/font-awesome/css/font-awesome.css'); require('../../../../node_modules/font-awesome/css/font-awesome.min.css');
- When using React, copy the html to the .tsx file in the components folder. If you want to use the HTML CSS classes as-is and not the SASS way, refer to this blog post. For image references, here is a good post to refer.
For anyone new to React as me, few tips below for styling:
1. Use className instead of HTML class attribute
2. In order to use inline styles, use style={{style attributes}} or define an object, since everything in JSX are elements - When ready, use gulp serve to launch your solution in local workbench.
Important: If you’re using custom icons or fonts from the above CSS libraries, you will receive Typescript errors saying that loader module was not found for WOFF2 font type. Here, you will need to push the custom loader for WOFF2 font type through gulpfile.js as below.First install url-loader from npm.npm install url-loader --save-dev
Then modify gulpfile.js at the root directory to load the custom loader.
build.configureWebpack.mergeConfig({ additionalConfiguration: (generatedConfiguration) => { generatedConfiguration.module.loaders.push([ { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader', query: { limit: 10000, mimetype: 'application/font-woff2'} } ]); return generatedConfiguration; } });
Now gulp serve your solution and it should work fine.
You might still face CSS issues in the solution as the referring CSS doesn’t exactly match the HTML-CSS implementation. To resolve any conflicts, use CSS Override (!important) wherever necessary.
In this post I have shown how we can configure bootstrap and font-awesome third party CSS files to work with SharePoint Framework solutions while leveraging React Framework.
Hi Asish,
I am facing issue with loaders.push() method.
[10:13:26] Starting subtask ‘configure-webpack’…
[10:13:28] Error – [configure-webpack] TypeError: Cannot read property ‘push’ of
undefined
[10:13:28] Error – ‘configure-webpack’ sub task errored after 1.92 s
Cannot read property ‘push’ of undefined
[10:13:28] ‘serve’ errored after 17 s
[10:13:28]
here my gulpfile.js code
‘use strict’;
const gulp = require(‘gulp’);
const build = require(‘@microsoft/sp-build-web’);
build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) => {
generatedConfiguration.module.loaders.push([
{ test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: ‘url-loader’, query: { limit: 10000, mimetype: ‘application/font-woff2’} }
]);
}
});
build.initialize(gulp);
Can you please provide me solution ASAP
Seems like a build issue. Try the below steps and let me know how it went.
1. If not already, install url-loader from npm (code above). Make sure it is available under node_modules and entry in package.json (dev-dependencies section)
2. Return the generatedConfiguration in the above method at the end so it returns the added definition
3. Use gulp clean, to remove any odd dependencies from prior builds
If none of the above works, please gulp serve –verbose to see if it is failing to find something.
1. I have already installed url-loader and its available under node_modules
2. return generatedConfiguration is there in my code. and tested with proper code but still getting the 10:13:28] Error – [configure-webpack] TypeError: Cannot read property ‘push’ of
undefined
[10:13:28] Error – ‘configure-webpack’ sub task errored after 1.92 s
Cannot read property ‘push’ of undefined error
3. Done gulp clean
4. used gulp serve -verbose but got the below error
D:\Ravinder\Dev\SPFx\TestWebpart>gulp serve -verbose
Build target: DEBUG
[07:40:58] Using gulpfile D:\Ravinder\Dev\SPFx\TestWebpart\gulpfile.js
[07:40:58] Task ‘-verbose’ is not in your gulpfile
[07:40:58] Please check the documentation for proper gulpfile formatting
[07:40:58] Task ‘-verbose’ is not in your gulpfile
[07:40:58] Please check the documentation for proper gulpfile formatting
About to exit with code: 1
Process terminated before summary could be written, possible error in async code
not continuing!
Trying to exit with exit code 1
Can you please help me on this issue
Hi Ravinder,
Quickly on the code, I suppose it is gulp serve –verbose (double hyphen). Please try that because the error seems to say like wrong syntax “-verbose”. If it works, then please go through the output text and it might give inputs on your code such as below. Also, there might be something wrong with your gulp release. could you uninstall and install it again. Next, use “npm outdated” to see if there are old versions of file.
Refer here to see how to update outdated packages in SPFx – https://github.com/SharePoint/sp-dev-docs/blob/master/docs/spfx/update-latest-packages.md
Build target: DEBUG
Found config file: config.json
Found config file: tslint.json
Found config file: copy-assets.json
Found config file: write-manifests.json
Found config file: serve.json
Found config file: deploy-azure-storage.json
Found config file: package-solution.json
[09:06:31] Using gulpfile **Removed by Asish*\gulpfile.js
[09:06:31] Starting gulp
[09:06:31] Starting ‘serve’…
[09:06:31] Starting subtask ‘pre-copy’…
[09:06:31] Finished subtask ‘pre-copy’ after 379 ms
[09:06:31] Starting subtask ‘copy-static-assets’…
[09:06:32] Starting subtask ‘sass’…
[09:07:00] Warning – [sass] ** removed by Asish ** : filename should end with module.scss
[09:07:00] Finished subtask ‘sass’ after 28 s
[09:07:00] Starting subtask ‘tslint’…
[09:07:00] Starting subtask ‘typescript’…
[09:07:00] [typescript] TypeScript version: 2.1.6
[09:07:00] [tslint] ** removed by Asish **.ts
[09:07:01] Warning – tslint – ** removed by Asish **.ts(9,10): error no-unused-imports: unused import: ‘SPComponentLoader’
Try below
build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) => {
generatedConfiguration.module.rules.push(
{
test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: ‘url-loader’,
query: { limit: 10000, mimetype: ‘application/font-woff2’}
}
);
return generatedConfiguration;
}
});
Hi Ashish,
For your info i am using gulp tool and gulp serve –nobrowser commands to run thecode but still getting the push undefined error and as per you suggestion
i used gulp serve –verbose and getting the same error like below
[07:59:44] Starting subtask ‘configure-webpack’…
[07:59:46] Error – [configure-webpack] TypeError: Cannot read property ‘push’ of
undefined
[07:59:46] Error – ‘configure-webpack’ sub task errored after 1.45 s
Cannot read property ‘push’ of undefined
[07:59:46] ‘serve’ errored after 7.18 s
Please help me out issue
Hi Ravinder,
Sorry for a late reply.. I am still trying to replicate the issue so don’t have a concrete fix yet. From the details above it seems some problem with the webpack loader component in sp-build-web build configuration. In the meantime, please review the documentation and hopefully there is something specific to this.
https://dev.office.com/sharepoint/docs/spfx/toolchain/extending-webpack-in-build-pipeline
https://webpack.github.io/docs/loaders.html
The following link shows how to fix this issue:
https://github.com/SharePoint/sp-dev-docs/issues/927
Basically change:
generatedConfiguration.module.loaders.push
to:
generatedConfiguration.module.rules.push
It has to do with a change made between Webpack V1 and V2