webpack-obfuscator icon indicating copy to clipboard operation
webpack-obfuscator copied to clipboard

process variable is undefined when use DefinePlugin

Open Katarn opened this issue 4 years ago • 2 comments

I wrote about this bug in another issue, but it is already closed, it would probably be more correct to make a separate issue in a more suitable repository for this.

I made a minimal example.

Just run npm ci && npm run build. After that, in the dist directory, you will see the main.js file. Open it in a code editor and you will see something like:

....shift())}}(n),process[r(309)][r(311)]&&console[r(302)](r(311))})();...

Of course, the process variable is undefined. Moreover, it should not be in the code, it should either be replaced with true (according to this line), or, with "smart optimization", the if (...) check block should not exist at all, since it will always be executed.

Then you can uncomment these two lines (not necessarily at the same time, you can uncomment them separately) and see how the code is generated in the main.js file.

Katarn avatar Aug 06 '21 14:08 Katarn

This is how I fixed it:

/* javascript-obfuscator:disable */
const endpoint = `${process.env.VUE_APP_API_DOMAIN}/api/v1`
/* javascript-obfuscator:enable */

thierrymichel avatar Oct 04 '21 10:10 thierrymichel

This problem still exists. The problem is that javascript-obfuscator's stringArray option/mode replaces env and VUE_APP_API_DOMAIN (or some other env variable) with string array lookups for the property names.

Once those replacements are made, the substitution logic performed by DefinePlugin and dotenv-webpack won't work.

One way to fix this is with stringArray: false. However, that effectively disables much of the obfuscation.

Another solution is to use the webpack-obfuscator Webpack plugin instead of the loader. The webpack-obfuscator plugin can run after the Dotenv (or similar) plugin which will enable that plugin to make the substitution first.

Yet another solution is effectively the same as proposed by @thierrymichel. I didn't want to use a template literal since I'm using the value in an expression, so I ended up using something like this:

if(/* javascript-obfuscator:disable */process.env.NODE_ENV/* javascript-obfuscator:enable */ === 'development') {
    ...
}

//or

/* javascript-obfuscator:disable */
if(process.env.NODE_ENV === 'development') {
/* javascript-obfuscator:enable */
    ...
}

Although the first solution in the code excerpt above is messy, it isolates the identifier better and will likely lead to fewer obfuscation errors.

rinogo avatar Mar 02 '22 22:03 rinogo