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

Throwing an error when a variable is not defined #16

Open
oxidizing8018 opened this issue Jul 12, 2018 · 3 comments
Open

Throwing an error when a variable is not defined #16

oxidizing8018 opened this issue Jul 12, 2018 · 3 comments

Comments

@oxidizing8018
Copy link

oxidizing8018 commented Jul 12, 2018

These are my options:

const opts = {
  "ifdef-verbose": true,
  "ifdef-triple-slash": true
};

In some .js file I have:

/// #if STATS
console.log('stats defined');
/// #else
console.log('stats not defined');
/// #endif

And when I try running my project:

Module build failed: Error: ifdef-loader error: error evaluation #if condition(STATS): ReferenceError: STATS is not defined

Obviously I didn't defined STATS in the loader options. But, why throw an error if STATS is not defined? For me makes no sense to throw an error in this case, I would expect that the '#if STATS' part is removed and the '# else' part is kept.

Is this the desired behaviour, or am I missing something?

@nippur72
Copy link
Owner

I would say it's desidered behaviour: what comes after the if is evaluated as a plain JavaScript expression, so throwing ReferenceError is expected to happen if STATS is not defined at all (at least in strict mode).

I don't think that can be fixed easily since the loader doesn't have its own expression parser, it just uses something like eval() to evaluate expressions.

And you can't just trap the error and resolve to false because it wouldn't work if you write #if !STATS.

Possible workarounds:

  • initilize with STATS: undefined
  • check with #if typeof STATS === 'undefined'

@oxidizing8018
Copy link
Author

oxidizing8018 commented Jul 12, 2018

Just for clarification, what I was trying to achieve is to have two different configurations, one for development and other for production:

dev: {
  DEVELOPMENT: true,
  STATS: true,
},
prod: {
  PRODUCTION: true,
}

Now I'm forced to duplicate the defines:

dev: {
  DEVELOPMENT: true,
  PRODUCTION: false,
  STATS: true,
},
prod: {
  DEVELOPMENT: false,
  PRODUCTION: true,
  STATS: false
}

I don't like this solution, so I will go with your workaround #if typeof STATS === 'undefined'.

Thanks a lot for the quick response!

@oxidizing8018
Copy link
Author

oxidizing8018 commented Jul 12, 2018

I've modified the beginning of the evaluate() function in preprocessor.js and added the following code:

function evaluate(condition, keyword, defs) {
  condition = condition.replace(/defined\( *([a-z|A-Z|0-9|_]+) *\)/g, (match, p1) => {
    return defs[p1] === true;
  })
  ...
}

This allow me to write options in this way:

dev: {
  DEVELOPMENT: true,
  STATS: true,
},
prod: {
  PRODUCTION: true,
}

and use the preprocessor defines in this way:

/// #if defined(STATS)
console.log('stats defined');
/// #endif

If STATS is not defined there is no error thrown. I don't like to modify library sources directly but I prefer to work in this way.

Thanks for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants