Burnee Burnee - 1 month ago 40
TypeScript Question

How to import CSS from node_modules in webpack angular2 app

Lets say that we start with the following starter pack:
https://github.com/angularclass/angular2-webpack-starter

After

npm install
and
npm run start
everything works fine.

I want to add an external css module, for example bootstrap 4's css (and only the css). (I know that bootstrap has a bootstrap-loader, but now I'm asking for general solution, so please think about bootstrap 4 here as it could be any other css module that is available via npm).

I install bootstrap via npm:
npm install bootstrap@4.0.0-alpha.4 --save


First I thought that it is enough to add
import 'bootstrap/dist/css/bootstrap.css';
to the vendor.ts file.

But it isn't.

What should I do to have a proper solution?

Solutions I'm NOT asking for:


  1. "Copy the external css module to the assets folder, and use it from there"


    • I'm looking for a solution that works together with npm package.


  2. "Use bootstrap-loader for webpack"


    • As I described above, I'm looking for a general solution, bootstrap is only an example here.


  3. "Use another stack"


    • I'm looking for a solution in the exact starter pack that I've mentioned above.




Thx in advance!

Answer

You won't be able to import any css to your vendors file using that stack, without making some changes.

Why? Well because this line:

import 'bootstrap/dist/css/bootstrap.css';

It's only importing your css as string, when in reality what you want is your vendor css in a style tag. If you check config/webpack.commons.js you will find this rule:

 {
   test: /\.css$/,
   loaders: ['to-string-loader', 'css-loader']
 },

This rule allows your components to import the css files, basically this:

@Component({
  selector: 'app',
  encapsulation: ViewEncapsulation.None,
  styleUrls: [
    './app.component.css' // this why you import css as string
  ],

In the AppComponent there's no encapsulation, because of this line encapsulation: ViewEncapsulation.None, which means any css rules will be applied globally to your app. So you can import the bootstrap styles in your app component:

@Component({
  selector: 'app',
  encapsulation: ViewEncapsulation.None,
  styleUrls: [
    './app.component.css',
    '../../node_modules/bootstrap/dist/css/bootstrap.css'
  ],

But if you insist in importing to your vendor.ts then you will need to install a new loader, npm i style-loader --save-dev this will allow webpack to inject css to your page. Then you need to create a specific rule, on your webpack.common.js and change the existing one:

 { //this rule will only be used for any vendors
   test: /\.css$/,
   loaders: ['style-loader', 'css-loader'],
   include: [/node_modules/]
 },
 {
   test: /\.css$/,
   loaders: ['to-string-loader', 'css-loader'],
   exclude: [/node_modules/] //add this line so we ignore css coming from node_modules
 },

The firs rule will be only applied when you try to import css, from any package inside node_modules the second rule will be applied to any css that you import from outside the node_modules

Comments