Customize Angular loaders for individual files

Our current codebase was originally built with Angular, utilizing the Angular CLI and its default webpack configuration. However, as we transition towards using web components, we are faced with the challenge of incorporating SCSS within our web component TS files. To address this, we developed a new webpack loader that adds the necessary SCSS file as a dependency, waits for the CSS to be compiled by the sass-loader, and then inserts it into our TS file using a string replacement method.

While this setup functions well in a standard webpack environment, Angular processes SCSS files differently, resulting in the SCSS files being converted into JavaScript. This transformation is not required for files ending in .webcomponent.scss.

The question is: How can we instruct Angular not to apply its default loaders to our *.webcomponent.scss files?

The extra-webpack-config.js file contains the following configuration:

module.exports = {
    module: {
        rules: [
            {
                test: /\.webcomponent\.ts$/,
                use: [
                    {
                        loader: './webcomponent-loader.js'
                    }
                ]
            },
            {
                test: /\.webcomponent\.scss$/,
                use: [
                    {
                        loader: 'sass-loader'
                    }
                ]
            }
        ]
    }
};

Additionally, our angular.json file includes a custom webpack configuration:

"customWebpackConfig": {
    "path": "./extra-webpack.config.js",
    "mergeStrategies": {
        "module": "prepend",
        "loaders": "replace"
    }
}

Within the webcomponent-loader, the code snippet used is:

this.addDependency(this.resourcePath.replace(/.ts$/, '.scss'));

Unfortunately, the above implementation results in the error message:

Invalid CSS after "module.exports": expected selector, was '= "/*Colors*/\\n/*Bl'

It appears that Angular has converted the SCSS code into JavaScript. Any assistance on resolving this issue would be greatly appreciated.

Answer №1

After some trial and error, I managed to customize the default loaders by creating an additional webpack configuration file called extra-webpack.config.js:

module.exports = (config, options) => {
    config.module.rules.forEach(rule => {
        if (rule.test.exec('.scss')) {
            rule.test = new RegExp('(?<!\.webcomponent)(' + rule.test.source + ')');
        }
    });

    config.module.rules.push({
        test: /\.webcomponent\.ts$/,
        use: [
            {
                loader: './webcomponent-loader.js'
            }
        ]
    },
    {
        test: /\.webcomponent\.scss$/,
        use: [
            {
                loader: './identity-loader.js'
            },
            {
                loader: 'sass-loader'
            }
        ]
    });

    return config;
};

In essence, I modified the existing configuration by adjusting the test regex to exclude specific files using a negative lookbehind. Additionally, I integrated my custom loaders into the configuration rules. Although I encountered issues with my CSS, I will address them in a separate inquiry.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Obtain data attributes using JQuery's click event handler

I'm facing an issue with a div structure setup as follows: <div class='bar'> <div class='contents'> <div class='element' data-big='join'>JOIN ME</div> <div class=& ...

Guide to making a ng-bootstrap modal that retains a component's state

I am currently working on implementing a modal with Angular by following a tutorial on the ng-bootstrap website ( - in the "Components as content" section). However, I am facing a challenge where I want the component displayed in the modal to retain its st ...

What is the best way to incorporate the correct SCSS file?

I have a specific scenario using Vue where I need to utilize different stylesheets based on configuration settings. In this case, I have a config file with the value type: "a", which means I must include and use the "a-setup.scss" style ...

Dealing with compilation errors in TypeScript

I'm working on a simple TypeScript program that looks like this - const users = [{ name: "Ahmed" }, { name: "Gemma" }, { name: "Jon" }]; // We're trying to find a user named "jon". const jon = users.find(u => u.name === "jon"); However, wh ...

Dynamically attach rows to a table in Angular by triggering a TypeScript method with a button click

I need help creating a button that will add rows to a table dynamically when pressed. However, I am encountering an error when trying to call the function in TypeScript (save_row()). How can I successfully call the function in TypeScript and dynamically a ...

Can you explain the concept of widening in relation to function return types in TypeScript?

