geoyws
geoyws

Reputation: 3687

Why does Webpack's DefinePlugin require us to wrap everything in JSON.stringify?

new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(true),
    VERSION: JSON.stringify("5fa3b9"),
    BROWSER_SUPPORTS_HTML5: true,
    TWO: "1+1",
    "typeof window": JSON.stringify("object")
})

https://github.com/webpack/docs/wiki/list-of-plugins#defineplugin

This seems very unusual, unnecessary and "dev-error-prone".

Is it type-checking concerns?

Upvotes: 38

Views: 5585

Answers (1)

Felix Kling
Felix Kling

Reputation: 816272

The answer is below the example:

  • If the value is a string it will be used as a code fragment.
  • If the value isn't a string, it will be stringified (including functions).

I.e. the value of a string is inserted into the source code verbatim.

Passing JSON.stringify(true) or passing true directly is the same, since non-string values are converted to strings.

However, there is a big difference between JSON.stringify('5fa3b9') and "5fa3b9":

Assuming your code was

if (version === VERSION)

then VERSION: JSON.stringify('5fa3b9') would result in

if (version === "5fa3b9")

but VERSION: "5fa3b9" would result in

if (version === 5fa3b9)

which is invalid code.

Note that because the plugin does a direct text replacement, the value given to it must include actual quotes inside of the string itself. Typically, this is done either with either alternate quotes, such as '"production"', or by using JSON.stringify('production').

Upvotes: 52

Related Questions