Neutrino Koa Preset
neutrino-preset-koa
is a Neutrino preset for Koa applications development.
What is Neutrino?
Neutrino is a configuration engine that allows to bundle Webpack configurations or their parts as modules and publish them to NPM. Such modules usually are called presets or middlewares. They are designed to work in conjunction with Neutrino core in your project. You can compose compilation, linting, testing and other configurations, and share them to developers.
Features
- Zero upfront configuration necessary to start developing and building a Koa project
- Modern Babel compilation supporting ES modules, async functions, dynamic imports, ES class properties, rest spread operators, decorators and automatic polyfills bound to the platform
- Sourcemaps
- Tree-shaking to create smaller bundles
- Built-in HTTP server for launching the application on development and production
- Hot Module Replacement with source-watching during development
- Disabled redundant
[HMR]
console messages - You can change your files without restarting the server
- TypeScript support
- User-friendly building progress bar
- Detect and warn about circular and duplicated dependencies during the build time
- Git revision information through environment variables (VERSION, COMMITHASH, BRANCH)
- Consider external dependencies sourcemaps for better debugging during development
- Debug console cleared on every file change. Your outdated logs will be removed
- Chunking of external dependencies apart from application code
- Automatically discovers free HTTP port to run a server locally
- Graceful server shutdown
- Outputs building log to
stdout
andstderr
. No pollution to the console - Shows PID (Process ID) in the output
- Only Linux and MacOS: Sets the NodeJS process name the same as the project name. So can be easily found with
ps x | grep myname
- Production-optimized bundles with minification
Requirements
- Node.js v10+
- Neutrino v9
- Webpack v4
- Koa v2.3+
Installation
neutrino-preset-koa
can be installed with NPM. Inside your project, make sure neutrino
, webpack
and neutrino-preset-koa
are development dependencies.
npm install --save koanpm install --save-dev neutrino neutrino-preset-koa webpack webpack-cli
Now edit your project's package.json
to add commands for starting and building the application:
Then add the new file .neutrinorc.js
in the root of the project:
let koa = moduleexports = use:
And create a webpack.config.js
file in the root of the project, that uses the Neutrino API to access the generated webpack config:
let neutrino = moduleexports =
Project Layout
neutrino-preset-koa
follows the standard 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 and TypeScript files that would be available to your compiled project.
Quickstart
After installing Neutrino and the Koa preset, add a new directory named src
in the root of the project, with a single JS file named index.js
in it.
Edit your src/index.js
file with the following:
let Koa = moduleexports = // don't call .listen()
Important: This preset requires your entry point to export an instance of Koa application. But you don't need to start it by calling listen()
method. The preset has a built-in launch server that will do it internally. You can only customize the server in the preset options.
Start the app, then either open a browser and navigate to one of the provided addresses or use curl from another terminal window:
❯ npm start √ Build completed[project-name] Server started on: http://192.168.31.5:50274 http://127.0.0.1:50274 http://MyHome-PC:50274 http://localhost:50274
❯ curl http://localhost:50274{"success":true}
The server will automatically choose a free port by default in a development mode. So it may differ on every run and in your particular case.
Building
neutrino-preset-koa
builds assets to the build
directory by default when running npm run build
. Using the quick start example above as a reference:
❯ npm run build √ Building project completedHash: 89e4fb250fc535920ba4Version: webpack 3.5.6Time: 424ms Asset Size Chunks Chunk Names index.js 4.29 kB 0 [emitted] indexindex.js.map 3.73 kB 0 [emitted] index
You can either serve or deploy the contents of this build
directory as a Node.js server. For Node.js this usually means adding a main
property to 'package.json' pointing to the primary main built entry point. Also it is recommended to add a private flag to not accidentally publish your server.
Now you can start a built application:
❯ node . [project-name] Server started on: http://192.168.31.5 http://127.0.0.1 http://MyHome-PC http://localhost
The server will set a port to 80
by default in production mode. The default port is defined during a build time.
Hot Module Replacement
As neutrino-preset-koa
completely controls launching of your application instance it automatically enables Hot Module Replacement for all files during development. No extra configuration or changes in your source code are necessary. You don't need to restart the server every time files changed.
Using dynamic imports with import()
will automatically create split points and hot replace those modules upon modification during development.
Debugging
You can start the Node.js server in inspect
mode to debug the process by setting neutrino.options.debug
to true
. This can be done from the API
Preset options
You can provide custom options and have them merged with this preset's default options to easily affect how this preset builds. You can modify Koa preset settings from .neutrinorc.js
by overriding with an options object.
The following shows how you can pass an options object to the Koa preset and override its options, showing the defaults:
.neutrinorc.js
let koa = moduleexports = use:
Customizing
Launcher
This preset wraps your application with HTTP server that launches your application. It can be configured using server
property in the preset options
So you don't need to think about how to serve your application. This is completely managed by neutrino-preset-koa
preset.
If you want to disable the launcher you need to explicitly set the option to false
This turns your application into a regular Node.js application and disables all advantages of this preset. You will have to call listen()
on Koa
instance by yourself if you need to start a server.
Disabling the launcher not for debugging purposes is not recommended. Probably you might need @neutrinojs/node instead in this case.
Port
There are multiple ways to customize the HTTP port of your application server:
Custom port
You can configure a default port of the server in options using server.port
property in the preset options. For example:
Now your server will start on 8080
in both production and development modes.
Automatic discovering
The default behavior of port when not configured is to default to 80
/443
on production and to take random free default port on development.
You can choose random free port on both production and development by passing one of these values to the server.port
preset option: false
, null
, 0
. For example:
Environment variable
Even when port is customized in preset options it is considered default and may be overridden any time by PORT
environment variable. This may be useful for production environments as the server will check process.env.PORT
in the runtime first and then fallback to a port you have defined.
PORT
environment variable will always have a priority over any configuration.
Host
By default the server starts on a default IPv6/IPv4 host which exposes it to local network. There is no way to configure a server host from the preset options. But you still can use HOST
environment variable to define your custom host.
HTTP version
This preset uses HTTP v1.x by default. You can switch to HTTP v2 in options.
But there may be no browsers that support not encrypted HTTP2. That's why you need to enable SSL.
SSL
When you want to start a browser on https
you need to provide paths to an SSL certificate and a public key
If you run in development mode and want to use a temporary locally self-signed certificate you may configure it like this
Node
You can change the minimum Node.js version to be supported by your application. Babel compiler will consider this and output a code with the necessary syntax. You can do this changing node
property in the preset options. For example:
Entry point
By default Neutrino, and therefore this preset, creates a single main index
entry point to your application, and this maps to the index.*
file in the src
directory.
Important! This preset has a limitation – it supports only a single entry point. Defining 2 or more may cause it to work not properly.
You can customize a single entry point in your .neutrinorc.js
and override a default one
.neutrinorc.js
moduleexports = options: mains: server: './server.js' use:
To overcome the limitation you can define multiple configurations
.neutrinorc.js
moduleexports = options: mains: index: './server1.js' use: options: mains: index: './server2.js' use:
Webpack config
Sometime you want to extend Webpack configuration with custom loaders or plugins. This can be done in .neutrinorc.js
file using Neutrino API also known as webpack-chain
.
Plugins
For example, you can add TypeScript checking
let koa = let TsChecker = moduleexports = use: { let productionMode = processenvNODE_ENV === 'production' if productionMode return neutrinoconfig }
Specifically for this plugin you also need to create tsconfig.json
file
It will enable highlighting in your code editor too.
Graceful Shutdown
neutrino-preset-koa
automatically shutdowns a server instance gracefully. Application server prints this message to signal successful closing when exited:
Server shutting down...Server closed
During shutdown these steps are performed
- Stop listening new requests
- Close all open inactive connections
- Wait current requests to end and close their connections at the end
The preset doesn't forcefully exit a process but waits for queued operations to finish including your async Koa middlewares. In most cases you are not required to handle it explicitly. But if you have some long running operations or timers outside Koa middlewares that continue event loop then you should take care of them by yourself. Other will be handled by neutrino-preset-koa
. The good practice is to use this in your code in cases of shutdown:
'SIGINT' 'SIGTERM' 'SIGBREAK' 'SIGHUP'
Don't call process.exit()
as it considered a bad practice. The application should exit naturally when there is an empty call stack and no more scheduled tasks. You should see this at the very end if the finishing of the application is correct:
Application exited
In case your application will not finish for some reason in 10 seconds, there is a timeout that kills the application forcefully. You will not be able to handle this termination. The application will exit with an error signal right after this message
Server killed, due to timeout
Graceful Shutdown works correctly on all platforms only in a built version which is started using
node .
This is another reason to use this command on a production environment. It may not work properly when you start the server as a child process of npm start
.
VSCode tips
Project settings
These are suggested workspace settings for VSCode editor:
.vscode/settings.json
This should prevent building as you type code.
Launching in the VSCode Debugger
Visual Studio Code has its own built-in debugger. You may launch your application in the development mode using this debugger. Use this configuration:
launch.json
Use these 3 tasks for different purposes
- Start instead of
npm start
. Builds with live reloading. You can override the Neutrino settings port with"env": {"PORT": "0"}
- Run instead of
node .
. Runs what was built. Useful for testing of the production build. You can override the Neutrino settings port with"env": {"PORT": "80"}
- Debug when want to attach to a manually opened app, e.g.
node --inspect .
.
You will be able to use breakpoints in the editor. Sometime breakpoints outside routes don't work during Hot Module Replacement. You may restart the application in such cases.