Skip to content
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

refactor: improved loading algorithm of options and configs #234

Closed
wants to merge 1 commit into from

Conversation

alexander-akait
Copy link
Member

Why?

  1. No todo 😄
  2. Always load config if your pass config.path, now it is not working as expected if i pass config.path and sourceMap: false my config file not loading -> options.config && !sourceMap && length > 1 (i want to load config and set sourceMap use loader options ), also sometimes i want setup some option from options loader.
  3. Some perf (we don't create rc object because it is not necessary if i use only options without options.config)
  4. Allow to passing options to postcss throw loader.options, now it is possibly only using postcss config.

@alexander-akait
Copy link
Member Author

/cc @michael-ciniawsky friendly ping

package.json Outdated
@@ -33,6 +33,7 @@
"docs": "jsdoc2md lib/index.js > LOADER.md",
"pretest": "npm run lint && npm run test:build",
"test": "jest",
"test-only": "npm run test:build && jest",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this ? 😛

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky when i write code i want run only test to avoid regression (without lint), full test with lint and test i do before PR 😄

lib/index.js Outdated
to: file,
from: file,
map: sourceMap
? sourceMap === 'inline'
? { inline: true, annotation: false }
: { inline: false, annotation: false }
: false
}, config.options)
}, options, config.options)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will options from webpack.config.js e.g

