1 | # Babel Debug Macros And Feature Flags
|
2 |
|
3 | This provides debug macros and feature flagging.
|
4 |
|
5 | ## Setup
|
6 |
|
7 | The plugin takes 4 types options: `flags`, `svelte`, `debugTools`, and
|
8 | `externalizeHelpers`. The `importSpecifier` is used as a hint to this plugin as
|
9 | to where macros are being imported and completely configurable by the host.
|
10 |
|
11 | Like Babel you can supply your own helpers using the `externalizeHelpers`
|
12 | options.
|
13 |
|
14 | ```js
|
15 | {
|
16 | plugins: [
|
17 | ['babel-debug-macros', {
|
18 | // @optional
|
19 | debugTools: {
|
20 | isDebug: true,
|
21 | source: 'debug-tools',
|
22 | // @optional
|
23 | assertPredicateIndex: 0
|
24 | },
|
25 |
|
26 | flags: [
|
27 | { source: '@ember/env-flags', flags: { DEBUG: true } },
|
28 | {
|
29 | name: 'ember-source',
|
30 | source: '@ember/features',
|
31 | flags: {
|
32 | FEATURE_A: false,
|
33 | FEATURE_B: true,
|
34 | DEPRECATED_CONTROLLERS: "2.12.0"
|
35 | }
|
36 | }
|
37 | ],
|
38 |
|
39 | // @optional
|
40 | svelte: {
|
41 | 'ember-source': "2.15.0"
|
42 | },
|
43 |
|
44 | // @optional
|
45 | externalizeHelpers: {
|
46 | module: true,
|
47 | // global: '__my_global_ns__'
|
48 | }
|
49 | }]
|
50 | ]
|
51 | }
|
52 | ```
|
53 |
|
54 | Flags and features are inlined into the consuming module so that something like UglifyJS will DCE them when they are unreachable.
|
55 |
|
56 | ## Simple environment and feature flags
|
57 |
|
58 | ```javascript
|
59 | import { DEBUG } from '@ember/env-flags';
|
60 | import { FEATURE_A, FEATURE_B } from '@ember/features';
|
61 |
|
62 | if (DEBUG) {
|
63 | console.log('Hello from debug');
|
64 | }
|
65 |
|
66 | let woot;
|
67 | if (FEATURE_A) {
|
68 | woot = () => 'woot';
|
69 | } else if (FEATURE_B) {
|
70 | woot = () => 'toow';
|
71 | }
|
72 |
|
73 | woot();
|
74 | ```
|
75 |
|
76 | Transforms to:
|
77 |
|
78 | ```javascript
|
79 | if (true /* DEBUG */) {
|
80 | console.log('Hello from debug');
|
81 | }
|
82 |
|
83 | let woot;
|
84 | if (false /* FEATURE_A */) {
|
85 | woot = () => 'woot';
|
86 | } else if (true) {
|
87 | woot = () => 'toow';
|
88 | }
|
89 |
|
90 | woot();
|
91 | ```
|
92 |
|
93 | ## `warn` macro expansion
|
94 |
|
95 | ```javascript
|
96 | import { warn } from 'debug-tools';
|
97 |
|
98 | warn('this is a warning');
|
99 | ```
|
100 |
|
101 | Expands into:
|
102 |
|
103 | ```javascript
|
104 | (true && console.warn('this is a warning'));
|
105 | ```
|
106 |
|
107 | ## `assert` macro expansion
|
108 |
|
109 | The `assert` macro can expand in a more intelligent way with the correct
|
110 | configuration. When `babel-plugin-debug-macros` is provided with the
|
111 | `assertPredicateIndex` the predicate is injected in front of the assertion
|
112 | in order to avoid costly assertion message generation when not needed.
|
113 |
|
114 | ```javascript
|
115 | import { assert } from 'debug-tools';
|
116 |
|
117 | assert((() => {
|
118 | return 1 === 1;
|
119 | })(), 'You bad!');
|
120 | ```
|
121 |
|
122 | With the `debugTools: { assertPredicateIndex: 0 }` configuration the following expansion is done:
|
123 |
|
124 | ```js
|
125 | (true && !((() => { return 1 === 1;})()) && console.assert(false, 'this is a warning'));
|
126 | ```
|
127 |
|
128 | When `assertPredicateIndex` is not specified, the following expansion is done:
|
129 |
|
130 | ```javascript
|
131 | (true && console.assert((() => { return 1 === 1;})(), 'this is a warning'));
|
132 | ```
|
133 |
|
134 | ## `deprecate` macro expansion
|
135 |
|
136 | ```javascript
|
137 | import { deprecate } from 'debug-tools';
|
138 |
|
139 | let foo = 2;
|
140 |
|
141 | deprecate('This is deprecated.', foo % 2);
|
142 | ```
|
143 |
|
144 | Expands into:
|
145 |
|
146 | ```javascript
|
147 | let foo = 2;
|
148 |
|
149 | (true && !(foo % 2) && console.warn('This is deprecated.'));
|
150 | ```
|
151 |
|
152 | ## Externalized Helpers
|
153 |
|
154 | When you externalize helpers you must provide runtime implementations for the
|
155 | above macros. An expansion will still occur, however we will emit references to
|
156 | those runtime helpers.
|
157 |
|
158 | A global expansion looks like the following:
|
159 |
|
160 | ```javascript
|
161 | import { warn } from 'debug-tools';
|
162 |
|
163 | warn('this is a warning');
|
164 | ```
|
165 |
|
166 | Expands into:
|
167 |
|
168 | ```javascript
|
169 | (true && Ember.warn('this is a warning'));
|
170 | ```
|
171 |
|
172 | While externalizing the helpers to a module looks like the following:
|
173 |
|
174 | ```javascript
|
175 | import { warn } from 'debug-tools';
|
176 |
|
177 | warn('this is a warning');
|
178 | ```
|
179 |
|
180 | Expands into:
|
181 |
|
182 | ```javascript
|
183 | (true && warn('this is a warning'));
|
184 | ```
|
185 |
|
186 | # Svelte
|
187 |
|
188 | Svelte allows for consumers to opt into stripping deprecated code from your
|
189 | dependecies. By adding a package name and minimum version that contains no
|
190 | deprecations, that code will be compiled away.
|
191 |
|
192 | For example, consider you are on `ember-source@2.10.0` and you have no
|
193 | deprecations. All deprecated code in `ember-source` that is `<=2.10.0` will be
|
194 | removed.
|
195 |
|
196 | ```
|
197 |
|
198 | svelte: {
|
199 | "ember-source": "2.10.0"
|
200 | }
|
201 |
|
202 | ```
|
203 |
|
204 | Now if you bump to `ember-source@2.11.0` you may encounter new deprecations.
|
205 | The workflow would then be to clear out all deprecations and then bump the
|
206 | version in the `svelte` options.
|
207 |
|
208 | ```
|
209 | svelte: {
|
210 | "ember-source": "2.11.0"
|
211 | }
|
212 | ```
|