customize-cra icon indicating copy to clipboard operation
customize-cra copied to clipboard

πŸ“ŒπŸ“Œ Breaking change: `css-loader@^3.0.0` (+`addLessLoader`)

Open Anish-Agnihotri opened this issue 4 years ago β€’ 20 comments

As part of our 1.0 release, we need to support css-loader@^3.0.0 which was added to create-react-app in #7876.

Across various issues (#231, #242, #243), the new css-loader configuration format (a switch from a boolean to options for lessOptions) has caused errors during the run and build process of customize-cra.

With version 1.0, we have introduced a fix for this, although it is a breaking change, and will require maintainers to alter their customizers configurations.

In particular, configuration options for the addLessLoader customizer will now be nested in a lessOptions object, as so:

Before:

addLessLoader({
  javascriptEnabled: true,
  modifyVars: { '@primary-color': '#A80000' },
}),

Now:

addLessLoader({
  lessOptions: {
    javascriptEnabled: true,
    modifyVars: { '@primary-color': '#A80000' },
  },
}),

For additional information, please see the revised docs.

If you run into issues migrating to the 1.0 release, please report the issue, and fall-back to the 0.9.1 release until I can diagnose and help you resolve your issue.

Anish-Agnihotri avatar May 28 '20 20:05 Anish-Agnihotri

I updated to 1.0 and changed included lessOptions: { as advised. This caused all .less files to stop loading. I removed the nested lessOptions: { object and it works fine.

My package-lock.json currently shows I am indeed on 1.0.0:

"customize-cra": {
  "version": "1.0.0",
  "resolved": "https://registry.npmjs.org/customize-cra/-/customize-cra-1.0.0.tgz",
  "integrity": "sha512-DbtaLuy59224U+xCiukkxSq8clq++MOtJ1Et7LED1fLszWe88EoblEYFBJ895sB1mC6B4uu3xPT/IjClELhMbA==",
  "requires": {
    "lodash.flow": "^3.5.0"
  }
},

And inside the node_modules/customize-cra package.json:

{
  "_from": "customize-cra@latest",
  "_id": "[email protected]",

Any suggestions?

mjfwebb avatar Jun 02 '20 16:06 mjfwebb

@mjfwebb Thanks for reporting thisβ€”that is odd, but I will take a look at it tonight and get back to you.

Please use without the nested lessOptions for the time being so that you can continue to use your .less files.

Anish-Agnihotri avatar Jun 03 '20 13:06 Anish-Agnihotri

I ran into the same issue as @mjfwebb after updating customize-cra from version 0.8.0 to 1.0.0 and updating lessOptions like described in https://github.com/arackaf/customize-cra/issues/253#issue-626797945:

alidationError: Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'javascriptEnabled'. These properties are valid:
   object { lessOptions?, prependData?, appendData?, sourceMap?, implementation? }

After upgrading my less-loader from version 5.0.0 to 6.1.0 the changes mentioned in https://github.com/arackaf/customize-cra/issues/253#issue-626797945 were necessary to be implemented and everything worked again.

I am using

...
"customize-cra": "^1.0.0",
"less": "^3.11.3",
"less-loader": "^6.1.0",
"react-app-rewired": "^2.1.6",
"react-scripts": "^3.4.1",
...

so i updated lessOptions in my config-overrides.js.

iwan-uschka avatar Jun 11 '20 11:06 iwan-uschka

Just wanted to confirm that my previous experience of it failing was due to my still using less-loader version 5.0.0, just as @iwan-uschka described.

After upgrading less-loader to the latest version (7.0.1 as of writing this), I was required to add lessOptions: { as originally posted.

I suggest specifically mentioning this as a caveat or gotcha.

mjfwebb avatar Sep 24 '20 20:09 mjfwebb

How can I resolve background-image: url('public/assets/01.png') on the less files?

lamdoann avatar Jan 02 '21 15:01 lamdoann

Hi @lamdoann, i just gave it a try at put an image at /public/images/test.png. I was able to reference it in a less file like

background: url(/images/test.png);

The background image was loaded correctly in the browser. In dev tools i can see, that the url has been adjusted:

background: url(../../../images/test.png);

Hope this helps.

iwan-uschka avatar Jan 02 '21 15:01 iwan-uschka

Hi @iwan-uschka, thanks for your reply. I got this error when loading images from public folder. Module not found: You attempted to import ../public/assets/hand-map-02.png which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.

lamdoann avatar Jan 02 '21 16:01 lamdoann

@lamdoann Can you please share some code? How does your less file look like? How do you reference the image? I guess your image is located in /public/images/ right?

iwan-uschka avatar Jan 02 '21 16:01 iwan-uschka

Yes, I put images in /public/assets folder. I cannot access /public/assets folder on less files. It works when I put assets in /src.

lamdoann avatar Jan 02 '21 16:01 lamdoann

Well, like i said, it would help if you can show some code. You haven't said anything yet about how you reference your assets inside your less files.

I am using craco to customise create-react-app. The interesting part of my .cracorc.js looks like this:

const CracoLessPlugin = require('craco-less');

module.exports = function ({ env }) {
  return {
    style: {
      css: {
        loaderOptions: {
          url: false,
        },
      },
    },
    plugins: [
      {
        plugin: CracoLessPlugin,
        options: {
          lessLoaderOptions: {
            lessOptions: {
              javascriptEnabled: true,
            },
          },
        },
      }
    ]
  };
};

By setting css loader option url to false i am able to reference assets normally in my css (which means i can reference them normally in my less or scss files) and these assets won't be part of the bundle. This way you can reference files outside of the src directory. At least that is how I understood it :) A discussion about this issue is going on at https://github.com/facebook/create-react-app/issues/9870.

Maybe you can add some configuration into your config-overrides.js like describe in https://github.com/arackaf/customize-cra/blob/master/api.md#addlessloaderloaderoptions:

const { override, addLessLoader } = require("customize-cra");

module.exports = override(
  addLessLoader({
    cssLoaderOptions: {
      url: false
    }
  })
);

I couldn't find any dedicated documentation about customizing css loader options outside less loader scope.

iwan-uschka avatar Jan 02 '21 16:01 iwan-uschka

Here is my config-overrides.js ` const { override, addLessLoader } = require('customize-cra');

module.exports = override( addLessLoader({ lessOptions: { javascriptEnabled: true, cssLoaderOptions: { url: false } }, }) ); `

And my index.less .bg { width: 100%; height: 400px; background-image: url('/public/assets/hand-map-02.png'); }

lamdoann avatar Jan 02 '21 16:01 lamdoann

Thx! I guess this doesn't work :) If that's the case we have to wait for others to help out. Sorry..

iwan-uschka avatar Jan 02 '21 17:01 iwan-uschka

Ah, please have a look again.

Yours

const { override, addLessLoader } = require("customize-cra");

module.exports = override(
  addLessLoader({
    lessOptions: {
      javascriptEnabled: true,
      cssLoaderOptions: {
        url: false
      },
    },
  })
);

is not correct. There is no lessOptions or javascriptEnabled available in customize-cra, as far as i can see (please tell me if i missed it). cssLoaderOptions should be used as a root property of addLessLoader. Maybe this works:

const { override, addLessLoader } = require("customize-cra");

module.exports = override(
  addLessLoader({
    cssLoaderOptions: {
      url: false
    },
  })
);

iwan-uschka avatar Jan 02 '21 17:01 iwan-uschka

@iwan-uschka for new version, you can see the first comment of this topic. It will be like this: addLessLoader({ lessOptions: { javascriptEnabled: true, modifyVars: { '@primary-color': '#A80000' }, }, }),

lamdoann avatar Jan 03 '21 03:01 lamdoann

I found the way to fix it. I overrided ModuleScopePlugin plugin. It worked. Thanks for your support @iwan-uschka

lamdoann avatar Jan 03 '21 03:01 lamdoann

Oooops, i haven't even read the beginning of this block 😬 You're absolutely right about the new version, sorry. Glad you made it πŸ‘ Please paste your solution here. It might help others. Cheers

iwan-uschka avatar Jan 03 '21 09:01 iwan-uschka

I've been trying to set up Ant Design with Create React App and Customize CRA but I'm getting an error when loading Less files.

TypeError: this.getOptions is not a function

My setup:

  • Create React App 4.0.0
  • React App Rewired 2.1.8
  • Customize CRA 1.0.0
  • Postcss 8.2.10
  • Less 4.1.1
  • Less Loader 8.1.1
  • Ant Design
  • Tailwind CSS

When running yarn start, I get the following error:

Failed to compile.

./src/entities/scratchpad/theme/antd/custom-theme.less (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-8-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--5-oneOf-8-3!./node_modules/less-loader/dist/cjs.js??ref--5-oneOf-8-4!./src/entities/scratchpad/theme/antd/custom-theme.less)
TypeError: this.getOptions is not a function

I have Tailwind installed and running so I guess that de postcss-loader is not the problem. I've read that the problem maybe with less-loader version, but cannot get ant version of it working.

Anyone knows why may be this happening and how to solve it?

packetstracer avatar Apr 19 '21 08:04 packetstracer

Finaly got it working downgrading less loader to version 7.

Package.json "less-loader": "^7.1.1"

ConfigOverrides.dev.js

    config = override(
      fixBabelImports('import', {
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: true,
      }),
      addLessLoader({
        lessOptions: {
          javascriptEnabled: true,
          modifyVars: { '@primary-color': '#13c2c2' },
        },
      }),
      addPostcssPlugins([require('tailwindcss')])
    )(config)

NOTE: that for Tailwind to load correctly I had to set the addPostcssPlugins([require('tailwindcss')]) invocation line after the addLessLoader() one.

Hope this helps to anyone.

packetstracer avatar Apr 19 '21 09:04 packetstracer

Finaly got it working downgrading less loader to version 7.

Package.json "less-loader": "^7.1.1"

ConfigOverrides.dev.js

    config = override(
      fixBabelImports('import', {
        libraryName: 'antd',
        libraryDirectory: 'es',
        style: true,
      }),
      addLessLoader({
        lessOptions: {
          javascriptEnabled: true,
          modifyVars: { '@primary-color': '#13c2c2' },
        },
      }),
      addPostcssPlugins([require('tailwindcss')])
    )(config)

NOTE: that for Tailwind to load correctly I had to set the addPostcssPlugins([require('tailwindcss')]) invocation line after the addLessLoader() one.

Hope this helps anyone.

Hi @packetstracer, I do my own similar to you. But I encountered a problem: Before this, I use all SCSS (also import antd & tailwind using SCSS), so the order of compiled CSS same with scss importing order Now, to config antd color variable, I import antd LESS & config LESS loader same as you, I also use less-loader version 7 ("less-loader": "^7.3.0"). In the compiled CSS, antd CSS appears at a different position in the file & causes much change on the UI because of CSS priority changes. Any suggestion for my case? Thanks for reading this.

minhthangtkqn avatar Nov 17 '21 03:11 minhthangtkqn

this config is working good too:

$ nvm current
v14.19.1

package.json

    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "customize-cra": "^1.0.0",
    "react-scripts": "^5.0.1",
    "react": "^18.2.0",
    "react-app-rewired": "^2.2.1",
//config-overrides.js
const {
  override,
  addWebpackModuleRule,
} = require("customize-cra");

module.exports = {
  webpack: override(
    addWebpackModuleRule({
      test: [/\.css$/, /\.less$/],
      use: ['style-loader', 'css-loader', 'postcss-loader', {
        loader: 'less-loader',
        options: {
          lessOptions: {
            strictMath: false,
            noIeCompat: true,
            modifyVars: {
              "primary-color": "#fcbf2c", // for example, you use Ant Design to change theme color.
            },
            javascriptEnabled: true,
          }
        }
      }]
    }),
  ),
};

AndrewEastwood avatar Jul 11 '22 13:07 AndrewEastwood