0.4.0 • Published 4 years ago

@nickglenn/frontend-config v0.4.0

Weekly downloads
-
License
MIT
Repository
github
Last release
4 years ago

Frontend Config Preset

This library is a simple preset for quickly setting up a build pipeline using Rollup, Typescript, and PostCSS.

This is an opinionated preset! If you are looking for deeper customization than what's provided here, you may want to consider a different solution or a fully custom build pipeline.

  • Provides loaders for importing JSON, CSS, SASS/SCSS, and PostCSS with autoprefixing for cross-browser support
  • Includes support for .env files
  • Handles injection of environment variables directly into your build
  • Minifies CSS and JS code for production
  • Built in wizard for generating a custom build pipeline for your project
  • Automatic configuration support for popular libraries (like React and Preact)

Usage

Create a new folder, set up a package.json file and then install this library using npm. If you want to short hand this, you can run the following commands in terminal:

mkdir my-project
cd my-project
npm init
npm i -D @nickglenn/frontend-config

Automatic Set Up

After you've set up a package.json and have installed the library. You can run the initialization script using the following command:

npx ng-frontend-init

Manual Set Up

Assuming you're familiar with setting up a Typescript project, you can simply add a rollup.config.js or rollup.config.ts file and fill it out with the following:

import config from "@nickglenn/frontend-config";

module.exports = config({
  /** enter configuration options here */
});

Base Configuration

This config function provided by this library will generate a full Rollup build configuration for you. The only required fields are input and output. All Rollup options are available to you, with exception of plugins which are handled differently.

input

See https://rollupjs.org/guide/en/#input

output

See https://rollupjs.org/guide/en/#output

If the sourcemap property is not provided, this preset will automatically enable it when running a "non-production" build.

external

See https://rollupjs.org/guide/en/#external

If isLibrary is set to true, the external array will automatically be filled in using the names of all the packages found in the "dependencies" map.

dotenv

null | DotenvConfigOptions

Unless explicitly set to null, the dotenv library will be initialized using the provided (or default) settings. This allows for developers to maintain a local .env file with environment variables that will be made available to the build process.

See options for DotenvConfigOptions

isProduction

boolean | () => boolean

Determines whether or not this is a "production" build. By default, this will be set to true if your NODE_ENV is equal to "production". When configured with a function, the function will be invoked after the configuration has loaded environment variables if dotenv is enabled.

allowAutoConfig

boolean

Allows the configuration script to inspect your package.json and make some configuration decisions on your behalf. Defaults to true.

See the Automatic Configuration section below for more information

missingExports

string[]

Packages that don't support ESM compatible exports can cause issues for Rollup's CommonJS plugin. This can be solved manually using namedExports. However, this can be tedious to set up as it involves starting the build, identifying the missing export that crashed the build, add the named export to the list, and then repeating this project until your build succeeds. With this option, you can simply specify a package name and the configuration tool will attempt to handle the rest.

Example

Let's say you get an error like the following:

bundles ./src/index.tsx → dist/app.js...
[!] Error: 'exactProp' is not exported by node_modules/@material-ui/utils/index.js
https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module
node_modules/@material-ui/styles/esm/StylesProvider/StylesProvider.js (5:9)
3: import React from 'react';
4: import PropTypes from 'prop-types';
5: import { exactProp } from '@material-ui/utils';
            ^
6: import createGenerateClassName from '../createGenerateClassName';
7: import { create } from 'jss';
Error: 'exactProp' is not exported by node_modules/@material-ui/utils/index.js

You can resolve this quickly by passing the following option:

missingExports: ["@material-ui/utils"],

isLibrary

boolean

Sets up the bundle to be used as a library, rather than a standalone bundle. I will automatically populated the external property with any dependencies listed in your package.json file and configure Typescript to include declarations alongside your outputted bundle files. Defaults to false.

rootDir

string

Defines the root directory that modules and other files will be resolved from. Defaults to the current working directory using process.cwd().

Note: This setting is also passed directly to Rollup's node-resolve plugin used for resolving modules installed by package managers.

packageJson

Optionally override values loaded from the project's package.json file. See npm's documentation for package.json for the full list of options.

inject

object

Inject values directly into the top of your bundle. The top-level keys must be Javascript safe variable names!

Example

The following configuration would inject the following values into your build.

inject: { foo: { bar: "baz" } }

// would be injected as

var foo = {"bar": "baz"};