Recently, I've observed an interesting behavior in TypeScript. interface Foo { x: () => { x: 'hello' }; } const a: Foo = { x: () => { return { x: 'hello', excess: 3, // no error } }, } I came acro ...

What should I do to resolve the error when "HttpClient" name is not found?

Whenever I attempt to start my project using npm start, I encounter an error: [at-loader] Checking completed with 1 error [at-loader] ./node_modules/@ngx-translate/http-loader/src/http-loader.d.ts:10:23 TS2304: Cannot find name 'HttpClient' ...

There appears to be a problem with the syntax in the JSON data at position 0, as it is detecting

WARNING: core.es5.js?0445:1084 WARNING SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous> SCENARIO: The goal is to automatically select the option that the user previously chose and prevent them from voting twi ...

Reactive property in the Vue composition API

Within a Vue 3 project that utilizes TypeScript, there are two properties named locale and content: <script setup lang="ts"> import { computed, ref } from 'vue' import { useI18n } from "vue-i18n" import { Landing, Local ...

Angular: displaying dates in a specific format while disregarding time zones

Is there a way to format date-time in Angular using DatePipe.format() without converting timezones, regardless of location? For instance, for various examples worldwide (ignoring time differences) I would like to obtain 07/06/2022: console.log('2022-0 ...

Using ES6 proxy to intercept ES6 getter functions

I have implemented a proxy to track all property access on instances of a class, demonstrated in the code snippet below: class Person { public ageNow: number; public constructor(ageNow: number) { this.ageNow = ageNow; const proxy = new Proxy( ...

Using Angular with adal-angular4 and implementing refresh token functionality

I have incorporated the Azure AD authentication in my Angular application using the package mentioned below: https://www.npmjs.com/package/adal-angular4 However, I am facing an issue where the token expires after 10-20 minutes. I have searched through va ...

The "webpack --watch" command stops running after completing a single build

Previously, I relied on the webpack --watch command to keep my webpack running in watch mode for my ReactJS app. Unfortunately, it seems to have stopped working abruptly. Now, it only compiles the code once and then stops. I attempted the solutions mentio ...

Potential null object in React/TypeScript

Encountering a persistent error here - while the code functions smoothly in plain react, it consistently throws an error in typescript stating "Object is possibly null". Attempts to resolve with "!" have proved futile. Another error logged reads as follow ...

The problem with RXJS pipe in Angular application is that it evaluates excessively, leading to eventual breakdown

I'm experiencing challenges when attempting to fork an Observable (that has been piped multiple times): subscribing to it in one place, and piping and subscribing to it in another place. I am facing 2 issues: The pipes are being evaluated multiple t ...

Troubleshooting Node.js import module errors

I have just discovered two files that I created using the TS language specification manual (on page 111). The first file, called geometry.ts, contains the following code: export interface Point { x: number; y: number }; export function point(x: number, y ...

The program encountered a problem stating that the 'getItem' property is not found within the 'string' type

I am utilizing Firebase to register links on a website. I'm attempting to pass the uuid in order to create a sub collection, but have been unsuccessful. Any idea what might be causing this issue? constructor(private af: AngularFirestore) {} async add ...

Encountering an Error: Unforeseen Token < Causing Webpack Configuration Problem in Typescript

Seeking assistance to resolve an issue that has arisen while working on a project with Typescript, React, and Webpack. I referred to the guide available at https://www.typescriptlang.org/docs/handbook/react-&-webpack.html After configuring everything, ...

Vue's computed property utilizing typed variables

I am trying to create a computed array of type Todo[], but I keep encountering this specific error: No overload matches this call. Overload 1 of 2, '(getter: ComputedGetter<Todo[]>, debugOptions?: DebuggerOptions | undefined): ComputedRef<T ...

What are the benefits of adding member functions to the data structures of React.js store?

Using React.js and Typescript, I store plain Javascript objects in the React.js store. These objects are sometimes received from the server without any member functions, but I wish to add functions for better organization. Instead of having to rely on exte ...