Code Monkey home page Code Monkey logo

Comments (9)

uweg avatar uweg commented on June 14, 2024 15

I have the same issue with LESS. However, I found a way to fix it.

Does not work:

{
  test: /\.less$/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        localIdentName: '[local]--[hash:base64:5]',
        sourceMap: true
      }
    },
    {
      loader: 'less-loader',
      options: {
        sourceMap: true
      }
    },
    {
      loader: 'string-replace-loader',
      options: {
        search: 'placeholder',
        replace: 'replacement',
        flags: 'g'
      }
    }
  ]
}

Works:

{
  test: /\.less$/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        localIdentName: '[local]--[hash:base64:5]',
        sourceMap: true
      }
    },
    {
      loader: 'string-replace-loader',
      options: {
        search: 'placeholder',
        replace: 'replacement',
        flags: 'g'
      }
    },
    {
      loader: 'less-loader',
      options: {
        sourceMap: true
      }
    }
  ]
}

For whatever reason, the order of the loaders seems to be important.

from string-replace-loader.

Aaltuj avatar Aaltuj commented on June 14, 2024

i have this issue also with scss. Is this loader not capable of doing css/scss replacement??
My typescript replacement is working:

  {
          test: /app.bootstrap\.ts$/,
          loader: 'string-replace-loader',
          query: {
            search: /'.+.bootstrap'/,
            replace: `\'./${applicationToBuild}.bootstrap\'`
          }
        },

but this ain't working:

   {
          test: /variables\.scss$/,
          loader: 'string-replace-loader',
          query: {
            search: /".+.variables"/,
            replace: `"theme-variables/${applicationToBuild}.variables"`
          }
        },

from string-replace-loader.

palak-temp avatar palak-temp commented on June 14, 2024

Hi @uweg

I have the same situation and I try your tricks but I'm getting this:-

ERROR in ./node_modules/css-loader?{"modules":true,"camelCase":true,"importLoaders":1}!./node_modules/string-replace-loader?{"search":{},"replace":"../public","flags":"g"}!./node_modules/postcss-loader/lib?{"plugins":[null,null]}!./node_modules/less-loader/dist/cjs.js!./project/assets/less/style.less Module not found: Error: Can't resolve '../public/img/common-bg.png' in 'D:\project\assets\less' @ ./node_modules/css-loader?{"modules":true,"camelCase":true,"importLoaders":1}!./node_modules/string-replace-loader?{"search":{},"replace":"../public","flags":"g"}!./node_modules/postcss-loader/lib?{"plugins":[null,null]}!./node_modules/less-loader/dist/cjs.js!./project/assets/less/style.less 6:1001-1039

from string-replace-loader.

palak-temp avatar palak-temp commented on June 14, 2024

But, it works when I put it on the top.

{
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: [
                        {
                           loader: "string-replace-loader",
                           options: {
                               search: "placeholder",
                               replace: "replacement",
                               flags: "g",
                           },
                       }, {
                            loader: "css-loader",
                            options: {
                                modules: true,
                                camelCase: true,
                                importLoaders: 1,
                            },
                        }, {
                            loader: "postcss-loader",
                            options: {
                                plugins: [
                                    autoprefixer({
                                        browsers: [
                                            "last 2 versions",
                                            "Firefox ESR",
                                            "> 1%",
                                            "ie >= 8",
                                            "iOS >= 8",
                                            "Android >= 4",
                                        ],
                                    }),
                                    pxtorem({
                                        rootValue: 100,
                                        propWhiteList: [],
                                    }),
                                ],
                            },
                        },
                        "less-loader",
                    ],
                }),
            },

from string-replace-loader.

Va1 avatar Va1 commented on June 14, 2024

sorry for delayed reply.

first of all, you can only specify options.search as a string, as this is how webpack docs want you to do because wepback translates options to JSON and back before they get to the loader code.

regarding main issue: loaders ordering does matter and the fact that you can not replace after LESS or SASS loader did its job means that they somehow changed the contents in a way replacement does not work anymore. i am not sure though, will have a closer look into how CSS raw contents accessible to loaders look like when i have time. you should replace before preprocessing anyways, if you can.

from string-replace-loader.

