Skip to content

Commit 9aa4e47

Browse files
committed
fix:add CommonJS and ESM examples
1 parent cf450f1 commit 9aa4e47

File tree

1 file changed

+141
-42
lines changed

1 file changed

+141
-42
lines changed

content/guide/hooks.md

Lines changed: 141 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,21 @@ The NativeScript CLI supports two different ways of executing hooks:
4141
**Basic Module Definition**
4242

4343
To write an in-process hook, use the following module definition:
44+
::: code-group
4445

45-
```javascript
46+
```javascript [thehook.mjs (ESM)]
47+
export default function (hookArgs) {
48+
// Hook implementation ESM
49+
}
50+
```
51+
52+
```javascript [thehook.js (CommonJS)]
4653
module.exports = function () {
47-
// Hook implementation
54+
// Hook implementation CommonJs
4855
}
4956
```
5057

58+
:::
5159
**Using hookArgs**
5260

5361
The hook function can accept a special argument named `hookArgs`, which is an object containing all arguments passed to the hooked method.
@@ -71,29 +79,58 @@ Then `hookArgs` will have the following structure:
7179
```
7280

7381
**Using hookArgs in your hook:**
82+
::: code-group
7483

75-
```javascript
84+
```javascript [thehook.mjs (ESM)]
85+
export default function (hookArgs) {
86+
console.log(JSON.stringify(hookArgs.prepareData))
87+
}
88+
```
89+
90+
```javascript [thehook.js (CommonJS)]
7691
module.exports = function (hookArgs) {
7792
console.log(hookArgs.projectData)
7893
}
7994
```
8095

96+
:::
8197
**Dependency Injection**
8298

8399
NativeScript CLI is built with Dependency Injection and executes in-process hooks in a way that allows you to use any registered service from the injector.
84100

85101
**_Approach 1: Direct Service Injection_**
86102

87-
```javascript
103+
::: code-group
104+
105+
```javascript [thehook.mjs (ESM)]
106+
export default function ($logger, $fs, $projectDataService, hookArgs) {
107+
$logger.info('Executing hook')
108+
// Use $fs, $projectDataService, etc.
109+
}
110+
```
111+
112+
```javascript [thehook.js (CommonJS)]
88113
module.exports = function ($logger, $fs, $projectDataService, hookArgs) {
89114
$logger.info('Executing hook')
90115
// Use $fs, $projectDataService, etc.
91116
}
92117
```
93118

119+
:::
94120
**_Approach 2: Injector Resolution_**
95121

