UNPKG

12.3 kBMarkdownView Raw
1# Neutrino Node.js Preset
2
3`@neutrinojs/node` is a Neutrino preset that supports building Node.js applications.
4
5[![NPM version][npm-image]][npm-url]
6[![NPM downloads][npm-downloads]][npm-url]
7[![Join the Neutrino community on Spectrum][spectrum-image]][spectrum-url]
8
9## Features
10
11- Zero upfront configuration necessary to start developing and building a Node.js project
12- Modern Babel compilation supporting ES modules, Node.js 6.10+, async functions, and dynamic imports
13- Supports automatically-wired sourcemaps
14- Tree-shaking to create smaller bundles
15- Hot Module Replacement with source-watching during development
16- Chunking of external dependencies apart from application code
17- Easily extensible to customize your project as needed
18
19## Requirements
20
21- Node.js v6 LTS, v8, v9
22- Yarn v1.2.1+, or npm v5.4+
23- Neutrino v8
24
25## Installation
26
27`@neutrinojs/node` can be installed via the Yarn or npm clients. Inside your project, make sure
28`neutrino` and `@neutrinojs/node` are development dependencies.
29
30#### Yarn
31
32```bash
33❯ yarn add --dev neutrino @neutrinojs/node
34```
35
36#### npm
37
38```bash
39❯ npm install --save-dev neutrino @neutrinojs/node
40```
41
42If you want to have automatically wired sourcemaps added to your project, add `source-map-support`:
43
44#### Yarn
45
46```bash
47❯ yarn add source-map-support
48```
49
50#### npm
51
52```bash
53❯ npm install --save source-map-support
54```
55
56## Project Layout
57
58`@neutrinojs/node` follows the standard [project layout](https://neutrino.js.org/project-layout) specified by Neutrino. This
59means that by default all project source code should live in a directory named `src` in the root of the
60project. This includes JavaScript files that would be available to your compiled project.
61
62## Quickstart
63
64The fastest way to get started is by using the `create-project` scaffolding tool.
65Don’t want to use the CLI helper? No worries, we have you covered with the [manual installation](#manual-installation).
66
67### create-project
68
69Run the following command to start the process. Substitute `<directory-name>` with the directory name you wish to create
70for this project.
71
72
73#### Yarn
74
75```
76❯ yarn create @neutrinojs/project <directory-name>
77```
78
79_Note: The `create` command is a shorthand that helps you do two things at once. See the [Yarn create docs](https://yarnpkg.com/lang/en/docs/cli/create) for more details._
80
81#### npm/npx
82
83[`npx`](https://github.com/zkat/npx) comes pre-installed with `npm`. If you’re running an older version of `npm`, then
84`npm install -g npm` to update to the latest version.
85
86```
87❯ npx @neutrinojs/create-project <directory-name>
88```
89
90The CLI helper will prompt for the project to scaffold, and will offer to set
91up a test runner as well as linting to your project. Refer to the [Create new project](../create-project) section
92for details on all available options.
93
94### Manual Installation
95
96After installing Neutrino and the Node.js preset, add a new directory named `src` in the root of the project, with
97a single JS file named `index.js` in it.
98
99```bash
100❯ mkdir src && touch src/index.js
101```
102
103Edit your `src/index.js` file with the following:
104
105```js
106import { createServer } from 'http';
107
108const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
109const port = process.env.PORT || 3000;
110
111createServer(async (req, res) => {
112 await delay(500);
113 console.log('Request!');
114 res.end('hi!');
115})
116.listen(port, () => console.log(`Server running on port ${port}`));
117```
118
119Now edit your project's package.json to add commands for starting and building the application.
120
121```json
122{
123 "scripts": {
124 "start": "neutrino start --use @neutrinojs/node",
125 "build": "neutrino build --use @neutrinojs/node"
126 }
127}
128```
129
130If you are using `.neutrinorc.js`, add this preset to your use array instead of `--use` flags:
131
132```js
133module.exports = {
134 use: ['@neutrinojs/node']
135};
136```
137
138Start the app, then either open a browser to http://localhost:3000 or use curl from another terminal window:
139
140#### Yarn
141
142```bash
143❯ yarn start
144Server running on port 3000
145```
146
147```bash
148❯ curl http://localhost:3000
149hi!
150```
151
152#### npm
153
154```bash
155❯ npm start
156Server running on port 3000
157```
158
159```bash
160❯ curl http://localhost:3000
161hi!
162```
163
164## Building
165
166`@neutrinojs/node` builds assets to the `build` directory by default when running `neutrino build`. Using the
167quick start example above as a reference:
168
169```bash
170❯ yarn build
171
172Hash: 89e4fb250fc535920ba4
173Version: webpack 3.5.6
174Time: 424ms
175 Asset Size Chunks Chunk Names
176 index.js 4.29 kB 0 [emitted] index
177index.js.map 3.73 kB 0 [emitted] index
178✨ Done in 1.51s.
179```
180
181You can either serve or deploy the contents of this `build` directory as a Node.js module, server, or tool. For Node.js
182this usually means adding a `main` property to package.json pointing to the primary main built entry point. Also when
183publishing your project to npm, consider excluding your `src` directory by using the `files` property to whitelist
184`build`, or via `.npmignore` to blacklist `src`.
185
186```json
187{
188 "main": "build/index.js",
189 "files": [
190 "build"
191 ]
192}
193```
194
195_Note: While this preset works well for many types of Node.js applications, it's important to make the distinction
196between applications and libraries. This preset will not work optimally out of the box for creating distributable
197libraries, and will take a little extra customization to make them suitable for that purpose._
198
199## Hot Module Replacement
200
201While `@neutrinojs/node` supports Hot Module Replacement for your app, it does require some application-specific
202changes in order to operate. Your application should define split points for which to accept modules to reload using
203`module.hot`:
204
205For example:
206
207```js
208import { createServer } from 'http';
209import app from './app';
210
211if (module.hot) {
212 module.hot.accept('./app');
213}
214
215createServer((req, res) => {
216 res.end(app('example'));
217}).listen(/* */);
218```
219
220Or for all paths:
221
222```js
223import { createServer } from 'http';
224import app from './app';
225
226if (module.hot) {
227 module.hot.accept();
228}
229
230createServer((req, res) => {
231 res.end(app('example'));
232}).listen(/* */);
233```
234
235Using dynamic imports with `import()` will automatically create split points and hot replace those modules upon
236modification during development.
237
238## Debugging
239
240You can start the Node.js server in `inspect` mode to debug the process by setting `neutrino.options.debug` to `true`.
241This can be done from the [API](https://neutrino.js.org/api#optionsdebug) or the [CLI using `--debug`](https://neutrino.js.org/cli#-debug).
242
243## Preset options
244
245You can provide custom options and have them merged with this preset's default options to easily affect how this
246preset builds. You can modify Node.js preset settings from `.neutrinorc.js` by overriding with an options object. Use
247an array pair instead of a string to supply these options in `.neutrinorc.js`.
248
249The following shows how you can pass an options object to the Node.js preset and override its options, showing the
250defaults:
251
252```js
253module.exports = {
254 use: [
255 ['@neutrinojs/node', {
256 // Enables Hot Module Replacement. Set to false to disable
257 hot: true,
258
259 polyfills: {
260 // Enables fast-async polyfill. Set to false to disable
261 async: true
262 },
263
264 // Target specific versions via babel-preset-env
265 targets: {
266 node: '6.10'
267 },
268
269 // Remove the contents of the output directory prior to building.
270 // Set to false to disable cleaning this directory
271 clean: {
272 paths: [neutrino.options.output]
273 },
274
275 // Add additional Babel plugins, presets, or env options
276 babel: {
277 // Override options for babel-preset-env, showing defaults:
278 presets: [
279 ['babel-preset-env', {
280 targets: { node: '6.10' },
281 modules: false,
282 useBuiltIns: true,
283 // These are excluded when using polyfills.async. Disabling the async polyfill
284 // will remove these from the exclusion list
285 exclude: ['transform-regenerator', 'transform-async-to-generator']
286 }]
287 ]
288 }
289 }]
290 ]
291};
292```
293
294_Example: Override the Node.js Babel compilation target to Node.js v8:_
295
296```js
297module.exports = {
298 use: [
299 ['@neutrinojs/node', {
300 // Add additional Babel plugins, presets, or env options
301 babel: {
302 // Override options for babel-preset-env
303 presets: [
304 ['babel-preset-env', {
305 // Passing in targets to babel-preset-env will replace them
306 // instead of merging them
307 targets: {
308 node: '8.0'
309 }
310 }]
311 ]
312 }
313 }]
314 ]
315};
316```
317
318## Customizing
319
320To override the build configuration, start with the documentation on [customization](https://neutrino.js.org/customization).
321`@neutrinojs/node` creates some conventions to make overriding the configuration easier once you are ready to make
322changes.
323
324By default Neutrino, and therefore this preset, creates a single **main** `index` entry point to your application, and this
325maps to the `index.*` file in the `src` directory. This means that this preset is optimized toward a single main entry
326to your application. Code not imported in the hierarchy of the `index` entry will not be output to the bundle. To overcome
327this you must either define more mains via [`options.mains`](https://neutrino.js.org/customization#optionsmains), import
328the code path somewhere along the `index` hierarchy, or define multiple configurations in your `.neutrinorc.js`.
329
330### Vendoring
331
332This preset automatically vendors all external dependencies into a separate chunk based on their inclusion in your
333package.json. No extra work is required to make this work.
334
335### Rules
336
337The following is a list of rules and their identifiers which can be overridden:
338
339| Name | Description | Environments and Commands |
340| --- | --- | --- |
341| `compile` | Compiles JS files from the `src` directory using Babel. Contains a single loader named `babel` | all |
342
343### Plugins
344
345The following is a list of plugins and their identifiers which can be overridden:
346
347_Note: Some plugins are only available in certain environments. To override them, they should be modified conditionally._
348
349| Name | Description | Environments and Commands |
350| --- | --- | --- |
351| `banner` | Injects source-map-support into the mains (entry points) of your application if detected in `dependencies` or `devDependencies` of your package.json. | Only when `source-map-support` is installed |
352| `copy` | Copies all files from `src/static` to `build` when using `neutrino build`. | `build` command |
353| `clean` | Clears the contents of `build` prior to creating a production bundle. | `build` command |
354| `start-server` | Start a Node.js for the first configured main entry point. | `start` command |
355| `hot` | Enables Hot Module Replacement. | `start` command |
356| `named-modules` | Enables named modules for improved debugging and console output. From `@neutrinojs/hot`. | `start` command |
357| `module-concat` | Concatenate the scope of all your modules into one closure and allow for your code to have a faster execution time in the browser. | `NODE_ENV production` |
358
359### Override configuration
360
361By following the [customization guide](https://neutrino.js.org/customization) and knowing the rule, loader, and plugin IDs above,
362you can override and augment the build by by providing a function to your `.neutrinorc.js` use array. You can also
363make these changes from the Neutrino API in custom middleware.
364
365_Example: Allow importing modules with a `.esm` extension._
366
367```js
368module.exports = {
369 use: [
370 '@neutrinojs/node',
371 (neutrino) => neutrino.config.resolve.extensions.add('.esm')
372 ]
373};
374```
375
376## Contributing
377
378This preset is part of the [neutrino-dev](https://github.com/mozilla-neutrino/neutrino-dev) repository, a monorepo
379containing all resources for developing Neutrino and its core presets and middleware. Follow the
380[contributing guide](https://neutrino.js.org/contributing) for details.
381
382[npm-image]: https://img.shields.io/npm/v/@neutrinojs/node.svg
383[npm-downloads]: https://img.shields.io/npm/dt/@neutrinojs/node.svg
384[npm-url]: https://npmjs.org/package/@neutrinojs/node
385[spectrum-image]: https://withspectrum.github.io/badge/badge.svg
386[spectrum-url]: https://spectrum.chat/neutrino