webpack: Loaders used with the inline syntax can't fully override module types

Bug report

What is the current behavior?

Hi,

Letโ€™s say that I create a webpack config with a rule that handles all .txt files using the asset/resource type:

{
  test: /\.txt$/i,
  type: 'asset/resource'
}

I then wish to create a loader that will be used with the inline notation to handle some other .txt files, but using the javascript/auto type.

Since (unless Iโ€™m missing something) that type canโ€™t be set directly in the inline syntax, I use the following snippet in the loader (which is something that works to override the default behavior with .json files):

const requiredType = 'javascript/auto';
if (this._module.type !== requiredType) {
    const factory = this._compilation.dependencyFactories.get(LoaderDependency);
    this._module.type = requiredType;
    this._module.generator = factory.getGenerator(requiredType);
    this._module.parser = factory.getParser(requiredType);
}

And import the .txt file in my JS modules using the following syntax:

import '!!./loader.js!./foo.txt';

The compilation then fails with the following message:

str must be a string, but is a object: module.exports = "";

If I remove the rule from the webpack.config.js file that error disappears.

If the current behavior is a bug, please provide the steps to reproduce.

Here is a gist with a minimal repro: https://gist.github.com/Lyrkan/bdff6c43ed3edbed3f9a166e0b68799c

What is the expected behavior?

The module type declared in the rule should be ignored for that import and the compilation should be successful.

Other relevant information: webpack version: 5.18.0 Node.js version: 14.15.1 Operating System: Linux Additional tools: None

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 23 (14 by maintainers)

Most upvoted comments

Yay, solved! You are fantastic ๐Ÿ‘ ๐Ÿ‘ ๐Ÿ‘

My exact use case is not ./style.css, but ./src/asset/test.css, so I thought that I have to adapt your example accordingly and tried

import Test from './src/assets/test.css.webpack[javascript/auto]!=!!!style-loader?injectType=lazyStyleTag!cssl-loader!./src/assets/test.css';

which failed with the mentioned error.

But after changing it to the following, it worked

import Test from 'test.css.webpack[javascript/auto]!=!!!style-loader?injectType=lazyStyleTag!cssl-loader!./src/assets/test.css';

Youโ€™re a real lifesaver! Thank you! Thank you! Thank you! ๐Ÿ˜†

Another solution is using ./style.css.webpack[javascript/auto]!=!!!style-loader!css-loader!./style.css, i.e. we say webpack that is custom internal module (no loaders/types) and say what it will be outputed in js + apply required loaders