Css-loader: Migration strategy for adding tilde

Created on 30 Mar 2019  Â·  28Comments  Â·  Source: webpack-contrib/css-loader

There are two import syntax:

@value foo from 'bar/baz.css';
@value foo from '~bar/baz.css';

css-loader@^1 tries to resolve 'bar/baz.css' in node_modules, and fails to resolve '~bar/baz.css'.
css-loader@^2 tries to resolve 'bar/baz.css' only in local folder, and resolves '~bar/baz.css' in node_modules

The problem

We have a few hundreds of react-components, which actively uses css imports. We cannot change all of them at once, because they are in different repositories, and some of them have cycled dependencies from each other. And it looks like there is no css-loader version which supports both formats.

Say, we have package A, which depends on B and C. Both, B and C have their own release cycle. If only one package updates its syntax, we will be unable to update that package until the second package also updates its syntax. Multiply that by few hundreds, and you will get our situation. So, we totally blocked.

What is an official webpack strategy for migration from 'bar/baz.css' to '~bar/baz.css' syntax?

4 (important) 4 (inconvenient) Needs triage Feature

Most helpful comment

I think we can implement resolve Function to allow old projects migrate on new version. What do you think?

All 28 comments

I think it is bug, we need fix it https://github.com/webpack-contrib/css-loader/issues/861, we should support bar/baz.css and ~bar/baz.css:
bar/baz.css should:

  1. Try to resolve from node_modules
  2. Try to resolve local folder

~bar/baz.css should:

  1. Try to resolve from node_modules

/cc @Diokuz friendly ping. Officially:

  • @value foo from 'bar/baz.css'; - relative loading
  • @value foo from '~bar/baz.css'; - loading from node_modules

I think it is right behavior, previously was wrong, but i think known how to difficult migrate all code. Solution:

  1. Add example in README using postcss-loader (we can implement light plugin for rewriting)
  2. Add option to allow change resolving mechanics (for me bad idea) because other developers can stop migrate on right syntax

So, there is no way to migrate gradually, and we need to rewrite all our components at once?

I think we can implement resolve Function to allow old projects migrate on new version. What do you think?

What can we do to get this implemented?

Yes, PR welcome, don't have time right now

@evilebottnawi done in #933!

Sorry for big delay

/cc @niksy i think we can create postcss-plugin for this stuff and avoid put logic into css-loader, what do you think, sorry again

@evilebottnawi yeah, that’s certainly one way to do this, but introduces complexity on another part. That plugin then needs to read and parse every dependancy and change import statements, not to mention that you need to apply that plugin on whole codebase, including node_modules. If you have idea and know how to do that performantly, great! I’m more inclined on solving this on css-loader side. Not everyone uses PostCSS.

we can implement light plugin for rewriting

There's such a plugin now: https://github.com/princed/postcss-modules-tilda
It could be used as a temporary solution (@Diokuz) and possibly even in css-loader itself (@niksy, @evilebottnawi)

@princed can you send a PR in readme with example setup?

@princed @evilebottnawi this doesn’t solve issue I mentioned https://github.com/webpack-contrib/css-loader/issues/914#issuecomment-500874514 - you will need to apply this plugin to _every_ dependancy, including node_modules.

As for using plugins, you can also achieve this with URL mapper, but as I said, this only works for your modules by default:

const urlMapper = require('postcss-url-mapper');

// Add "~" to all url/@import statements for Webpack resolve.alias
urlMapper(
    (url) => {
        return `~${url}`;
    },
    { atRules: true }
);

I’m more inclined in implementing full solution rather than temporary, and using new resolve option can solve this issue on css-loader side.

OK, I’ve reviewed codebase and it seems that there’s been a lot of changes since my PR has been submitted.

Main thing I’m concerned with is will this PostCSS solution work with node_modules dependencies by default?

@niksy can you clarify?

Let’s say you have this configuration:

module.exports = {
    module: {
        rules: [
            {
                exclude: /node_modules/,
                test: /\.css$/i,
                use: ['style-loader', 'css-loader']
            }
        ]
    }
};

Wouldn’t PostCSS for adding tilde work only on dependencies outside node_modules?

@niksy tilde always try to load module from resolve.modules option (by default it is node_modules)

OK, @princed, can you make a PR for this change?

@niksy You mean README?

@niksy yes!

Same problems for url and @import, we need fix it

@evilebottnawi Could you elaborate please?

@princed we should support without tilde:

a {
  // `package` placed in `node_modules`
  background: url('package/assets/img.pmg');
}

@evilebottnawi
My package https://github.com/princed/postcss-modules-tilda supports @import already.
I could add url support if you are willing to use it in css-loader.

We improve our resolver, so we can achieve this without problem and we solve this :star:

We improve our resolver, so we can achieve this without problem and we solve this

Fantastic… so what is now the official way when I don't want those tildas?
Do I just drop them when I update to some version containing this patch?

@kubijo

Fantastic… so what is now the official way when I don't want those tildas?

When you use foo/baz.css, we try to resolve, order is matter:

  1. Try to resolve relative file
  2. Try to resolve from node_modules
  3. Try to use aliases

Do I just drop them when I update to some version containing this patch?

Yes

We don't remove ~, because there are situations, when you have local file and package, and we don't know what you want, it is edge case

Sorry for possibly annoying bumping of this, but do you have any idea for when there will be a release that will include this?
I'm currently in the middle of a big refactor and would like drop those tildas…

@kubijo ETA is the next week

Was this page helpful?
0 / 5 - 0 ratings

Related issues

osenvosem picture osenvosem  Â·  4Comments

Naspo88 picture Naspo88  Â·  3Comments

grydstedt picture grydstedt  Â·  3Comments

heldrida picture heldrida  Â·  4Comments

jonathanong picture jonathanong  Â·  3Comments