|
|
|
# Neutrino Node.js Preset
|
|
|
|
[![NPM version][npm-image]][npm-url] [![NPM downloads][npm-downloads]][npm-url] [![Join Slack][slack-image]][slack-url]
|
|
|
|
|
|
|
|
`neutrino-preset-node` is a Neutrino preset that supports building Node.js applications.
|
|
|
|
|
|
|
|
## Features
|
|
|
|
|
|
|
|
- Zero upfront configuration necessary to start developing and building a Node.js project
|
|
|
|
- Modern Babel compilation supporting ES modules, Node.js 6.9+, async functions, and dynamic imports
|
|
|
|
- Supports automatically-wired sourcemaps
|
|
|
|
- Tree-shaking to create smaller bundles
|
|
|
|
- Hot Module Replacement with source-watching during development
|
|
|
|
- Chunking of external dependencies apart from application code
|
|
|
|
- Easily extensible to customize your project as needed
|
|
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
|
|
- Node.js v6.9+
|
|
|
|
- Yarn or npm client
|
|
|
|
- Neutrino v5
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
|
|
`neutrino-preset-node` can be installed via the Yarn or npm clients. Inside your project, make sure
|
|
|
|
`neutrino` and `neutrino-preset-node` are development dependencies.
|
|
|
|
|
|
|
|
#### Yarn
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ yarn add --dev neutrino neutrino-preset-node
|
|
|
|
```
|
|
|
|
|
|
|
|
#### npm
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ npm install --save-dev neutrino neutrino-preset-node
|
|
|
|
```
|
|
|
|
|
|
|
|
If you want to have automatically wired sourcemaps added to your project, add `source-map-support`:
|
|
|
|
|
|
|
|
#### Yarn
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ yarn add source-map-support
|
|
|
|
```
|
|
|
|
|
|
|
|
#### npm
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ npm install --save source-map-support
|
|
|
|
```
|
|
|
|
|
|
|
|
## Project Layout
|
|
|
|
|
|
|
|
`neutrino-preset-node` follows the standard [project layout](https://neutrino.js.org/project-layout) specified by Neutrino. This
|
|
|
|
means that by default all project source code should live in a directory named `src` in the root of the
|
|
|
|
project. This includes JavaScript files that would be available to your compiled project.
|
|
|
|
|
|
|
|
## Quickstart
|
|
|
|
|
|
|
|
After installing Neutrino and the Node.js preset, add a new directory named `src` in the root of the project, with
|
|
|
|
a single JS file named `index.js` in it.
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ mkdir src && touch src/index.js
|
|
|
|
```
|
|
|
|
|
|
|
|
Edit your `src/index.js` file with the following:
|
|
|
|
|
|
|
|
```js
|
|
|
|
import { createServer } from 'http';
|
|
|
|
|
|
|
|
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
|
|
const port = process.env.PORT || 3000;
|
|
|
|
|
|
|
|
createServer(async (req, res) => {
|
|
|
|
await delay(500);
|
|
|
|
console.log('Request!');
|
|
|
|
res.end('hi!');
|
|
|
|
})
|
|
|
|
.listen(port, () => console.log(`Server running on port ${port}`));
|
|
|
|
```
|
|
|
|
|
|
|
|
Now edit your project's package.json to add commands for starting and building the application.
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"scripts": {
|
|
|
|
"start": "neutrino start --presets neutrino-preset-node",
|
|
|
|
"build": "neutrino build --presets neutrino-preset-node"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Start the app, then either open a browser to http://localhost:3000 or use curl from another terminal window:
|
|
|
|
|
|
|
|
#### Yarn
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ yarn start
|
|
|
|
Server running on port 3000
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ curl http://localhost:3000
|
|
|
|
hi!
|
|
|
|
```
|
|
|
|
|
|
|
|
#### npm
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ npm start
|
|
|
|
Server running on port 3000
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ curl http://localhost:3000
|
|
|
|
hi!
|
|
|
|
```
|
|
|
|
|
|
|
|
## Building
|
|
|
|
|
|
|
|
`neutrino-preset-node` builds assets to the `build` directory by default when running `neutrino build`. Using the
|
|
|
|
quick start example above as a reference:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
❯ yarn build
|
|
|
|
clean-webpack-plugin: /node/build has been removed.
|
|
|
|
Build completed in 0.419s
|
|
|
|
|
|
|
|
Hash: 89e4fb250fc535920ba4
|
|
|
|
Version: webpack 2.2.1
|
|
|
|
Time: 424ms
|
|
|
|
Asset Size Chunks Chunk Names
|
|
|
|
index.js 4.29 kB 0 [emitted] index
|
|
|
|
index.js.map 3.73 kB 0 [emitted] index
|
|
|
|
✨ Done in 1.51s.
|
|
|
|
```
|
|
|
|
|
|
|
|
You can either serve or deploy the contents of this `build` directory as a Node.js module, server, or tool. For Node.js
|
|
|
|
this usually means adding a `main` property to package.json pointing to the built entry point. Also when publishing your
|
|
|
|
project to npm, consider excluding your `src` directory by using the `files` property to whitelist `build`,
|
|
|
|
or via `.npmignore` to blacklist `src`.
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"main": "build/index.js",
|
|
|
|
"files": [
|
|
|
|
"build"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
_Note: While this preset works well for many types of Node.js applications, it's important to make the distinction
|
|
|
|
between applications and libraries. This preset will not work optimally out of the box for creating distributable
|
|
|
|
libraries, and will take a little extra customization to make them suitable for that purpose._
|
|
|
|
|
|
|
|
## Hot Module Replacement
|
|
|
|
|
|
|
|
While `neutrino-preset-node` supports Hot Module Replacement for your app, it does require some application-specific
|
|
|
|
changes in order to operate. Your application should define split points for which to accept modules to reload using
|
|
|
|
`module.hot`:
|
|
|
|
|
|
|
|
For example:
|
|
|
|
|
|
|
|
```js
|
|
|
|
import { createServer } from 'http';
|
|
|
|
import app from './app';
|
|
|
|
|
|
|
|
if (module.hot) {
|
|
|
|
module.hot.accept('./app');
|
|
|
|
}
|
|
|
|
|
|
|
|
createServer((req, res) => {
|
|
|
|
res.end(app('example'));
|
|
|
|
}).listen(/* */);
|
|
|
|
```
|
|
|
|
|
|
|
|
Or for all paths:
|
|
|
|
|
|
|
|
```js
|
|
|
|
import { createServer } from 'http';
|
|
|
|
import app from './app';
|
|
|
|
|
|
|
|
if (module.hot) {
|
|
|
|
module.hot.accept();
|
|
|
|
}
|
|
|
|
|
|
|
|
createServer((req, res) => {
|
|
|
|
res.end(app('example'));
|
|
|
|
}).listen(/* */);
|
|
|
|
```
|
|
|
|
|
|
|
|
Using dynamic imports with `import()` will automatically create split points and hot replace those modules upon
|
|
|
|
modification during development.
|
|
|
|
|
|
|
|
## Customizing
|
|
|
|
|
|
|
|
To override the build configuration, start with the documentation on [customization](https://neutrino.js.org/customization).
|
|
|
|
`neutrino-preset-node` creates some conventions to make overriding the configuration easier once you are ready to make
|
|
|
|
changes.
|
|
|
|
|
|
|
|
By default the Node.js preset creates a single **main** `index` entry point to your application, and this maps to the
|
|
|
|
`index.js` file in the `src` directory. This means that the Node.js preset is optimized toward a main entry to your app.
|
|
|
|
Code not imported in the hierarchy of the `index` entry will not be output to the bundle. To overcome this you
|
|
|
|
must either define more entry points, or import the code path somewhere along the `index` hierarchy.
|
|
|
|
|
|
|
|
### Vendoring
|
|
|
|
|
|
|
|
This preset automatically vendors all external dependencies into a separate chunk based on their inclusion in your
|
|
|
|
package.json. No extra work is required to make this work.
|
|
|
|
|
|
|
|
### Rules
|
|
|
|
|
|
|
|
The following is a list of rules and their identifiers which can be overridden:
|
|
|
|
|
|
|
|
- `compile`: Compiles JS files from the `src` directory using Babel. Contains a single loader named `babel`.
|
|
|
|
|
|
|
|
### Plugins
|
|
|
|
|
|
|
|
The following is a list of plugins and their identifiers which can be overridden:
|
|
|
|
|
|
|
|
- `banner`: Injects source-map-support into the entry point of your application if detected in `dependencies` or
|
|
|
|
`devDependencies` of your package.json.
|
|
|
|
- `copy`: Copies non-JS files from `src` to `build` when using `neutrino build`.
|
|
|
|
- `clean`: Clears the contents of `build` prior to creating a production bundle.
|
|
|
|
- `progress`: Displays a progress bar when using `neutrino build`.
|
|
|
|
|
|
|
|
### Simple customization
|
|
|
|
|
|
|
|
By following the [customization guide](https://neutrino.js.org/customization/simple) and knowing the rule, loader, and plugin IDs above,
|
|
|
|
you can override and augment the build directly from package.json.
|
|
|
|
|
|
|
|
_Example: Allow importing modules with an `.mjs` extension._
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"neutrino": {
|
|
|
|
"config": {
|
|
|
|
"resolve": {
|
|
|
|
"extensions": [
|
|
|
|
".mjs"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Advanced configuration
|
|
|
|
|
|
|
|
By following the [customization guide](https://neutrino.js.org/customization/advanced) and knowing the rule, loader, and plugin IDs above,
|
|
|
|
you can override and augment the build by creating a JS module which overrides the config.
|
|
|
|
|
|
|
|
_Example: Allow importing modules with an `.mjs` extension._
|
|
|
|
|
|
|
|
```js
|
|
|
|
module.exports = neutrino => {
|
|
|
|
neutrino.config.resolve.extensions.add('.mjs');
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
## Contributing
|
|
|
|
|
|
|
|
This preset is part of the [neutrino-dev](https://github.com/mozilla-neutrino/neutrino-dev) repository, a monorepo
|
|
|
|
containing all resources for developing Neutrino and its core presets. Follow the
|
|
|
|
[contributing guide](https://neutrino.js.org/contributing) for details.
|
|
|
|
|
|
|
|
[npm-image]: https://img.shields.io/npm/v/neutrino-preset-node.svg
|
|
|
|
[npm-downloads]: https://img.shields.io/npm/dt/neutrino-preset-node.svg
|
|
|
|
[npm-url]: https://npmjs.org/package/neutrino-preset-node
|
|
|
|
[slack-image]: https://neutrino-slack.herokuapp.com/badge.svg
|
|
|
|
[slack-url]: https://neutrino-slack.herokuapp.com/
|