gregorskii avatar gregorskii commented on June 14, 2024

Would it make sense for this to be a plugin then? If it were a plugin it could attach to a specific phase and enforce that it happens directly on the source files before it is compiled.

I am finding this to be difficult, if not impossible to use within a package that defines the CSS loaders for you, like CRA or GatsbyJS. They have predefined multi loaders for most kinds of css, but you cannot easily with webpack inject a loader into that process dynamically (as far as I know) and they typically use the oneOf: { syntax to make sure the file only gets processed by the correct loader.

In that case any subsequent loader for a file type is ignored. I tried using enforce: 'pre' to see if I could get it to process sort of like eslint does on JS, but that didn't seem to work either.

from string-replace-loader.

Va1 avatar Va1 commented on June 14, 2024

sorry for even more of a delayed reply lol.

there is a plugin which allows for replacements – webpack.DefinePlugin. it's also official. you can use it instead of this loader (i assume) or together with this loader, depending on what are you trying to achieve.

with my above note on the order of loaders and the absence of further essence of the issue, i'm closing it. let me know if i should reopen.

big thanks to all participants. cheers guys

from string-replace-loader.

prma85 avatar prma85 commented on June 14, 2024

@Va1 I am having the same issue

I have the string-replace-loader to load before sass. It does replace the @import .. but it is not replacing the content itself for variables. How can I use the webpack.DefinePlugin together to do the replace? Doesn't have any mention to it on the webpack documentation.

const replaceList = [
  { search: /bootstrap-4/gi, replace: "bootstrap" },
  { search: /bootstrap-sass-official/gi, replace: "bootstrap-sass" },
  { search: /..\/..\/..\/..\/libs\/bootstrap/gi, replace: "bootstrap" },
  { search: /@import "bootstrap/gi, replace: '@import "~bootstrap' },
  { search: /@import "font-awesome/gi, replace: '@import "~font-awesome' },
  { search: /@import "libs\//gi, replace: '@import "~' },
  { search: /libs\/font-awesome\/fonts/gi, replace: '/fonts' },
];
loader: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              importLoaders: 3,
              sourceMap: true,
            },
          },
          {
            loader: "resolve-url-loader",
            options: {
              sourceMap: true,
            },
          },
          {
            loader: "sass-loader",
            options: {
              implementation: require("node-sass"),
              sassOptions: {
                sourceComments: true,
                outputStyle: "nested",
              },
              sourceMap: true,
            },
          },
          {
            loader: "string-replace-loader",
            options: {
              multiple: replaceList,
            },
          },
        ],

and my _base.scss

// a lot of bootstrap imports (all replaced)
@import "~font-awesome/scss/font-awesome";
@import "local/font-awesome"

finally, my font-awesome.scss

$fa-font-path: "libs/font-awesome/fonts";

i.icon-fa {
    -webkit-font-smoothing: antialiased;
}

the variable value $fa-font-path: is not being replaced if I add it in the second file, but it is replaced if I add it in the first file. The issue here is that the replace only works for the entry point. As soon the scss file loads a new file, it doesn't go through the loaders list anymore, it will keep inside of the sass-loader. :(

from string-replace-loader.

cnt-null avatar cnt-null commented on June 14, 2024

@Va1 DefinePlugin affects everything, even js files. So there is a risk of unwanted replacement.

I managed to solve the replacement issue in css. Perhaps it will be useful to someone.

For example, I have an index.js file containing import 'styles.scss'.
And styles.scss contains @import '~semantic-ui-css/semantic.css'.
I try to use the string-replace-loader to overwrite some styles in semantic.css.

When styles are processed by the loaders chain and reach the MiniCssExtractPlugin.loader, the imported styles look like this:

import ___CSS_LOADER_AT_RULE_IMPORT_0___ from "-!../../node_modules/css-loader/dist/cjs.js!../../node_modules/semantic-ui-css/semantic.css";

That is, the styles are not yet extracted from semantic.css and we only see an "import ..." string.
Hence, the string-replace-loader cannot replace these styles.
But the problem can be solved like this:
Remove @import '~semantic-ui-css/semantic.css' from styles.scss.
Add import 'semantic-ui-css/semantic.css' to index.js.

from string-replace-loader.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.