Skip to content

Module-level aliases don't work #1122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
GottemHams opened this issue Feb 6, 2025 · 3 comments
Open

Module-level aliases don't work #1122

GottemHams opened this issue Feb 6, 2025 · 3 comments

Comments

@GottemHams
Copy link

GottemHams commented Feb 6, 2025

Bug report

Actual Behavior

Although this loader does support resolve.alias at the top level of the Webpack config, it seems module-specific aliases are ignored (module.rules[i].resolve.alias). This results in Can't find stylesheet to import errors, which occurs for both @use and @import. One reason for module-level aliases is so that every rule can have its own aliases, without any risk of accidentally importing SASS into TypeScript for example (or vice versa even).

ERROR in ./sass/entry.scss (./sass/entry.scss.webpack[javascript/auto]!=!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./sass/entry.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
Can't find stylesheet to import.
  ╷
1 │ @import '@aliased/import';
  │         ^^^^^^^^^^^^^^^^^
  ╵
  sass/entry.scss 1:9  root stylesheet
 @ ./sass/entry.scss

This error seems to originate from sass-loader if I'm interpreting this correctly, which is why I created the issue here and not elsewhere.

Expected Behavior

Perhaps there is a way to just ask Webpack what aliases are relevant for the current loader/rule? That way it will keep working even if they ever add aliases at more levels.

How Do We Reproduce?

  1. Clone the reproduction repo
  2. Run npm i of course
  3. Now you can do either npm run build-fail or npm run build-good

I only used @import in this example because it's closer to my actual scenario (can't use @use due to dependencies), and I figured it's pretty redundant to show @use since the behaviour is exactly the same anyway.

Please paste the results of npx webpack-cli info here, and mention other relevant information

  System:
    OS: macOS 14.4.1
    CPU: (12) arm64 Apple M2 Pro
    Memory: 116.09 MB / 16.00 GB
  Binaries:
    Node: 23.6.1 - /opt/homebrew/bin/node
    Yarn: 1.22.22 - /opt/homebrew/bin/yarn
    npm: 10.9.2 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 133.0.6943.53
    Safari: 17.4.1
  Packages:
    css-loader: ^7.1.2 => 7.1.2 
    sass-loader: ^16.0.4 => 16.0.4 
    webpack: ^5.97.1 => 5.97.1 
    webpack-cli: ^6.0.1 => 6.0.1 
@alexander-akait
Copy link
Member

alexander-akait commented Feb 6, 2025

That's expected, because you set it not for SASS, you set it for JS (under the hood webpack convert CSS into JS)

Please use on global level:

// ...
plugins: [
		new MiniCssExtractPlugin({
			filename: '[name].css',
			runtime: false,
		}),
],
resolve: {
		byDependency: {
			"sass": {
				extensions: ['.scss'],
				alias: {
					'@aliased': path.resolve(__dirname, 'sass', 'alias'),
				},
			}
		}
},
module: {
		rules: [
// ...

@alexander-akait
Copy link
Member

alexander-akait commented Feb 6, 2025

Just comment:

{
  loader: MiniCssExtractPlugin.loader,
},

and use on a module level:

{
	test: /\.scss$/,
	exclude: /node_modules/,
	resolve: {
		byDependency: {
			"sass": {
				extensions: ['.scss'],
				alias: {
					'@aliased': path.resolve(__dirname, 'sass', 'alias'),
				},
			}
		}
	},
	use: [
		/*{
			loader: MiniCssExtractPlugin.loader,
		},*/
		{
			loader: 'css-loader',
			options: {
				sourceMap: true,
				url: false,
			},
		},
		{
			loader: 'sass-loader',
			options: {
				sourceMap: true,
				sassOptions: {
					silenceDeprecations: ['import'],
				},
			},
		},
	],
},

And it will work, the main problem here is what this code applied to JS (mini-css-extract-plugin doing it in importModule), this is such a design, we are working on built-in CSS support right now inside webpack and this limitation will not exist anymore.

Also any module can contain different resolve logic, for example you can have mixed require() and import() in your file and so we should apply options by dependencies (same for other things in SASS you can have pure CSS and SASS imports and they works different too), otherwise resolver will be broken and that is why I strongly recommend use byDependency, global options when you really want to make aliases across any dependecies

@alexander-akait
Copy link
Member

alexander-akait commented Feb 6, 2025

So I want to say it is mini-css-extract-plugin limitation, because even using (without byDependency will work if you comment mini-css-extract-plugin):

resolve: {
  extensions: ['.scss'],
  alias: {
    '@aliased': path.resolve(__dirname, 'sass', 'alias'),
  },
},

So no problems with sass-loader

@alexander-akait alexander-akait transferred this issue from webpack-contrib/sass-loader Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants