nippur72 / ifdef-loader

Webpack loader for JavaScript/TypeScript conditional compilation.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use ifdef-loader with ESLint

and-semakin opened this issue · comments

Hi! Thank you for the tool!

Is there a way to use ifdef-loader with ESLint?

I try to conditionally import two files, but ESLint says that the syntax is broken:

// #if USE_FLASH
import embedpano from 'lib/krpano_flash/swfkrpano';
// #else
import embedpano from 'lib/krpano/krpano';
// #endif

ESLint output:

10:8  error  Parsing error: Identifier 'embedpano' has already been declared

I have the same issue. Is there any plan to fix this or suggestion for workaround?

Unfortunately this is not easy to solve. Because ifdef-loader syntax resides in a // comment, there are lot of cases where the resulting unprocessed code is not a valid code. This is this tool's biggest limitation.

When I have cases like that, I switch back to a simple if() else, letting webpack/Uglify remove the unused code. E.g.

if(USE_FLASH) {
  ...
} else {
  ...
}

Now this is a bad example because imports can't be put under if()s, but there are lot of other cases where this trick does apply.

commented

I had a similar issue and after many other variants I only found the following workaround.

Not really nice code, but it works for me in the context of a clientside app with typescript, vue and webpack.

theming.vue

<script lang="ts">
let foo: any;

/// #if THEME=='special'
import special from "./themes/special/foo.vue";
// standard
/// #else
import standard from "./themes/standard /foo.vue";
/// #endif

if (typeof special != "undefined")
	foo= special;
else if (typeof standard != "undefined")
	foo= standard;

export default foo;
</script>

In my case I can go trough the eslint and typescript pipeline.

To solve this problem, ifdef-loader should optionally allow something like this:

/// #if USE_FLASH
import embedpano from 'lib/krpano_flash/swfkrpano';
/// #else
/// import embedpano from 'lib/krpano/krpano';
/// #endif

Obviously it's perfectly legit code for any linting system because all of the #else block is commented

ifdef-loader should remove all beginning-of-line triple-slashs in #elif and #else block at compile-time

@tomchen wow, neat idea!

For now, we could use

let embedpano
/// #if USE_FLASH
embedpano = require('lib/krpano_flash/swfkrpano')
/// #else
embedpano = require('lib/krpano/krpano')
/// #endif

(CommonJS require() is synchronous and similar to static import)

or

/// #if USE_FLASH
import embedpano1 from 'lib/krpano_flash/swfkrpano';
// #else
import embedpano2 from 'lib/krpano/krpano';
/// #endif
const embedpano = typeof embedpano1 !== "undefined" ? embedpano1 : embedpano2

But the aforementioned #else block comment should be a better way if implemented in ifdef-loader


ifdef-loader provides a reliable way to conditionally eliminate code, if we do something like

const USE_FLASH = true
// ...
const embedpano = USE_FLASH ? require('lib/krpano_flash/swfkrpano') : require('lib/krpano/krpano')

Then both 'lib/krpano_flash/swfkrpano' and 'lib/krpano/krpano' will probably be included in the final code (this depends on how far the dead code elimination of babel, webpack, uglify, terser could reach, and is not that predictable), which is likely not what we want.

this is now addressed in v2.3.0 with the option ifdef-uncomment-prefix (see the README).