{
  test: /\.css$/,
  use: [ { loader: 'postcss-loader', options: { parser: 'sugarss' } ]
}

be assigned when postcss.config.js is present ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky using options allow change map, it is bad, for some it is misleading behavior, but to and from now also we can change through config.options. I think about this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using options allow change map, it is bad, for some it is misleading behavior

? 🙃 You mean that currently one has to set map via { sourceMap: true || 'inline' } (webpack.config.js) exclusively?

but to and from now also we can change through config.options

They shouldn't be changeable, since File I/O is handled by the webpack (Runner) 😛

lib/index.js Outdated

return postcssrc(rc.ctx, rc.path, { argv: false })
}).then((config) => {
if (!config) config = {}

if (config.file) this.addDependency(config.file)

const sourceMap = options.sourceMap
delete options.sourceMap
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caused problems on 'multiple' runs for some weird reason, but maybe because it was defined in the wrong place, not sure here tbh ¯_(ツ)_/¯. It work for the first loader run and was then missing for all further runs, which lead to const sourceMap being always undefined. Besides that delete options.sourceMap => options.sourceMap = null (perf) ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky weird, should works, I will test in the near future

lib/index.js Outdated
},
options: {}
Promise.resolve().then(() => {
if (!options.config || (options.config && !options.config.path)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes to config loading behaviour ? See comment below where options get reassigned

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky we don't load postcss config file when config not present or present but without path.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postcss-load-config has it's config lookup algo backed in via cosmiconfig, options.config.path should only be used for cases like

|– .config
| |– postcss.config.js
|– src
| |– style.css
|
|– webpack.config.js

The current trigger for loading postcss.config.js is if no other options are set in webpack.config.js =>postcss.config.js

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky current behavior not works as expected we should fix this, see #234 (comment) (point 2).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky two solution:

  1. Load postcss config always and them merge option from loader with config options (i think loader options more important than postcss config option, but ).
  2. Load postcss config only when config: true or config: { path: '/path/to/config'} (best way, no problems with perf and understandable using)

@michael-ciniawsky michael-ciniawsky added this to the 2.0.6 milestone May 17, 2017
@michael-ciniawsky michael-ciniawsky changed the title refactor: improved loading algorithm of options and configs. refactor: improved loading algorithm of options and configs May 17, 2017
@alexander-akait alexander-akait force-pushed the refactor-options branch 2 times, most recently from e794dab to bce5503 Compare May 18, 2017 21:29
@alexander-akait
Copy link
Member Author

alexander-akait commented May 18, 2017

@michael-ciniawsky we should finish and merge this PR asap, i spend about 5 hours for migrate to new postcss loader in most of my projects, in half the configuration is not loaded or source maps not working, current loading algorithm is misleading and incorrect.

My solution:

  1. By default config is false and don't load postcss config.
  2. If your have config: true or config: { ctx : {...options}} we loading config (also working good for nested config). Now config: true is disable by schema, but we can fix this.
  3. If your have config: { path: '/path/to/config' } we loading config (absolutly path).

This may seem small breaking changed, but it is bugfix, because now postcss config don't loading in most use case.

@alexander-akait alexander-akait force-pushed the refactor-options branch 2 times, most recently from fab9590 to 62e2a2b Compare May 18, 2017 21:42
let options = Object.assign({

// Disable override `to` option
if (config.options.to) delete config.options.to
Copy link
Member Author

@alexander-akait alexander-akait May 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disable override important options from postcss config. it is break build.

options.parser = params.parser
options.syntax = params.syntax
options.stringifier = params.stringifier
const options = {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We always have params as object, because we have const options = loaderUtils.getOptions(this) || {}

lib/index.js Outdated
// Read options from options.config only when options.config is object
if (typeof options.config === 'object' &&
options.config !== null &&
Object.prototype.toString.call(options.config) === '[object Object]'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Special for config: true

parser: params.parser,
syntax: params.syntax,
stringifier: params.stringifier,
map: params.sourceMap
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postcss-load-config return map, we should also return map from parseOptions (consistently and don't misleading for future options).

@alexander-akait alexander-akait force-pushed the refactor-options branch 3 times, most recently from c8848bd to 75965c0 Compare May 18, 2017 22:09

return config
})
}).then((config) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config is always object parseOptions return object and postcss-load-config also return object

@michael-ciniawsky
Copy link
Member

I'm not in favour of changing the config loader behaviour to {config: true }. This neglects the reason for postcss.config.js which is simply to have no in webpack.config.js for most cases at all. I'm also concerned about merging options from (webpack.config.js) && (postcss.config.js). It should be a single source of truth and therefore an either or, I don't see the usecase for this, but if besides an edge case or personal perference one exists we can change it.

Always load config if your pass config.path, now it is not working as expected if i pass config.path and sourceMap: false my config file not loading -> options.config && !sourceMap && length > 1 (i want to load config and set sourceMap use loader options ), also sometimes i want setup some option from options loader.

{ sourceMap: false } is basically unnessecary (default), just omit it, we need to fix the conditional checks for sure agreed upon that, but without breaking the current behaviour

Some perf (we don't create rc object because it is not necessary if i use only options without options.config)

👍

Allow to passing options to postcss throw loader.options, now it is possibly only using postcss config.

What kind of options besides parser || syntax || stringifier && plugins ? The only two suitable options for map are external or inline as an annotation comment, which works via sourceMap: true || 'inline', from, to are handled by webpack aswell

@alexander-akait
Copy link
Member Author

alexander-akait commented May 19, 2017

@michael-ciniawsky

I'm not in favour of changing the config loader behaviour to {config: true }. This neglects the reason for postcss.config.js which is simply to have no in webpack.config.js for most cases at all. I'm also concerned about merging options from (webpack.config.js) && (postcss.config.js). It should be a single source of truth and therefore an either or, I don't see the usecase for this, but if besides an edge case or personal perference one exists we can change it.

Why now algorithm don't work as expected:

!options.config && !sourceMap && length

I want to use postcss.config.js (options.config is undefined) and disable source map (sourceMap is true), but not setup absolute config path.

options.config && !sourceMap && length > 1

I want to use config (absolutly, options.config is { path: "/path/to/config/"}) and disable source map (sourceMap is false or undefined) (see #234 (comment) point 2).

!options.config && sourceMap && length > 1

Seems works as expected.

options.config && sourceMap && length > 2

I want to use config and have source map, also i have exec. Why my postcss config don't loading.

{ sourceMap: false } is basically unnessecary (default), just omit it, we need to fix the conditional checks for sure agreed upon that, but without breaking the current behaviour

I can't change this in many boilerplate (many of popular them use this option also in config). It is using for all loader options from config.

config.js

module.exports = {
    // ...
    sourceMap: false,
    // ...
};

And in webpack.config.js it is setup to all loaders.

What kind of options besides parser || syntax || stringifier && plugins ? The only two suitable options for map are external or inline as an annotation comment, which works via sourceMap: true || 'inline', from, to are handled by webpack aswell

exec option example. Now also don't work see above.

@michael-ciniawsky
Copy link
Member

michael-ciniawsky commented May 20, 2017

The current loading algo is crap for sure, but still the behaviour shouldn't change :)

{ config: true } or similiar isn't an option (neglect's zero config approach)

postcss.config.js

module.exports = ({ file, options, env }) => ({
   // Maybe support options for `map` (PostCSS),
   // but `true` || `inline` handles that fine for the 99% cases,
   // webpack also sets specific requirements here
    sourceMap: options.sourceMap 
});

The reason for not supporting sourceMap within postcss.config.js is during the fact that, it should work with different PostCSS middlewares and therefore only supports PostCSS options && plugins (middleware agnostic). All other middleware related options are set, where the particular middleware normally provides an interface to do so. { sourceMap: true } is a webpack (postcss-loader) specific option and is better defined in webpack.config.js

webpack.config.js

{
   test: '..',
   use: [
     { loader: 'style-loader', options: { sourceMap: env === 'development' ? true : false} },
     { loader: 'css-loader', options: { sourceMap: env === 'development' ? true : false } },
     // { loader: 'postcss-loader', options: { sourceMap: env === 'development' ? true : false } },
     // Usage worst case scenario
     { 
       loader: 'postcss-loader', 
       options: { config: { ctx: { sourceMap: env === 'development' ? true : false } } } 
     },
     { loader: 'sass-loader', options: { sourceMap: env === 'development' ? true : false } }
   ]
}

All we need is to find a better way to filter the loader options and either parse the options, if we have additional ones (parser &&|| plugins), or try to load a config file

@alexander-akait
Copy link
Member Author

alexander-akait commented May 22, 2017

@michael-ciniawsky Today (sorry, few time 😞 ) I will create a table with all the options and behavior that should, so it will be easier to come to a final decision.

@alexander-akait
Copy link
Member Author

@TrySound Maybe you can help us and with this?

@alexander-akait
Copy link
Member Author

@alexander-akait
Copy link
Member Author

@michael-ciniawsky also adding any options to options (test: true) break all loading logic.

@michael-ciniawsky
Copy link
Member

@evilebottnawi Please reduce the PR here only to your proposed sourceMap changes

@alexander-akait
Copy link
Member Author

@michael-ciniawsky this PR contain only relevant changed

Copy link
Member

@michael-ciniawsky michael-ciniawsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does the sourceMap config in postcss.config.js look like ? A small example please

if (options.config.path) {
rc.path = path.resolve(options.config.path)
Promise.resolve().then(() => {
if (options.exec || options.parser || options.syntax || options.stringifier || options.plugins) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky why? your ugly algo is don't work as expected

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

if (options.config.ctx) {
rc.ctx.options = options.config.ctx
const rc = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky we don't need rc if we don't load config

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -32,6 +32,7 @@
"docs": "jsdoc2md lib/index.js > LOADER.md",
"pretest": "npm run lint && npm run test:build",
"test": "jest",
"test-only": "npm run test:build && jest && npm run clean",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky How can I run only tests?

// Disable override `map` option
if (config.options.map) delete config.options.map

let postcssOption = Object.assign({
Copy link
Member

@michael-ciniawsky michael-ciniawsky Jun 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this renamed? Should be options

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky because options related to loader (const options = loaderUtils.getOptions(this) || {}), postcssOptions related to postcss options

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works atm due to lexical scope, as long as there is no need to rename it please leave it as is

}

return postcssrc(rc.ctx, rc.path, { argv: false })
}).then((config) => {
if (!config) config = {}
.then((config) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong ident

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky don't understand, please provide example

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the code indentation is off :), at least looks it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-ciniawsky

return postcssrc(rc.ctx, rc.path, { argv: false })
      .then((config) => {
        // Get `sourceMap` option from loader options when no `map` option in `postcss.config.js`
        if (!config.options.map) config.options.map = options.sourceMap

        return config
      })

Where?

@alexander-akait
Copy link
Member Author

@michael-ciniawsky true || inline

@michael-ciniawsky
Copy link
Member

But that's not the only two options for map, what happens of e.g { inline: true, annotation: false } is directly passed via postcss.config does it work ?

@alexander-akait
Copy link
Member Author

alexander-akait commented Jun 14, 2017

@michael-ciniawsky Do your have specific examples of why this code is not working (example of config or failed tests), all tests are passed, or is this a subjective non-constructive mono solution?

@alexander-akait alexander-akait force-pushed the refactor-options branch 2 times, most recently from 531041a to 22ed94f Compare June 14, 2017 15:18
@michael-ciniawsky
Copy link
Member

Do you have specific examples of why this code is not working (example of config or failed tests), all tests are passed, or is this a subjective non-constructive mono solution?

You mean the config resolving here ?

@alexander-akait
Copy link
Member Author

alexander-akait commented Jun 14, 2017

@michael-ciniawsky i mean where algo don't work as expected

@alexander-akait
Copy link
Member Author

@michael-ciniawsky #259 Thanks for respect my work and my time.

@alexander-akait alexander-akait deleted the refactor-options branch June 14, 2017 15:24
@michael-ciniawsky
Copy link
Member

michael-ciniawsky commented Jun 14, 2017

const length = Object.keys(options)
      .filter((option) => {
        // if (option === 'exec') return
        if (option === 'config') return
        if (option === 'sourceMap') return

        return option
      })
      .length

    if (length) {
      return parseOptions.call(this, options)
    }

    const rc = {
      path: path.dirname(file),
      ctx: {
        file: {
          extname: path.extname(file),
          dirname: path.dirname(file),
          basename: path.basename(file)
        },
        options: {}
      }
    }

    if (options.config) {
      if (options.config.path) {
        rc.path = path.resolve(options.config.path)
      }

      if (options.config.ctx) {
        rc.ctx.options = options.config.ctx
      }
    }

    return postcssrc(rc.ctx, rc.path, { argv: false })

You can also take that and I close #259, it was just as another approach to test and discuss for now

https://github.com/postcss/postcss-loader/blob/master/lib/index.js#L99

postcss.config.js

module.exports = (ctx) => ({
  map: { inline: true, annotation: false }
}) 

Will this work ?

@michael-ciniawsky
Copy link
Member

Why are you closing this now? 🙃

@alexander-akait
Copy link
Member Author

alexander-akait commented Jun 14, 2017

@michael-ciniawsky because I'm tired of non constructive argument and ignoring, for me it will be faster to create fork.

Will this work ?

No, because your say:

The only two suitable options for map are external or inline as an annotation comment, which works via sourceMap: true || 'inline', from, to are handled by webpack aswell

@michael-ciniawsky
Copy link
Member

michael-ciniawsky commented Jun 14, 2017

What do you mean by non-constructive argument and ignoring ? Ignoring is just plain wrong... Disagreement !== Ignoring

Constrcutive or not is subjective, but

  • The PR at first changed the config loading enterily and I explained more then once, why I don't think it is a good idea to do it that way

  • For sourceMap my concern is that there will be confusion about it, when postcss.config.js supports it, but I'm not against it in general (there would still heve been edge case in the PR as is )

  • The other PR was not meant offensive in any way and I have had no problem by just closing it, I don't care about these things

let options = Object.assign({
      to: file,
      from: file,
      map: sourceMap // <=
        ? sourceMap === 'inline'
          ? { inline: true, annotation: false }
          : { inline: false, annotation: false }
        : false
}, config.options)

This would require additional changes to work with all possible options map PostCSS (postcss.config.js) supports

@alexander-akait
Copy link
Member Author

alexander-akait commented Jun 14, 2017

@michael-ciniawsky

  1. Your just close my PR without explaining what is wrong - it is non-constructive.
  2. Your say

The only two suitable options for map are external or inline as an annotation comment, which works via sourceMap: true || 'inline', from, to are handled by webpack aswell

Because i do only true and inline value supporting for sourceMap

  1. Ignoring - refactor: improved loading algorithm of options and configs #234 (comment), refactor: improved loading algorithm of options and configs #234 (comment), refactor: improved loading algorithm of options and configs #234 (comment), refactor: improved loading algorithm of options and configs #234 (comment)
  2. No Respect for my time and effort, thanks

Just don't ignore #259 and merge PR to solve issue

@michael-ciniawsky
Copy link
Member

michael-ciniawsky commented Jun 14, 2017

kk, can we please in general agree to take it a bit more relaxed and avoid the childish behaviour ?

your just close my PR without explaining what is wrong - it is non-constructive.

When I closed the PR is still changed the loading behaviour, that was the reason

Your say

The only two suitable options for map are external or inline as an annotation comment, which
works via sourceMap: true || 'inline', from, to are handled by webpack aswell
Because I do only true and inline value supporting for sourceMap

Yes, that's the two ways to handle sourcemaps, postcss.config.js supports {Object} e.g { inline: true, annotation: false } which postcss-loader needs handle aswell then, which is ok if needed

Ignoring - #234 (comment), #234 (comment), #234 (comment), #234 (comment)

I answered all of them and the second isn't even addressed at me 🙃

No Respect for my time and effort, thanks

I hearing this for the third+ time now, what about other people's time ? This is just trying to personify matters to passive aggressively offend && push others to do what you want? As I said I don't mind closing my PR's, waste my time in your speaking and in general the least thing I intend to do is to actively disrespect others. Which is disagree I did in anyway, but if you felt that way I apologize

@alexander-akait
Copy link
Member Author

@michael-ciniawsky thanks for apologize, let's first fix unexpected behavior with sourceMap #259

@alexander-akait
Copy link
Member Author

@michael-ciniawsky and then solve problems: should we respect map from postcss.config.js and how we should do this, or now all ok

@michael-ciniawsky
Copy link
Member

michael-ciniawsky commented Jun 14, 2017

should we respect map from postcss.config.js

Yes, but we need to add a check / refactor https://github.com/postcss/postcss-loader/blob/master/lib/index.js#L99 properly to support 'full' PostCSS Sourcemap Options {Object}, also the config.options.from/config.options.to sanitizing you added was a good idea

@michael-ciniawsky
Copy link
Member

Also check if some possible PostCSS Sourcemap Options doesn't play well with webpack (I don't know 💯 yet)

@michael-ciniawsky michael-ciniawsky modified the milestone: 2.0.7 Jun 14, 2017
laracasts pushed a commit to laravel-mix/laravel-mix that referenced this pull request Jun 26, 2017
Honestly, I have no idea why this fixes the glitch. But read about it
here:
webpack-contrib/postcss-loader#234 (comment)
6

And it worked. :|
devstar0826 added a commit to devstar0826/laravel-mix that referenced this pull request Oct 22, 2019
Honestly, I have no idea why this fixes the glitch. But read about it
here:
webpack-contrib/postcss-loader#234 (comment)
6

And it worked. :|
dreamhigh0525 pushed a commit to dreamhigh0525/laravel-mix that referenced this pull request Mar 8, 2023
Honestly, I have no idea why this fixes the glitch. But read about it
here:
webpack-contrib/postcss-loader#234 (comment)
6

And it worked. :|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants