Skip to content

Commit 9ccf19f

Browse files
committed
Add bs.inline
1 parent 2e5c7b6 commit 9ccf19f

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

layouts/ManualDocsLayout.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ let jsInteropNavs = [|
100100
href: "/docs/manual/latest/bind-to-global-js-values",
101101
},
102102
{name: "JSON", href: "/docs/manual/latest/json"},
103+
{name: "Inlining Constants", href: "/docs/manual/latest/inlining-constants"},
103104
{
104105
name: "Use Illegal Identifier Names",
105106
href: "/docs/manual/latest/use-illegal-identifier-names",
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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

Comments
 (0)