Create-react-app: Sass: Adding Bootstrap with a Custom Theme

Created on 16 Jul 2017  路  8Comments  路  Source: facebook/create-react-app

Hi!

I started playing with React and I thought "Create React App" was the right Kit. I wasn't wrong because the kit is really good and well documented. Simple and efficient!

But there is one thing that I really miss: sass integration within the project for bootstrap stylesheets.

Now, I understand the reasons why sass is not integrated: in theory we might use composition and perfectly encapsulate all the components. But the way you suggest to customize a bootstrap theme is really inconvenient.

I mean, don't get me wrong but creating an npm package for changing bootstrap sass-variables doesn't fit in the normal workflow development of a demo / application. Say my designer wants to change the primary color just to see how bootstrap-components look like: I think it should be one line of code (on the fly), not a new package.

I know I might use npm-link to speed up the workflow... But I feel it is really not the case.

So I wonder: is there any plan to integrate sass? I think the angular-cli approach (a parameter --style) would be perfect.

Composition is great, but sass is a standard de facto for many popular libs.

My 2 cents,
Maurizio

Most helpful comment

This is the approach I took to be able to control the customization of Bootstrap by overwriting the bootstrap sass variables.

[Edit] These instructions are for Bootstrap 3. For Bootstrap 4, see below.

Summary

  1. Install and copy the assets from bootstrap-sass into src/bootstrap
  2. In App.scss, import your own _variables.scss or just overwrite certain variables, set $icon-font-path: 'bootstrap/fonts/bootstrap/'; then import bootstrap with @import 'bootstrap/stylesheets/_bootstrap.scss';

Detailed steps

Per the SASS preprocessor instructions here.
npm install --save node-sass-chokidar

Now you can rename src/App.css to src/App.scss

Add sass version of bootstrap to control sass preprocessing to customize your theme.
npm install --save bootstrap-sass

