|
| 1 | +--- |
| 2 | +title: "Inlining Constants" |
| 3 | +description: "Inlining constants" |
| 4 | +canonical: "/docs/manual/latest/inlining-constants" |
| 5 | +--- |
| 6 | + |
| 7 | +# Inlining Constants |
| 8 | + |
| 9 | +Sometime, in the JavaScript output, you might want a certain value to be forcefully inlined. For example: |
| 10 | + |
| 11 | +```js |
| 12 | +if (process.env.mode === 'development') { |
| 13 | + console.log("Dev-only code here!") |
| 14 | +} |
| 15 | +``` |
| 16 | + |
| 17 | +The reason is that your JavaScript bundler (e.g. Webpack) might turn that into: |
| 18 | + |
| 19 | +```js |
| 20 | +if ('production' === 'development') { |
| 21 | + console.log("Dev-only code here!") |
| 22 | +} |
| 23 | +``` |
| 24 | + |
| 25 | +Then your subsequent Uglifyjs optimization would remove that entire `if` block. This is how projects like ReactJS provide a development mode code with plenty of dev warnings, while ensuring that the uglified (minified) production code is free of those expensive blocks. |
| 26 | + |
| 27 | +So, in ReScript, producing that example `if (process.env.mode === 'development')` output is important. This first try doesn't work: |
| 28 | + |
| 29 | +<CodeTab labels={["ReScript", "JS Output"]}> |
| 30 | + |
| 31 | +```res example |
| 32 | +@bs.val external process: 'a = "process" |
| 33 | +
|
| 34 | +let mode = "development" |
| 35 | +
|
| 36 | +if (process["env"]["mode"] === mode) { |
| 37 | + Js.log("Dev-only code here!") |
| 38 | +} |
| 39 | +``` |
| 40 | +```js |
| 41 | +var mode = "development"; |
| 42 | + |
| 43 | +if (process.env.mode === mode) { |
| 44 | + console.log("Dev-only code here!"); |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +</CodeTab> |
| 49 | + |
| 50 | +The JS output shows `if (process.env.mode === mode)`, which isn't what we wanted. To inline `mode`'s value, use `@bs.inline`: |
| 51 | + |
| 52 | +<CodeTab labels={["ReScript", "JS Output"]}> |
| 53 | + |
| 54 | +```res example |
| 55 | +@bs.val external process: 'a = "process" |
| 56 | +
|
| 57 | +@bs.inline |
| 58 | +let mode = "development" |
| 59 | +
|
| 60 | +if (process["env"]["mode"] === mode) { |
| 61 | + Js.log("Dev-only code here!") |
| 62 | +} |
| 63 | +``` |
| 64 | +```js |
| 65 | +if (process.env.mode === "development") { |
| 66 | + console.log("Dev-only code here!"); |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +</CodeTab> |
| 71 | + |
| 72 | +Now your resulting JS code can pass through Webpack and Uglifyjs like the rest of your JavaScript code, and that whole `console.log` can be removed. |
| 73 | + |
| 74 | +The inlining currently only works for **string, float and boolean**. |
| 75 | + |
| 76 | +## Tips & Tricks |
| 77 | + |
| 78 | +This is **not** an optimization. This is an edge-case feature for folks who absolutely need particular values inlined for a JavaScript post-processing step, like conditional compilation. Beside the difference in code that the conditional compilation might end up outputting, there's no performance difference between inlining and not inlining simple values in the eyes of a JavaScript engine. |
0 commit comments