Loading stylesheets in reverse order
Amos47 opened this issue · 2 comments
I am trying to configure webpack, but there seems to be an issue with the loading order.
I have some global styles and the component styles.
When I run the app with ng serve
the component styles load after the global files, allowing them to overwrite the global styles.
When I run with angular-ssr
though my webpack config, it loads the global styles.scss
after loading the application. I can't change the order because style-loader
requires that the window
be defined.
I understand this may be more of a webpack issue, but I'm hoping there's a known workaround for this issue so I can keep a consistent order for loading styles.
angular-cli.json
{
"project": {
"version": "1.1.1",
"name": "Project"
},
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"server/favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.scss"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"production": "environments/environment.production.ts",
"stage": "environments/environment.stage.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {
"inlineTemplate": false,
"spec": true
}
}
}
webpack-server.config.js
const {join, resolve} = require('path');
const loaders = require('./webpack/loaders');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const webpack = require('webpack');
var appTarget = process.env.NODE_ENV || 'dev';
module.exports = {
target: 'node',
entry: {
server: ['./src/server/index.ts', './src/styles.scss'],
},
output: {
filename: 'index.js',
path: resolve(join(__dirname, 'dist-server')),
libraryTarget: 'commonjs2',
},
resolve: {
extensions: ['.ts', '.js', '.json', 'scss', 'html'], //, 'ico', 'scss', 'html'],
},
module: {
rules: [
loaders.tsjit,
loaders.html,
loaders.scss,
loaders.globalScss
]
},
plugins: [
new webpack.NormalModuleReplacementPlugin(/(.*)environments\/environment(\.*)/, function(resource) {
if(appTarget !== 'dev'){
if (resource.request.indexOf(`environment.${appTarget}`) === -1) {
resource.request = resource.request.replace(/environments\/environment/, join('environments', `environment.${appTarget}`));
}
}
}),
new HtmlWebpackPlugin({
favicon: './src/server/favicon.ico'
})
],
externals: [
'@angular/animations',
'@angular/cli',
'@angular/common',
'@angular/compiler',
'@angular/compiler-cli',
'@angular/core',
'@angular/forms',
'@angular/http',
'@angular/platform-browser',
'@angular/router',
'@angular/tsc-wrapped',
'@angular/service-worker',
'angular-ssr',
'express',
function(context, request, callback) {
const exclusions = [/\@ngrx/, /rxjs/, /zone\.js/, /reflect-metadata/];
if (exclusions.some(expr => expr.test(request))) {
callback(null, `commonjs ${request.replace(/^.*?(\\|\/)node_modules(\\|\/)/, String())}`);
}
else {
callback();
}
},
],
node: {
process: true,
__dirname: true,
__filename: true
}
};
webpack.config.js
const {join, resolve} = require('path');
const loaders = require('./webpack/loaders');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
var appTarget = process.env.NODE_ENV || 'dev';
module.exports = {
entry: {
client: ['./src/index.html', './src/styles.scss', './src/polyfills.ts', './src/main.ts']
},
output: {
filename: 'app.js',
path: resolve(join(__dirname, 'dist')),
publicPath: '/',
},
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js', '.json', '.scss', 'html'],
},
externals: [
],
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
inject: 'body',
}),
new webpack.NormalModuleReplacementPlugin(/(.*)environments\/environment(\.*)/, function(resource) {
if(appTarget !== 'dev'){
if (resource.request.indexOf(`environment.${appTarget}`) === -1) {
resource.request = resource.request.replace(/environments\/environment/, join('environments', `environment.${appTarget}`));
}
}
})
],
module: {
rules: [
loaders.tsjit,
loaders.html,
loaders.scss,
loaders.globalScss
]
}
};
I also tried running ng eject
which created a new webpack from angular cli.
I then copied it over to the the webpack-server.config.js
and changed the entry point with the same result. Running just the front end works.
I'm hoping this isn't an unfixable issue. Having different style loading order in dev setup and our production setup is going to be an issue.
Starting to feel like I'm talking to myself...
I found a solution though. I ran ng eject
on a separate branch to create the webpack.config.js
file and used that one instead of the one listed in the issue. webpack-server.config.js
was left the same.
Thanks for the project... This process should be listed in the guide or example IMHO. Would have saved me a couple days of frustration.