0
votes

I am having trouble trying to load a primeng theme via scss (ultimately so I can customize it). I was able to do this for bootstrap but primeng is not working. There are currently no errors in webpack and its output log reports the emitted font files but the styles are not being applied on the controls

My initial problem was loading the fonts located in primeng\resources\themes\omega\fonts. I got past that using the resolve-url-loader, the sourceMap parameter in sass-loader as well as the url-loader and file-loader to emit the font files (as per some solutions I found online). I also put in the exclude in the /.(png|jpg|jpeg|gif|svg)$/ test to make sure it skips the fonts directory.

Here is what I have so far:

styles.scss

//bootstrap
@import "~bootstrap/scss/bootstrap";

//primeng
@import "~primeng/resources/themes/omega/theme.scss";
@import "~primeng/resources/themes/_theme.scss";

boot.browser.ts (entry point for webpack. Path is good cause the bootstrap import is working)

...
import './assets/scss/styles.scss';
...

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const AotPlugin = require('@ngtools/webpack').AotPlugin;
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;

module.exports = (env) => {
    // Configuration in common to both client-side and server-side bundles
    const isDevBuild = !(env && env.prod);
    const sharedConfig = {
        stats: { modules: false },
        context: __dirname,
        resolve: { extensions: ['.js', '.ts'] },
        output: {
            filename: '[name].js',
            publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
        },
        module: {
            rules: [
                { test: /\.ts$/, include: /ClientApp/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] : '@ngtools/webpack' },
                { test: /\.html$/, use: 'html-loader?minimize=false' },
                { test: /\.css$/, use: ['to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize'] },
                { test: /\.(png|jpg|jpeg|gif|svg)$/, exclude: [/fonts/], use: 'url-loader?limit=25000' },
                {
                    test: /\.(scss)$/,
                    use: [{
                        loader: 'style-loader', // inject CSS to page
                    }, {
                        loader: 'css-loader', // translates CSS into CommonJS modules
                    }, {
                        loader: 'postcss-loader', // Run post css actions
                        options: {
                            plugins: function () { // post css plugins, can be exported to postcss.config.js
                                return [
                                    require('precss'),
                                    require('autoprefixer')
                                ];
                            }
                        }
                    }, {
                        loader: 'resolve-url-loader', //handles url pathing in scss
                    }, {
                        loader: 'sass-loader?sourceMap' // compiles SASS to CSS
                    }]
                },
                {
                    test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    use: 'url-loader?limit=10000&mimetype=application/font-woff'
                },
                {
                    test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    use: 'file-loader'
                }
            ]
        },
        plugins: [new CheckerPlugin()]
    };

    // Configuration for client-side bundle suitable for running in browsers
    const clientBundleOutputDir = './wwwroot/dist';
    const clientBundleConfig = merge(sharedConfig, {
        entry: { 'main-client': './ClientApp/boot.browser.ts' },
        output: { path: path.join(__dirname, clientBundleOutputDir) },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./wwwroot/dist/vendor-manifest.json')
            }),
            new webpack.ProvidePlugin({
                $: 'jquery',
                jQuery: 'jquery',
                'window.jQuery': 'jquery',
                Popper: ['popper.js', 'default']
                // In case you imported plugins individually, you must also require them here:
                //Util: "exports-loader?Util!bootstrap/js/dist/util",
                //Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown"
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new webpack.SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
            })
        ] : [
                // Plugins that apply in production builds only
                new webpack.optimize.UglifyJsPlugin(),
                new AotPlugin({
                    tsConfigPath: './tsconfig.json',
                    entryModule: path.join(__dirname, 'ClientApp/app/app-browser.module#AppModule'),
                    exclude: ['./**/*.server.ts']
                })
            ])
    });

    // Configuration for server-side (prerendering) bundle suitable for running in Node
    const serverBundleConfig = merge(sharedConfig, {
        resolve: { mainFields: ['main'] },
        entry: { 'main-server': './ClientApp/boot.server.ts' },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./ClientApp/dist/vendor-manifest.json'),
                sourceType: 'commonjs2',
                name: './vendor'
            })
        ].concat(isDevBuild ? [] : [
            // Plugins that apply in production builds only
            new AotPlugin({
                tsConfigPath: './tsconfig.json',
                entryModule: path.join(__dirname, 'ClientApp/app/app-server.module#AppModule'),
                exclude: ['./**/*.browser.ts']
            })
        ]),
        output: {
            libraryTarget: 'commonjs',
            path: path.join(__dirname, './ClientApp/dist')
        },
        target: 'node',
        devtool: 'inline-source-map'
    });

    return [clientBundleConfig, serverBundleConfig];
};
2

2 Answers

0
votes

It looks like @import "~primeng/resources/themes/omega/theme.scss"; already loads the _theme.scss, so I am not sure if you are getting issues because you are loading the _theme.scss outside of omega after the theme.scss, so try just:

//bootstrap
@import "~bootstrap/scss/bootstrap";

//primeng
@import "~primeng/resources/themes/omega/theme.scss";

Sometimes when I've had issues with primeng styles (or because I wanted to use a different pathing setup), I load the theme.scss (or layout.scss if you're using a template) inside of my angular-cli.json instead within the "styles": [] option; so you might try that as well.

0
votes

The issue turned out to be that I needed to include primeng/resources/primeng.css in webpack.config.vendor.js. I had removed it along with primeng/resources/themes/omega/theme.css. It was correct to remove theme.css since the style would be compiled from the scss file but primeng.css is still needed, obviously.

Also, I was able to remove the last two tests in webpack.config.js that were used for the fonts. Webpack was definitely having errors before without those two tests but now it isn't, even after I deleted the dist folders and rebuilt them. I have no idea why there are no errors now without them - just glad it's working

Edit: Ah, the font bundling is required for the omega theme only. Will need those if that theme is used.