Reputation: 818
My Situation:
While developing an Angular 4 application, I wanted to make use of angular material. Since they only offer a few themes I had the need to create a custom theme. Their docs explain that in order to override the default theme you should create an scss file, so that's what I did. However, since my project didn't make use of scss files before, I had to adjust my webpack configuration. I tried to import the scss file on different places like in the styleUrls of the app component, or just with an import, nothings seems to work. Angular material keeps using the default theme.
My Webpack base file:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
module.exports = {
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'app': './src/main.ts'
},
resolve: {
extensions: ['.js', '.ts'],
modules: [
path.join(__dirname, 'node_modules')
]
},
resolveLoader: {
modules: [
path.join(__dirname, 'node_modules')
]
},
module: {
loaders: [{
test: /\.ts$/,
loaders: ['ts-loader', 'angular2-template-loader']
}, {
test: /\.html$/,
loader: 'html-loader'
}, {
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[hash].[ext]'
}, {
test: /\.css$/,
exclude: path.join(__dirname, 'src', 'modules'),
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader?sourceMap' })
}, {
test: /\.css$/,
include: path.join(__dirname, 'src', 'modules'),
loader: 'raw-loader'
}, {
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['raw-loader', 'sass-loader']
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)@angular/,
path.join(__dirname, 'src')
),
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery'
})
]
};
The webpack development file:
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var baseConfig = require('./webpack.config.base.js');
var path = require('path');
module.exports = webpackMerge(baseConfig, {
devtool: 'cheap-module-eval-source-map',
output: {
path: path.join(__dirname, 'dist'),
publicPath: 'http://localhost:8080/',
filename: 'js/[name].js',
chunkFilename: 'js/[id].chunk.js'
},
plugins: [
new ExtractTextPlugin('css/[name].css')
],
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
});
The webpack production file:
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var baseConfig = require('./webpack.config.base.js');
var path = require('path');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = webpackMerge(baseConfig, {
devtool: 'source-map',
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: 'js/[name].[hash].js',
chunkFilename: 'js/[id].[hash].chunk.js'
},
htmlLoader: {
minimize: false // workaround for ng2
},
plugins: [
new webpack.NoErrorsPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin('css/[name].[hash].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
})
]
});
The scss file in which I define my cusotm Angular Material theme:
@import '~@angular/material/theming';
@include mat-core();
$my-app-primary: mat-palette($mat-blue-grey);
$my-app-accent: mat-palette($mat-orange, 300);
$my-app-warn: mat-palette($mat-red, 600);
$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn);
@include angular-material-theme($my-app-theme);
How I am currently trying to import the scss file in my component's decorator:
@Component({
selector: 'app-property-detail',
templateUrl: './property.detail.component.html',
styleUrls: ['./property.detail.component.css', '../../assets/css/ngMaterialTheme.scss']
})
I already did some research before posting this question.
What I found but didn't help:
Any help would be greatly appreciated!
Edit:
I have a general styles.css file that gets imported in the app module. I tried to import the scss file over there:
@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
@import './ngMaterialTheme.scss';
However, I then get a webpack error saying:
./~/css-loader?sourceMap!./src/assets/css/ngMaterialTheme.scss Module not found: Error: Can't resolve '@angular/material/theming' in ...
I figured this might be useful because they advise this in:
Upvotes: 2
Views: 3855
Reputation: 1517
For Webpack 5 (and above?)
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.scss$/, use: 'scss-loader' } //etc.
]
}
Upvotes: 0
Reputation: 818
I have solved my issue by replacing
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['raw-loader', 'sass-loader']
}
with:
{
test: /\.scss$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "sass-loader" }
]
}
I now import both the styles.css and the scss file in the app module:
import '../../assets/css/styles.css';
import '../../assets/css/ngMaterialTheme.scss';
Upvotes: 1