injectVersion

Automatically injects a variable into your build using the version property found in the package.json file. Defaults to BUILD_VERSION.

injectVersion: "APP_VERSION"

// compiled.js

var APP_VERSION = "x.x.x";

exposeEnv

string[]

Specify environment variables (by key) that you want injected into your build. Defaults to ["NODE_ENV"].

Example

The following configuration example would allow you to use process.env.NODE_ENV inside your application:

exposeEnv: ["NODE_ENV"]

replace

{ [key: string]: null | boolean | number | string }

Replace compiled code that matches the string key in the object using Rollup's replace plugin. This option will apply JSON.stringify() to each value in the map, making it a more streamlined alternative to configuring the replace plugin yourself.

Example

You could easily replace every instance of a placeholder value like __FOO__ with a string literal, like "bar".

replace: { __FOO__: "bar" }

// someFile.ts (source)

declare const __FOO__: string;
var someValue = __FOO__;

// someFile.js (compiled)

var someValue = "bar";

minify

boolean

When set to true, the bundles will be uglified/minified. If nothing is provided, this will be set to true if your NODE_ENV is equal to "production".

autoprefixCSS

Configure the autoprefixer PostCSS plugin and passes it the styles plugin configuration. Pass null if you don't wish to use automatic vendor prefixing.

useBuiltins

boolean

Automatically appends the rollup-plugin-node-builtins and rollup-plugin-node-globals plugins to the end of the plugins list. This allows NodeJS provided libraries to be used by your front-end code. In some cases, the builtins are just a mock as there's not always a browser capable equivalent.

plugins

See Plugin Configuration

Plugin Configuration

This preset includes a number of popular Rollup plugins and sets up a base configuration for each depending on your other settings. You can customize or override the plugins using either a plugin configuration object or a configuration function.

Using an config object

If you do not wish to change the order of the plugins or add any new plugins to the mix, you can use a configuration object. Each key in the object corresponds to a plugin, and the value is the option argument that is passed to that plugin. The following table lists all of the fields available in the map and the plugin that they correlate to.

Note: You can disabled any plugin from being added by providing null as the value.

FieldPluginDescription
stylesrollup-plugin-postcssHandles importing of CSS, SCSS, and LESS files while also applying PostCSS plugins.
injectInternally generated plugin for injecting values. See inject
json@rollup/plugin-jsonAllows importing of JSON files.
typescriptrollup-plugin-typescriptCompiles Typescript files. Currently using the legacy plugin due to issues with @rollup/plugin-typescript.
replace@rollup/plugin-replaceReplaces values in your files at build time. Required for replace and exposeEnv.
commonjs@rollup/plugin-commonjsHandles importing of CommonJS packages as ES modules. A must have for most projects. Required for missingExports.
alias@rollup/plugin-aliasUsed to alias module imports to other module names or filepaths.
resolve@rollup/plugin-node-resolveHandles resolution of packages installed using a NPM or similar. Another must have for most projects.
strip@rollup/plugin-stripUsed to optimize builds by stripping out debug statements.
uglifyrollup-plugin-uglifyMinifies and compresses the resulting JS modules for a build. Required for minify.

Using a config function

(plugins: PluginFunctionMap) => Plugin[]

For users wishing to alter the plugin setup with greater control, you can use a function that accepts the current configuration created by the preset along with some helper methods for constructing each plugin.

import config from "@nickglenn/frontend-config";
import somePlugin from "some-other-plugin";

module.exports = config({
  plugins: ({ inject, typescript, uglify }) => ([
    inject({
      foo: "bar",
    }),
    typescript(),
    somePlugin(),
    uglify({}),
  ]),
});

Automatic Configurations

When allowAutoConfig is enabled, this preset will scan your package.json file for whatever dependencies you have installed and can make configurations on your behalf for certain libraries and frameworks.

React Support

Due to how React is written, it does not comply with Rollup's ES module requirement and requires some additional set up using Rollup's CommonJS plugin. Rather than having to deal with this manually, this preset will construct the missingExports option for you, adding "react", "react-dom", "react-is", and "prop-types" to the list.

Preact Support

Unlike React, Preact plays extremely well with Typescript and Rollup with no additional configuration. However, to use React libraries with Preact, you need to use Preact's "preact/compat" module. This preset handles that configuration for you, by aliasing "react" and "react-dom" to the aforementioned "preact/compat" library.