diff --git a/docs/README.md b/docs/README.md index 3f7f804..56fb681 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,7 +5,12 @@ --- -Neutrino is a companion tool which lets you build web and Node.js applications with shared presets or configurations. It intends to make the process of initializing and building projects much simpler by providing minimal development dependencies. +Neutrino is a companion tool which lets you build web and Node.js applications with shared presets or configurations. +It intends to make the process of initializing and building projects much simpler by providing minimal development +dependencies. -Neutrino uses Webpack to build both web and Node.js projects by providing complete build presets which can be shared across targets and projects. You can use Neutrino base presets to get started building a variety of projects, create your -own presets by extending the Neutrino core ones to be shared across your own projects or even by the community. Presets can even be manipulated on a project-by-project basis to handle almost any build situation your preset doesn't cover. +Neutrino uses Webpack to build both web and Node.js projects by providing complete build presets which can be shared +across targets and projects. You can use Neutrino base presets to get started building a variety of projects, create +your own presets by extending the Neutrino core ones to be shared across your own projects or even by the community. +Presets can even be manipulated on a project-by-project basis to handle almost any build situation your preset doesn't +cover. diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 66a5da6..191c3bc 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -8,6 +8,13 @@ * [Web Preset](/presets/neutrino-preset-web/README.md) * [React Preset](/presets/neutrino-preset-react/README.md) * [Node.js Preset](/presets/neutrino-preset-node/README.md) + * [Karma Preset](/presets/neutrino-preset-karma/README.md) + * [Mocha Preset](/presets/neutrino-preset-mocha/README.md) + * [Jest Preset](/presets/neutrino-preset-jest/README.md) * [Base Preset](/presets/neutrino-preset-base/README.md) - * [Overriding a preset](/presets/overriding-a-preset.md) - * [Creating a preset](/presets/creating-a-preset.md) +* [Customization](/customization/README.md) + * [Simple](/customization/simple.md) + * [Advanced](/customization/advanced.md) +* [Creating presets](/presets/creating-presets.md) +* [API](/api/README.md) +* [CLI](/cli/README.md) diff --git a/docs/api/README.md b/docs/api/README.md new file mode 100644 index 0000000..d6c868d --- /dev/null +++ b/docs/api/README.md @@ -0,0 +1 @@ +# Neutrino API diff --git a/docs/cli/README.md b/docs/cli/README.md new file mode 100644 index 0000000..90b4ef0 --- /dev/null +++ b/docs/cli/README.md @@ -0,0 +1 @@ +# Neutrino CLI diff --git a/docs/creating-presets.md b/docs/creating-presets.md new file mode 100644 index 0000000..f1fb353 --- /dev/null +++ b/docs/creating-presets.md @@ -0,0 +1,3 @@ +# Creating Neutrino Presets + +## Publishing (npm, GitHub) diff --git a/docs/customization/README.md b/docs/customization/README.md new file mode 100644 index 0000000..5c58fbe --- /dev/null +++ b/docs/customization/README.md @@ -0,0 +1,18 @@ +# Neutrino Customization + +No two JavaScript projects are ever the same, and as such there may be times when you will need to make modifications +to the way your Neutrino preset is building your project. Neutrino provides two ways you can augment a preset in the +context of a project without resorting to creating and publishing an entirely independent preset. + +### Simple Customization + +By defining a configuration object within your package.json, Neutrino will merge this information with that provided by +your preset, effectively overriding those options with your custom data. + +### Advanced Customization + +You can also create a configuration override directly in your project which can extend the presets you are using. + +--- + +Continue for details on each technique. diff --git a/docs/customization/advanced.md b/docs/customization/advanced.md new file mode 100644 index 0000000..6182585 --- /dev/null +++ b/docs/customization/advanced.md @@ -0,0 +1,85 @@ +# Advanced Neutrino Customization + +No two JavaScript projects are ever the same, and as such there may be times when you will need to make modifications +to the way your Neutrino preset is building your project. If you need more customization than can be afforded by +augmenting your project's package.json, consider using this advanced configuration guide to modify your build as +needed. + +## Creating a project-specific preset + +Neutrino configurations are backed by [webpack-chain](https://github.com/mozilla-rpweb/webpack-chain), a library for +making modifications to a Webpack configuration using a fluent or chained API. When your project needs more advanced +build overrides, you will be interacting with this API in order to perform modifications. + +First, we need to create a project-specific preset to make these changes. This can either be a JS file or a directory +with an `index.js` file. Since Neutrino uses Node.js and Webpack for interacting with presets, it is helpful to +understand that this is a Node.js module. By exporting a function from your module, you will be provided with a Neutrino +instance for modifying the build. Let's create a file called `neutrino-custom.js` in the root of our example project: + +```js +// neutrino-custom.js +module.exports = neutrino => { + // ... +}; +``` + +At the moment our custom configurator isn't doing anything, but it does get us far enough to be able to tell Neutrino +to use it for additional configuration. Modify your package.json and add `neutrino-custom.js` as an additional preset. + +_Note: Neutrino will attempt to load this module relative to the current working directory, which should be the root of +your project._ + +```json +{ + "config": { + "presets": [ + "neutrino-preset-react", + "neutrino-preset-karma", + "neutrino-custom.js" + ] + }, + "scripts": { + "build": "neutrino build" + } +} +``` + +Other than actually changing the config, that is all the setup necessary for Neutrino to pick up your custom changes. + +## Configuring + +The Neutrino instance provided to your custom configurator has a `config` property that is an instance of +[webpack-chain](https://github.com/mozilla-rpweb/webpack-chain). We won't go in-depth of all the configuration +possibilities here, but encourage you to check out the documentation for webpack-chain for instruction on your +particular use case. + +This `neutrino.config` is an accumulation of all configuration set up to this moment. Every Neutrino preset interacts +with and makes changes through this config, which is all available to you. For example, if you are using the presets +`neutrino-preset-react` and `neutrino-preset-karma`, any options set can be extended, manipulated, or removed. + +_Example: Neutrino's React preset adds `.jsx` as a module extension. Let's remove it._ + +```js +module.exports = neutrino => { + neutrino.config.resolve.extensions.delete('.jsx'); +}; +``` + +_Example: Neutrino's Node.js preset uses `babel-preset-env` to support Node.js v6.9. Let's change it to support back to +v4.2. This preset has a rule named "compile" and a loader named "babel"._ + +```js +module.exports = neutrino => { + neutrino.config.module + .rule('compile') + .loader('babel', ({ options }) => { + options.presets[0][1].targets.node = 4.2; + + return { options }; + }); +}; +``` + +Presets can also have their own custom data in addition to the Neutrino config. See your respective preset for details. +Again, rather than reiterate the documentation for [webpack-chain](https://github.com/mozilla-rpweb/webpack-chain) here, +please refer to its documentation for all ways you can modify a config instance to solve your use cases. diff --git a/docs/customization/simple.md b/docs/customization/simple.md new file mode 100644 index 0000000..3160dc8 --- /dev/null +++ b/docs/customization/simple.md @@ -0,0 +1,238 @@ +# Simple Neutrino Customization + +No two JavaScript projects are ever the same, and as such there may be times when you will need to make modifications +to the way your Neutrino preset is building your project. By defining a configuration object within your package.json, +Neutrino will merge this information with that provided by your preset, effectively overriding those options with your +custom data. + +## Prepare package.json + +First, you will need to define a `config` section within your package.json. You +[may have already done this](/usage.md#using-multiple-presets) if you +specified your presets through the `config` as opposed to flags through `scripts`: + +```json +{ + "config": { + "presets": [ + "neutrino-preset-react", + "neutrino-preset-karma" + ] + }, + "scripts": { + "start": "neutrino start", + "build": "neutrino build" + } +} +``` + +Add a new property to `config` named `neutrino`. This will be an object where we can provide configuration data: + +```json +{ + "config": { + "presets": [], + "neutrino": { + + } + } +} +``` + +Populate this object with configuration overrides. This is not a Webpack configuration, but rather a Neutrino-compatible +object based on [webpack-chain](https://github.com/mozilla-rpweb/webpack-chain). + +## Usage + +### Entries + +Add files to named entry points, or define new entry points. This is a key named `entry`, with a value being an object. +This maps to points to enter the application. At this point the application starts executing. + +_Example: Define an entry point named `vendor` that bundles React packages separately from the application code._ + +```json +{ + "config": { + "neutrino": { + "entry": { + "vendor": [ + "react", + "react-dom", + "react-hot-loader", + "react-router-dom" + ] + } + } + } +} +``` + +### Module + +The `module` object defines how the different types of modules within a project will be treated. Any additional +properties attached to `module` not defined below will be set on the final module configuration. + +#### Module Rules + +Using `module.rule` creates rules that are matched to requests when modules are created. These rules can modify how the +module is created. They can apply loaders to the module, or modify the parser. + +Using `module.rule.loader` allows to you define the Webpack loader and its options for processing a particular rule. +This loader is usually a `dependency` or `devDependency` of your project. Each `loader` object can specify a property +for the string `loader` and an `options` object. + +_Example: Add LESS loading to the project._ + +```json +{ + "dependencies": { + "less": "^2.7.2", + "less-loader": "^2.2.3" + }, + "config": { + "neutrino": { + "module": { + "rule": { + "styles": { + "test": "/\\.less$/", + "loader": { + "less": { + "loader": "less-loader", + "options": { + "noIeCompat": true + } + } + } + } + } + } + } + } +} +``` + +### Output + +The `output` object contains a set of options instructing Webpack on how and where it should output your bundles, +assets, and anything else you bundle or load with Webpack. This option can be any property/value combination that +[Webpack accepts](https://webpack.js.org/configuration/output/). + +_Example: Change the public path of the application._ + +```json +{ + "config": { + "neutrino": { + "output": { + "publicPath": "https://cdn.example.com/assets/" + } + } + } +} +``` + +### Node + +Use `node` to customize the Node.js environment using polyfills or mocks: + +_Example: mock the `__filename` and `__dirname` Node.js globals._ + +```json +{ + "config": { + "neutrino": { + "node": { + "__filename": "mock", + "__dirname": "mock" + } + } + } +} +``` + +### DevServer + +Use `devServer` to customize webpack-dev-server and change its behavior in various ways. + +_Example: gzip the application when serving and listen on port 9000._ + +```json +{ + "config": { + "neutrino": { + "devServer": { + "compress": true, + "port": 9000 + } + } + } +} +``` + +### Resolve + +Use `resolve` to change how modules are resolved. When using `resolve.extensions` and `resolve.modules`, these should be +specified as arrays, and will be merged with their respective definitions used in inherited presets. Any additional +properties attached to `resolve` not defined below will be set on the final module configuration. + +_Example: Add `.mjs` as a resolving extension and specify modules are located in a `custom_modules` directory._ + +```json +{ + "config": { + "neutrino": { + "resolve": { + "extensions": [".mjs"], + "modules": ["custom_modules"] + } + } + } +} +``` + +### ResolveLoader + +Use `resolveLoader` to change how loader packages are resolved. When using `resolveLoader.extensions` and +`resolveLoader.modules`, these should be specified as arrays, and will be merged with their respective definitions used +in inherited presets. Any additional properties attached to `resolveLoader` not defined below will be set on the final +module configuration. + +_Example: Add `.loader.js` as a loader extension and specify modules are located in a `web_loaders` directory._ + +```json +{ + "config": { + "neutrino": { + "resolve": { + "extensions": [".loader.js"], + "modules": ["web_loaders"] + } + } + } +} +``` + +### Additional configuration + +Any top-level properties you set on `config.neutrino` will be added to the configuration. + +_Example: Change the Webpack performance options to error when exceeding performance budgets._ + +```json +{ + "config": { + "neutrino": { + "performance": { + "hints": "error" + } + } + } +} +``` + +## Advanced Configuration + +With the options defined above in your package.json, you can perform a variety of build customizations on a per-project +basis. In the event that you need more customization than what is afforded through JSON, consider either switching to +[advanced configuration](/customization/advanced.md), or [creating your own preset](/creating-presets.md). diff --git a/docs/installation.md b/docs/installation.md index 9641475..82a7f72 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,9 +1,11 @@ # Installing Neutrino +## Requirements + Installing Neutrino requires Node.js v6+, and either [Yarn](https://yarnpkg.com/lang/en/docs/install/) or npm. At a minimum you will be installing Neutrino and a Neutrino preset, such as `neutrino-preset-react`. -### Yarn Installation +## Yarn Installation Run the following command inside your project directory. Substitute `PRESET_PKG` with the name of the preset you wish to install. @@ -18,7 +20,7 @@ For example, if you wanted to build your project using Neutrino's React preset: yarn add --dev neutrino neutrino-preset-react ``` -### npm Installation +## npm Installation Run the following command inside your project directory. Substitute `PRESET_PKG` with the name of the preset you wish to install. @@ -33,6 +35,6 @@ For example, if you wanted to build your project using Neutrino's React preset: npm install --save-dev neutrino neutrino-preset-react ``` -### Getting started +## Getting started Please continue through the documentation for instructions on Neutrino usage and default project layout. diff --git a/docs/presets/README.md b/docs/presets/README.md index 152a06e..1e8038f 100644 --- a/docs/presets/README.md +++ b/docs/presets/README.md @@ -1,14 +1,15 @@ # What are presets? -A preset is a Webpack- or Neutrino-compatible configuration capable of building or modifying -the build process for a project. Neutrino provides a few core presets to quickly get -started building some popular project types, but anyone can inherit, extend, and modify these -presets and tailor them to their project preferences. You can even create your own -presets from scratch. +A preset is a Neutrino-compatible configuration capable of building, modifying +the build process, or interacting with a project as a result of building. +Neutrino provides a few core presets to quickly get started building some popular project +types, but anyone can inherit, extend, and modify these presets and tailor them to their project, +team, or company preferences. You can even create your own presets from scratch. If you are familiar with Babel presets, Neutrino presets work similarly. For example, given the Babel preset `babel-preset-react`, you can compile React code with JSX -to vanilla JavaScript calls. Neutrino adopts this same concept. Many more aspects of +to vanilla JavaScript calls. Neutrino adopts this same concept by adapting Webpack into +a tool that understands configurations-as-packages, i.e. presets. Many more aspects of development surround building a complete React project, for which Webpack is commonly used. By encapsulating the common needs of a project type into a preset, Neutrino allows you to avoid the upfront cost of configuring and instead focus on project development. diff --git a/docs/project-layout.md b/docs/project-layout.md index 42c3ca2..f7890d1 100644 --- a/docs/project-layout.md +++ b/docs/project-layout.md @@ -7,9 +7,9 @@ development process for new projects as quick as possible. This is broken up int - Build assets - Testing -Each of these directories are set up via convention by a Neutrino preset, but echo can be customized as +Each of these directories are set up via convention by a Neutrino preset, but each can be customized as desired by overriding the preset's configuration or using a different preset. See -[Custom Configuration](#) for detailed instructions. +[Custom Configuration](/custom-configuration.md) for detailed instructions. ## Source Code @@ -17,23 +17,23 @@ By default Neutrino presets expect all project source code to live in a director root of the project. This includes JavaScript files, CSS stylesheets, images, and any other assets that would be available to your compiled project. -When running your project or creating a build bundle, Neutrino will look for this `src` directory for +When running your project or creating a build bundle, a preset will look for this `src` directory for the entry point(s) to your application and use this as the relative location for finding other assets necessary for creating your builds. ## Build Assets -When creating a build bundle, Neutrino presets will put the compiled assets, including any generated +When creating a build bundle, a preset will put the compiled assets, including any generated JavaScript files, into a directory named `build` by default. Typically your Neutrino preset will copy any non-JavaScript files from the source directory over to the build directory, allowing you to maintain -the same relative path structure for static assets as is used for the built assets. +the same relative path structure for static assets as is used for the source files. -Normally most projects will exclude checking in this build directory to source control, e.g. git, hg, etc. +Normally most projects will exclude checking in this build directory to source control. Be sure to add this directory to your project's `.gitignore`, `.hgignore`, or similar file. ## Testing -Neutrino presets expect all tests to be located in a directory named `test`. In order to make the +Neutrino presets by default expect all tests to be located in a directory named `test`. In order to make the separation between tests and test fixtures or harnesses easier to differentiate, Neutrino presets also usually look for test files ending in `_test.js` or `.test.js`. See your specific test preset for more detailed information about running tests and other conventions.