Add cross-platform cp ability to npm-script to copy boostrap assets to src/bootstrap.
npm install --save shx

   "scripts": {
+    "prebuild-css": "shx cp -R node_modules/bootstrap-sass/assets src/bootstrap",
+    "build-css": "node-sass-chokidar src/ -o src/",
+    "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test --env=jsdom",

Then in App.scss overwrite $icon-path-path to avoid this error:

Failed to compile.

./src/App.css
Module not found: You attempted to import ../fonts/bootstrap/glyphicons-halflings-regular.eot which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.

In App.scss

/* Bring in your custom variables */
@import '_variables.scss';

/* or just overwrite a variable */
$headings-color: #F00;

/* Set $icon-font-path from sass-loader issue #40, https://github.com/webpack-contrib/sass-loader/issues/40#issuecomment-70269553 */
$icon-font-path: 'bootstrap/fonts/bootstrap/';
@import 'bootstrap/stylesheets/_bootstrap.scss';

All 8 comments

I was able to get this working in our app which is based on create-react-app. Hopefully this is useful...

I found this to be helpful, but it requires you to eject: https://medium.com/@Connorelsea/using-sass-with-create-react-app-7125d6913760

We chose not to eject, which was nice because I could then upgrade react-scripts over time.
Instead of ejecting, I used npm-run-all. The one issue is that I can't add sass-loader, but I found this to be a reasonable alternative.

The general approach I took:

  • npm install --save-dev node-sass
  • npm install --save-dev npm-run-all
  • Add the following to package.json
    "build-css": "node-sass --precision 10 src/ -o src/ --include-path src/",
    "watch-css": "npm run build-css && node-sass --precision 10 src/ -o src/ --include-path src/ --watch --recursive",
  • Convert or add at least one sass or scss file.
  • Modify start and build scripts to build css:
    "start-react-scripts": "export NODE_PATH=src/ && react-scripts start",
    "start": "npm-run-all -p watch-css start-react-scripts",
    "build": "export NODE_PATH=src/ && npm run build-css && react-scripts build",
  • Bring in the sass files from bootstrap and import as appropriate.
  • Bring in Bootstrap Sass, etc...

This works well for us, giving live-reload, etc.
I tested this example on GitHub as a new create-react-app build. This is a minimal change to demonstrate bootstrap sass integration.
Hopefully this helps as an alternative.

Ideally, of course, we'd be able to modify webpack config and bring in sass-loader, etc. This would allow better sass integration.

Integrating sass-loader and CSS Modules together would be the best way to work with .scss files and also customizing Bootstrap SASS

@jazeee thank you very much for sharing your experience (and sorry for the huge delay in answering you!).

Well, I thought about the approach you propose, but I'm still not 100% I like it: you end up having double the files with potential issues related to imports (say by mistake you import the *.sass instead of .css). But, there is no other way...

In the end, I think I will (sadly)

  • eject and modify the webpack.config files
  • or fork react-scripts following 682.

I would also like to have typescript / css-modules / ... Something like d3-starter-kit, a simple project I setup some days ago.

I hope they will improve the situation very soon. Right now you cannot use it (as it is) for a real project!

This is the approach I took to be able to control the customization of Bootstrap by overwriting the bootstrap sass variables.

[Edit] These instructions are for Bootstrap 3. For Bootstrap 4, see below.

Summary

  1. Install and copy the assets from bootstrap-sass into src/bootstrap
  2. In App.scss, import your own _variables.scss or just overwrite certain variables, set $icon-font-path: 'bootstrap/fonts/bootstrap/'; then import bootstrap with @import 'bootstrap/stylesheets/_bootstrap.scss';

Detailed steps

Per the SASS preprocessor instructions here.
npm install --save node-sass-chokidar

Now you can rename src/App.css to src/App.scss

Add sass version of bootstrap to control sass preprocessing to customize your theme.
npm install --save bootstrap-sass

Add cross-platform cp ability to npm-script to copy boostrap assets to src/bootstrap.
npm install --save shx

   "scripts": {
+    "prebuild-css": "shx cp -R node_modules/bootstrap-sass/assets src/bootstrap",
+    "build-css": "node-sass-chokidar src/ -o src/",
+    "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test --env=jsdom",

Then in App.scss overwrite $icon-path-path to avoid this error:

Failed to compile.

./src/App.css
Module not found: You attempted to import ../fonts/bootstrap/glyphicons-halflings-regular.eot which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.

In App.scss

/* Bring in your custom variables */
@import '_variables.scss';

/* or just overwrite a variable */
$headings-color: #F00;

/* Set $icon-font-path from sass-loader issue #40, https://github.com/webpack-contrib/sass-loader/issues/40#issuecomment-70269553 */
$icon-font-path: 'bootstrap/fonts/bootstrap/';
@import 'bootstrap/stylesheets/_bootstrap.scss';

@willhlaw when you mention "Install and copy the assets from bootstrap-sass" -- Which bootstrap-sass are you referencing? The bootstrap-sass here: https://github.com/twbs/bootstrap-sass -- it is still using Bootstrap 3 not Bootstrap 4. I'm trying to solve the same problem but with Bootstrap 4

@bhellman1, above instructions are for Bootstrap 3. Below works for 4.

This is the approach I took to be able to control the customization of Bootstrap 4 by overwriting the bootstrap sass variables.

Summary

  1. Install and copy the scss from [email protected] into src/bootstrap
  2. In App.scss, import your own _variables.scss or just overwrite certain variables, then import bootstrap with @import 'bootstrap/bootstrap.scss';

Detailed steps

Per the SASS preprocessor instructions here.
npm install --save node-sass-chokidar

Now you can rename src/App.css to src/App.scss

Add sass version of bootstrap to control sass preprocessing to customize your theme.
npm install --save [email protected]

Add cross-platform cp ability to npm-script to copy boostrap scss to src/bootstrap.
npm install --save shx

   "scripts": {
+    "prebuild-css": "shx cp -R node_modules/bootstrap/scss src/bootstrap",
+    "build-css": "node-sass-chokidar src/ -o src/",
+    "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test --env=jsdom",

Then in App.scss

/* Bring in your custom variables */
@import '_variables.scss';

/* or just overwrite a variable */
$headings-color: #F00;

@import 'bootstrap/bootstrap.scss';

Very good answer @willhlaw thanks a lot. For this purpose, it's clearly better than use npm eject

Closing in favor of https://github.com/facebookincubator/create-react-app/issues/2498 since that's a subset of "supporting Sass". Thanks for sharing your solutions!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fson picture fson  路  3Comments

xgqfrms-GitHub picture xgqfrms-GitHub  路  3Comments

JimmyLv picture JimmyLv  路  3Comments

jnachtigall picture jnachtigall  路  3Comments

stopachka picture stopachka  路  3Comments