96-
```javascript
122+
::: code-group
123+
124+
```javascript [thehook.mjs (ESM)]
125+
export default function ($injector, hookArgs) {
126+
const $logger = $injector.resolve('$logger')
127+
const $fs = $injector.resolve('$fs')
128+
129+
$logger.info('Executing hook')
130+
}
131+
```
132+
133+
```javascript [thehook.js (CommonJS)]
97134
module.exports = function ($injector, hookArgs) {
98135
const $logger = $injector.resolve('$logger')
99136
const $fs = $injector.resolve('$fs')
@@ -102,6 +139,8 @@ module.exports = function ($injector, hookArgs) {
102139
}
103140
```
104141

142+
:::
143+
105144
**Important Notes:**
106145

107146
- Injected dependencies are resolved by name
@@ -112,7 +151,25 @@ module.exports = function ($injector, hookArgs) {
112151

113152
NativeScript CLI supports asynchronous code in hooks. If executing async code, you must return a Promise:
114153

115-
```javascript
154+
::: code-group
155+
156+
```javascript [thehook.mjs (ESM)]
157+
import { mkdirp } from 'mkdirp'
158+
159+
export default function ($logger) {
160+
return new Promise(function (resolve, reject) {
161+
mkdirp('somedir', function (err) {
162+
if (err) {
163+
reject(err)
164+
} else {
165+
resolve()
166+
}
167+
})
168+
})
169+
}
170+
```
171+
172+
```javascript [thehook.js (CommonJS)]
116173
var mkdirp = require('mkdirp')
117174

118175
module.exports = function ($logger) {
@@ -128,6 +185,8 @@ module.exports = function ($logger) {
128185
}
129186
```
130187

188+
:::
189+
131190
## Spawned Hooks
132191

133192
Spawned hooks are executed via Node's `child_process.spawn` from the project's root directory. All options are passed to the script using environment variables:
@@ -146,27 +205,25 @@ If a spawned hook returns a non-zero exit code, NativeScript CLI will throw an e
146205

147206
Hooks can execute code before or after a specific action:
148207

149-
```javascript
150-
module.exports = function (hookArgs) {
208+
::: code-group
209+
210+
```javascript [thehook.mjs (ESM)]
211+
export default function (hookArgs) {
151212
if (hookArgs.prepareData.release) {
152213
console.log('Before executing release build.')
153214
}
154215
}
155216
```
156217

157-
**Replacement Hooks**
158-
159-
Hooks can replace the original CLI function (use sparingly):
160-
161-
```javascript
162-
module.exports = function (hookArgs, $logger) {
163-
return () => {
164-
$logger.info('Replaced the original CLI function.')
218+
```javascript [thehook.js (CommonJS)]
219+
module.exports = function (hookArgs) {
220+
if (hookArgs.prepareData.release) {
221+
console.log('Before executing release build.')
165222
}
166223
}
167224
```
168225

169-
**Note:** Replacement hooks should only be used in specific, rare cases. Before/after hooks are strongly recommended.
226+
:::
170227

171228
## Adding Hooks to Plugins
172229

@@ -180,20 +237,46 @@ npm install @nativescript/hook --save
180237

181238
**2. Create postinstall.js**
182239

183-
Create `postinstall.js` at the root folder of your plugin:
240+
Create a postinstall script at the root folder of your plugin:
241+
::: code-group
184242

185-
```javascript
243+
```javascript [postinstall.mjs (ESM)]
244+
import path from 'path'
245+
import hook from '@nativescript/hook'
246+
import { fileURLToPath } from 'url'
247+
248+
const __filename = fileURLToPath(import.meta.url)
249+
const __dirname = path.dirname(__filename)
250+
hook(path.join(__dirname, '..')).postinstall()
251+
```
252+
253+
```javascript [postinstall.js(CommonJS)]
186254
require('@nativescript/hook')(__dirname).postinstall()
187255
```
188256
257+
:::
258+
189259
**3. Create preuninstall.js**
190260
191-
Create `preuninstall.js` at the root folder of your plugin:
261+
Create preuninstall script at the root folder of your plugin:
262+
263+
::: code-group
192264
193-
```javascript
194-
require('@nativescript/hook')(__dirname).preuninstall()
265+
```javascript [postinstall.mjs (ESM)]
266+
import path from 'path'
267+
import hook from '@nativescript/hook'
268+
import { fileURLToPath } from 'url'
269+
270+
const __filename = fileURLToPath(import.meta.url)
271+
const __dirname = path.dirname(__filename)
272+
hook(path.join(__dirname, '..')).preuninstall()
195273
```
196274
275+
```javascript [postinstall.js(CommonJS)]
276+
require('@nativescript/hook')(__dirname).postinstall()
277+
```
278+
279+
:::
197280
**4. Update package.json Scripts**
198281
199282
Add the postinstall and preuninstall scripts:
@@ -217,11 +300,11 @@ Define your hooks under the `nativescript` property:
217300
"hooks": [
218301
{
219302
"type": "before-prepare",
220-
"script": "lib/before-prepare.js"
303+
"script": "lib/before-prepare.mjs"
221304
},
222305
{
223306
"type": "after-prepare",
224-
"script": "lib/after-prepare.js"
307+
"script": "lib/after-prepare.mjs"
225308
}
226309
]
227310
}
@@ -250,7 +333,7 @@ Custom name for the hook. Defaults to the plugin package name.
250333
"hooks": [
251334
{
252335
"type": "after-prepare",
253-
"script": "lib/after-prepare.js",
336+
"script": "lib/after-prepare.mjs",
254337
"name": "my-custom-hook"
255338
}
256339
]
@@ -272,11 +355,11 @@ export default {
272355
hooks: [
273356
{
274357
type: 'before-prepare',
275-
script: './scripts/hooks/before-prepare.js',
358+
script: './scripts/hooks/before-prepare.mjs',
276359
},
277360
{
278361
type: 'after-prepare',
279-
script: './scripts/hooks/after-prepare.js',
362+
script: './scripts/hooks/after-prepare.mjs',
280363
},
281364
],
282365
} as NativeScriptConfig
@@ -290,7 +373,7 @@ export default {
290373
hooks: [
291374
{
292375
type: 'before-<hookName>' | 'after-<hookName>',
293-
script: './path/to/script.js',
376+
script: './path/to/script.mjs',
294377
},
295378
]
296379
```
@@ -317,7 +400,18 @@ The following hook types are available (prefix with `before-` or `after-`):
317400
318401
**Example: Release Build Check**
319402
320-
```javascript
403+
::: code-group
404+
405+
```javascript [thehook.mjs (ESM)]
406+
export default function (hookArgs) {
407+
if (hookArgs.prepareData.release) {
408+
console.log('Executing release build')
409+
// Modify API keys, enable production features, etc.
410+
}
411+
}
412+
```
413+
414+
```javascript [thehook.js (CommonJS)]
321415
module.exports = function (hookArgs) {
322416
if (hookArgs.prepareData.release) {
323417
console.log('Executing release build')
@@ -326,10 +420,13 @@ module.exports = function (hookArgs) {
326420
}
327421
```
328422
423+
:::
329424
**Example: Using NativeScript Services**
330425
331-
```javascript
332-
module.exports = function ($logger, $fs, hookArgs) {
426+
::: code-group
427+
428+
```javascript [thehook.mjs (ESM)]
429+
export default function ($logger, $fs, hookArgs) {
333430
$logger.info('Starting custom hook')
334431

335432
const configPath = hookArgs.projectData.projectDir + '/config.json'
@@ -340,25 +437,27 @@ module.exports = function ($logger, $fs, hookArgs) {
340437
}
341438
```
342439
343-
**Example: ESM Hook**
344-
In a file named `<name>.mjs`
440+
```javascript [thehook.js (CommonJS)]
441+
module.exports = function ($logger, $fs, hookArgs) {
442+
$logger.info('Starting custom hook')
345443

346-
```javascript
347-
export default function (hookArgs) {
348-
console.log(
349-
'MJS executing release build.',
350-
JSON.stringify(hookArgs.prepareData),
351-
)
444+
const configPath = hookArgs.projectData.projectDir + '/config.json'
445+
if ($fs.exists(configPath)) {
446+
const config = $fs.readJson(configPath)
447+
$logger.info(`Loaded config: ${JSON.stringify(config)}`)
448+
}
352449
}
353450
```
354451
452+
:::
453+
355454
## Hooks CLI Command
356455
357456
As described above these hooks are installed automatically through npm postinstall scripts included in the plugin package.
358457
359458
However, if you (or your CI environment) install dependencies with:
360459
361-
```
460+
```bash
362461
npm install --ignore-scripts
363462
```
364463
@@ -369,15 +468,15 @@ then those postinstall scripts don’t run, which means:
369468
370469
Starting with NativeScript 9.0 CLI (`npm install -g nativescript`), a new command was introduced:
371470
372-
```
471+
```bash
373472
ns hooks
374473
```
375474
376475
This command installs all plugin hooks after dependencies have been installed.
377476
378477
So if your environment blocks postinstall scripts, you can now safely do:
379478
380-
```
479+
```bash
381480
npm install --ignore-scripts
382481
ns hooks
383482
```

0 commit comments

Comments
 (0)