UNPKG

11.1 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.10+
22- Yarn or npm client
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
64After installing Neutrino and the Node.js preset, add a new directory named `src` in the root of the project, with
65a single JS file named `index.js` in it.
66
67```bash
68❯ mkdir src && touch src/index.js
69```
70
71Edit your `src/index.js` file with the following:
72
73```js
74import { createServer } from 'http';
75
76const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
77const port = process.env.PORT || 3000;
78
79createServer(async (req, res) => {
80 await delay(500);
81 console.log('Request!');
82 res.end('hi!');
83})
84.listen(port, () => console.log(`Server running on port ${port}`));
85```
86
87Now edit your project's package.json to add commands for starting and building the application.
88
89```json
90{
91 "scripts": {
92 "start": "neutrino start --use @neutrinojs/node",
93 "build": "neutrino build --use @neutrinojs/node"
94 }
95}
96```
97
98If you are using `.neutrinorc.js`, add this preset to your use array instead of `--use` flags:
99
100```js
101module.exports = {
102 use: ['@neutrinojs/node']
103};
104```
105
106Start the app, then either open a browser to http://localhost:3000 or use curl from another terminal window:
107
108#### Yarn
109
110```bash
111❯ yarn start
112Server running on port 3000
113```
114
115```bash
116❯ curl http://localhost:3000
117hi!
118```
119
120#### npm
121
122```bash
123❯ npm start
124Server running on port 3000
125```
126
127```bash
128❯ curl http://localhost:3000
129hi!
130```
131
132## Building
133
134`@neutrinojs/node` builds assets to the `build` directory by default when running `neutrino build`. Using the
135quick start example above as a reference:
136
137```bash
138❯ yarn build
139
140Hash: 89e4fb250fc535920ba4
141Version: webpack 3.5.6
142Time: 424ms
143 Asset Size Chunks Chunk Names
144 index.js 4.29 kB 0 [emitted] index
145index.js.map 3.73 kB 0 [emitted] index
146✨ Done in 1.51s.
147```
148
149You can either serve or deploy the contents of this `build` directory as a Node.js module, server, or tool. For Node.js
150this usually means adding a `main` property to package.json pointing to the primary main built entry point. Also when
151publishing your project to npm, consider excluding your `src` directory by using the `files` property to whitelist
152`build`, or via `.npmignore` to blacklist `src`.
153
154```json
155{
156 "main": "build/index.js",
157 "files": [
158 "build"
159 ]
160}
161```
162
163_Note: While this preset works well for many types of Node.js applications, it's important to make the distinction
164between applications and libraries. This preset will not work optimally out of the box for creating distributable
165libraries, and will take a little extra customization to make them suitable for that purpose._
166
167## Hot Module Replacement
168
169While `@neutrinojs/node` supports Hot Module Replacement for your app, it does require some application-specific
170changes in order to operate. Your application should define split points for which to accept modules to reload using
171`module.hot`:
172
173For example:
174
175```js
176import { createServer } from 'http';
177import app from './app';
178
179if (module.hot) {
180 module.hot.accept('./app');
181}
182
183createServer((req, res) => {
184 res.end(app('example'));
185}).listen(/* */);
186```
187
188Or for all paths:
189
190```js
191import { createServer } from 'http';
192import app from './app';
193
194if (module.hot) {
195 module.hot.accept();
196}
197
198createServer((req, res) => {
199 res.end(app('example'));
200}).listen(/* */);
201```
202
203Using dynamic imports with `import()` will automatically create split points and hot replace those modules upon
204modification during development.
205
206## Debugging
207
208You can start the Node.js server in `inspect` mode to debug the process by setting `neutrino.options.debug` to `true`.
209This can be done from the [API](https://neutrino.js.org/api#optionsdebug) or the [CLI using `--debug`](https://neutrino.js.org/cli#-debug).
210
211## Preset options
212
213You can provide custom options and have them merged with this preset's default options to easily affect how this
214preset builds. You can modify Node.js preset settings from `.neutrinorc.js` by overriding with an options object. Use
215an array pair instead of a string to supply these options in `.neutrinorc.js`.
216
217The following shows how you can pass an options object to the Node.js preset and override its options, showing the
218defaults:
219
220```js
221module.exports = {
222 use: [
223 ['@neutrinojs/node', {
224 // Enables Hot Module Replacement. Set to false to disable
225 hot: true,
226
227 polyfills: {
228 // Enables fast-async polyfill. Set to false to disable
229 async: true
230 },
231
232 // Target specific versions via babel-preset-env
233 targets: {
234 node: '6.10'
235 },
236
237 // Remove the contents of the output directory prior to building.
238 // Set to false to disable cleaning this directory
239 clean: {
240 paths: [neutrino.options.output]
241 },
242
243 // Add additional Babel plugins, presets, or env options
244 babel: {
245 // Override options for babel-preset-env, showing defaults:
246 presets: [
247 ['babel-preset-env', {
248 targets: { node: '6.10' },
249 modules: false,
250 useBuiltIns: true,
251 // These are excluded when using polyfills.async. Disabling the async polyfill
252 // will remove these from the exclusion list
253 exclude: ['transform-regenerator', 'transform-async-to-generator']
254 }]
255 ]
256 }
257 }]
258 ]
259};
260```
261
262_Example: Override the Node.js Babel compilation target to Node.js v8:_
263
264```js
265module.exports = {
266 use: [
267 ['@neutrinojs/node', {
268 // Add additional Babel plugins, presets, or env options
269 babel: {
270 // Override options for babel-preset-env
271 presets: [
272 ['babel-preset-env', {
273 // Passing in targets to babel-preset-env will replace them
274 // instead of merging them
275 targets: {
276 node: '8.0'
277 }
278 }]
279 ]
280 }
281 }]
282 ]
283};
284```
285
286## Customizing
287
288To override the build configuration, start with the documentation on [customization](https://neutrino.js.org/customization).
289`@neutrinojs/node` creates some conventions to make overriding the configuration easier once you are ready to make
290changes.
291
292By default Neutrino, and therefore this preset, creates a single **main** `index` entry point to your application, and this
293maps to the `index.*` file in the `src` directory. This means that this preset is optimized toward a single main entry
294to your application. Code not imported in the hierarchy of the `index` entry will not be output to the bundle. To overcome
295this you must either define more mains via [`options.mains`](https://neutrino.js.org/customization#optionsmains), import
296the code path somewhere along the `index` hierarchy, or define multiple configurations in your `.neutrinorc.js`.
297
298### Vendoring
299
300This preset automatically vendors all external dependencies into a separate chunk based on their inclusion in your
301package.json. No extra work is required to make this work.
302
303### Rules
304
305The following is a list of rules and their identifiers which can be overridden:
306
307| Name | Description | Environments and Commands |
308| --- | --- | --- |
309| `compile` | Compiles JS files from the `src` directory using Babel. Contains a single loader named `babel` | all |
310
311### Plugins
312
313The following is a list of plugins and their identifiers which can be overridden:
314
315_Note: Some plugins are only available in certain environments. To override them, they should be modified conditionally._
316
317| Name | Description | Environments and Commands |
318| --- | --- | --- |
319| `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 |
320| `copy` | Copies all files from `src/static` to `build` when using `neutrino build`. | `build` command |
321| `clean` | Clears the contents of `build` prior to creating a production bundle. | `build` command |
322| `start-server` | Start a Node.js for the first configured main entry point. | `start` command |
323| `hot` | Enables Hot Module Replacement. | `start` command |
324| `named-modules` | Enables named modules for improved debugging and console output. From `@neutrinojs/hot`. | `start` command |
325| `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` |
326
327### Override configuration
328
329By following the [customization guide](https://neutrino.js.org/customization) and knowing the rule, loader, and plugin IDs above,
330you can override and augment the build by by providing a function to your `.neutrinorc.js` use array. You can also
331make these changes from the Neutrino API in custom middleware.
332
333_Example: Allow importing modules with a `.esm` extension._
334
335```js
336module.exports = {
337 use: [
338 '@neutrinojs/node',
339 (neutrino) => neutrino.config.resolve.extensions.add('.esm')
340 ]
341};
342```
343
344## Contributing
345
346This preset is part of the [neutrino-dev](https://github.com/mozilla-neutrino/neutrino-dev) repository, a monorepo
347containing all resources for developing Neutrino and its core presets and middleware. Follow the
348[contributing guide](https://neutrino.js.org/contributing) for details.
349
350[npm-image]: https://img.shields.io/npm/v/@neutrinojs/node.svg
351[npm-downloads]: https://img.shields.io/npm/dt/@neutrinojs/node.svg
352[npm-url]: https://npmjs.org/package/@neutrinojs/node
353[spectrum-image]: https://withspectrum.github.io/badge/badge.svg
354[spectrum-url]: https://spectrum.chat/neutrino