Amit Rahav
Amit Rahav

Reputation: 115

Import scss file from less using webpack5 custom loader

I followed this gist suggestions for importing scss via custom js loader, But I ran into problem - The custom loader does not run for the imported scss file from less.

ERROR in ./src/app/scss/ant.less (./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[6].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[6].use[2]!./node_modules/resolve-url-loader/index.js??ruleSet[1].rules[1].oneOf[6].use[3]!./node_modules/less-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[6].use[4]!./src/app/scss/ant.less)
Module build failed (from ./node_modules/less-loader/dist/cjs.js):

I'm using:

Here is the relevant module section of my webpack config (after ejecting):

module: {
      strictExportPresence: true,
      rules: [
        // ... Rule for Handle node_modules packages that contain sourcemaps
        {
          oneOf: [
            // Rule for handle `image/avif` 
            ...
            // Rule for handle [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/] assets
            ...
            // Rule for handle /\.svg$/ assets
            ...
            // Rule for custom formatJs transformer
            ...
            // Process application JS with Babel.
            // The preset includes JSX, Flow, TypeScript, and some ESnext features.
            ...
            // Process any JS outside of the app with Babel.
            // Unlike the application JS, we only compile the standard ES features.
            ...
            // Include less-loader (exact settings may deviate depending on your building/bundling procedure)
            {
              test: lessRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 3,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  lessOptions: {
                    javascriptEnabled: true,
                  },
                },
                "less-loader"
              ),
              // Don't consider CSS imports dead code even if the
              // containing package claims to have no side effects.
              // Remove this when webpack adds a warning or an error for this.
              // See https://github.com/webpack/webpack/issues/6571
              sideEffects: true,
            },
            // "postcss" loader applies autoprefixer to our CSS.
            ...
            // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
            // using the extension .module.css
            ...
            // Opt-in support for SASS (using .scss or .sass extensions).
            // By default we support SASS Modules with the
            // extensions .module.scss or .module.sass
            {
              test: sassRegex,
              exclude: [sassModuleRegex, lessRegex],
              use: getStyleLoaders(
                {
                  importLoaders: 3,
                  sourceMap: isEnvProduction
                    ? shouldUseSourceMap
                    : isEnvDevelopment,
                  modules: {
                    mode: 'icss',
                  },
                },
                'sass-loader'
              ),
              // Don't consider CSS imports dead code even if the
              // containing package claims to have no side effects.
              // Remove this when webpack adds a warning or an error for this.
              // See https://github.com/webpack/webpack/issues/6571
              sideEffects: true,
            },
            // Adds support for CSS Modules, but using SASS
            // using the extension .module.scss or .module.sass
            {
              test: sassModuleRegex,
              exclude: lessRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 3,
                  sourceMap: isEnvProduction
                    ? shouldUseSourceMap
                    : isEnvDevelopment,
                  modules: {
                    mode: 'local',
                    getLocalIdent: getCSSModuleLocalIdent,
                  },
                },
                'sass-loader'
              ),
            },
            // "file" loader makes sure those assets get served by WebpackDevServer.
            // When you `import` an asset, you get its (virtual) filename.
            // In production, they would get copied to the `build` folder.
            // This loader doesn't use a "test" so it will catch all modules
            // that fall through the other loaders.
            {
              // Exclude `js` files to keep "css" loader working as it injects
              // its runtime that would otherwise be processed through "file" loader.
              // Also exclude `html` and `json` extensions so they get processed
              // by webpacks internal loaders.
              exclude: [/^$/, /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
              type: 'asset/resource',
            },
            // ** STOP ** Are you adding a new loader?
            // Make sure to add the new loader(s) before the "file" loader.
          ],
        },
        // Define a second rule for only being used from less files
        // This rule will only be used for converting our sass-variables to less-variables
        {
          test: sassRegex,
          issuer: lessRegex,
          use: {
            loader: path.resolve(
              paths.appSrc,
              'app/scss/sassVarsToLess.js' // I ensured it is the correct path
            ),
          }
        },
      ].filter(Boolean),
    }

'app/scss/sassVarsToLess.js':

"use strict";

// This loader will simply replace all $something sass-variable with @something less-variables
export default function (source) {
  return source.replace(/\$/gi, "@");
}

The printed error indicates that the sassVarsToLess.js file does not loads the imported scss from less. I tried to change the loaders order - but it doesn't work in any other order.

Upvotes: 0

Views: 1000

Answers (1)

Michael Foidl
Michael Foidl

Reputation: 1

Check out this post. When transpiling SASS or SCSS, all imports below the topmost level seem to be handled by the SASS transpiler, not webpack. Maybe the same is true for LESS.

Upvotes: 0

Related Questions