Skip to content

Commit

Permalink
Merge pull request #22 from lostpebble/simplify-api
Browse files Browse the repository at this point in the history
Simplify API for 2.0.0, aligning with changes over the years
  • Loading branch information
lostpebble authored Oct 8, 2020
2 parents 93dfc07 + 61d991e commit e072ddf
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 106 deletions.
117 changes: 54 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
### Why generate a new `package.json`?

This plugin is useful for when you have a large source project for development / testing from which smaller Node.js projects are bundled for various deployments and applications. Such as Google Cloud Functions.
This plugin is useful for when you have a large source project for development / testing from which smaller Node.js
projects are bundled for various deployments and applications. Such as Google Cloud Functions.

_Or even just for bundling your regular Node.js server code, and knowing that your `package.json` is as lean as it can possibly be for that next deployment._
_Or even just for bundling your regular Node.js server code, and knowing that your `package.json` is as lean as it can
possibly be for that next deployment._

We all know how our development environments can get a bit messy... :sweat_smile:


### :floppy_disk: Install

```
Expand All @@ -20,7 +21,7 @@ npm install generate-package-json-webpack-plugin --save-dev
## :electric_plug: Usage

```
const basePackageValues = {
const basePackage = {
"name": "my-nodejs-module",
"version": "1.0.0",
"main": "./index.js",
Expand All @@ -29,27 +30,28 @@ const basePackageValues = {
}
}
const versionsPackageFilename = __dirname + "/package.json";
// inside your webpack configuration
plugins: [new GeneratePackageJsonPlugin(basePackageValues, versionsPackageFilename)],
plugins: [new GeneratePackageJsonPlugin(basePackage)],
```

That's pretty much it. The plugin will generate a new `package.json` file with all the dependencies your code uses, merged with the values you pass into the plugin. The versions for the detected dependencies are sourced from the `versionsPackageFilename` here.
That's pretty much it. The plugin will generate a new `package.json` file with all the dependencies your code uses. The
versions for the detected dependencies are sourced directly from the modules inside `node_modules`.

**N.B.** This base package file is deliberately barren, as a base to built upon for our final output `package.json`- any
dependencies listed inside of it will be set deliberately and interpretted differently by the generation process. [See
below for more information](#adding-modules-outside-of-your-code-build-modules-etc).

### Important note on `externals`

The plugin only writes the dependencies of modules which are found in the input code
and have been marked in `externals` inside of your Webpack config.
The plugin only writes the dependencies of modules which are found in the input code and have been marked in `externals`
inside of your Webpack config.

This is logical because if a module is not marked as an external module it is included in
your final webpack bundle and hence wouldn't need to be installed as a dependency
again on deployment.
This is logical because if a module is not marked as an external module it is included in your final webpack bundle and
hence wouldn't need to be installed as a dependency again on deployment.

Because of this, this plugin is best used in conjunction with something
like [webpack-node-externals](https://github.com/liady/webpack-node-externals),
which you can use to make sure your node modules are not included with your
final `bundle.js`, like so:
like [webpack-node-externals](https://github.com/liady/webpack-node-externals), which you can use to make sure your node
modules are not included with your final `bundle.js`, like so:

```
const nodeExternals = require("webpack-node-externals");
Expand All @@ -63,13 +65,14 @@ externals: [nodeExternals({
As you can see, you can add modules that you deliberately _do_ want bundled using the `whitelist` option.

### Adding modules outside of your code (build modules etc.)
#### OR to deliberately set different versions of bundled dependencies

Simply place those dependencies inside the `basePackageValues` object which represents the base of the new `package.json` to be created.
#### OR to deliberately set different versions of bundled dependencies, or as different dependency type (`peerDependencies`, for example)

Keep the version number string empty (`""`) to pull the
version from your original `package.json` which was set with `versionsPackageFilename`.
To use a version which is different - set the version string deliberately here.
Simply place those dependencies inside the `basePackageValues` object which represents the base of the
new `package.json` to be created.

Keep the version number string empty (`""`) to have the plugin resolve the version. To use a version which is
different, set the version string deliberately here.

```
const basePackageValues = {
Expand All @@ -82,7 +85,7 @@ const basePackageValues = {
"engines": {
"node": "<= 6.9.1"
},
dependencies: {
devDependencies: {
"cross-var": "^1.1.0",
"cross-env": "",
},
Expand All @@ -92,30 +95,30 @@ const basePackageValues = {
}
```

In this example, `cross-var` has deliberately been set to version `^1.1.0`, and
regardless of what is in `versionsPackageFilename` it will use this version.
`cross-env` however will pull its version number from `versionsPackageFilename`.
In this example, `cross-var` has deliberately been set to version `^1.1.0`, and regardless of what is actually installed
it will use this version.
`cross-env` however will pull its version number from `node_modules`.

This is mostly useful for adding dependencies which are required at runtime but which are not picked up in your webpack
bundle. Such as `cross-var` in this example which injects environment variables into a run script in a cross-platform
friendly way.

Note that the same behaviour applies to all types of dependencies (`dependencies`, `devDependencies` and
`peerDependencies`). In this example `react` will have the same behaviour as `cross-env`, but rather than being placed
Note that the same behaviour applies to all types of dependencies (`dependencies`, `devDependencies` and
`peerDependencies`). In this example `react` will have the same behaviour as `cross-env`, but rather than being placed
inside the `dependencies` list in the output file, it will be placed inside the `peerDependencies` list.

## Simple API

```
new GeneratePackageJsonPlugin(basePackageValues, versionsPackageFilename, extraOptions)
new GeneratePackageJsonPlugin(basePackage, options)
```

### First argument: `basePackageValues`
### First argument: `basePackage`

( **Required** ) You should set the base values for your `package.json` file here. For example:

```
const basePackageValues = {
const basePackage = {
"name": "my-nodejs-module",
"version": "1.0.0",
"main": "./bundle.js",
Expand All @@ -127,21 +130,7 @@ const basePackageValues = {

This will be merged with the generated `"dependencies": { ... }` to form the final `package.json` distribution file.

### Second argument: `versionsPackageFilename`

( **Required** )

This is the filename from which the plugin will source the versions for the modules
that appear in the final generated `package.json`. Usually it will just be the base
`package.json` file in your parent directory (assuming that your development code
has been using dependencies sourced from your base `node_modules` folder):

Commonly, this will be set like this:
```
const versionsPackageFilename = __dirname + "/package.json";
```

### Third argument: `extraOptions`
### Second argument: `options`

( *Optional* )

Expand All @@ -150,39 +139,41 @@ An object with the following structure:
```
{
debug: true,
extraSourcePackageFilenames: [
useInstalledVersions: true,
resolveContextPaths: [__dirname],
sourcePackageFilenames: [
join(__dirname, "../other-workspace/package.json"),
],
additionalDependencies: {
react: "^16.13.1",
},
useInstalledVersions: true,
}
```

**The options:**

`debug` (default: *false*) : Enable to show some debugging information on how the plugin is finding dependencies and creating a new `package.json`.
`debug` (default: *false*) : Enable to show some debugging information on how the plugin is finding dependencies and
creating a new `package.json`.

`extraSourcePackageFilenames` : This is useful for mono-repos and projects where your dependencies in your code are not only defined in a single `package.json` file.
If you share code between multiple projects or "workspaces" to be bundled into a final distribution project, you probably want to set this option.
`useInstalledVersions` (default: *true*) : Resolve node modules and use the exact version that is installed in your
environment. This is useful to lock versions on production deployments. This is the default and easiest way to use the
plugin, if this is not enabled then you should be providing package.json files in `sourcePackageFilenames` from which
the plugin will source module versions.

`additionalDependencies`: A dictionary of additional dependencies (same as `package.json` format) to
add to the generated file. This is useful if you have some dependencies that are not imported in
you code but you still want to include them.
`resolveContextPaths`: Context paths for the internal resolve behaviour that looks upwards for `node_modules` to pull
the versions from. The current directory is the default, but if you have a monorepo, there are edge cases where defining
multiple contexts could be useful.

`useInstalledVersions` (default: *false*) : Resolve node modules and use the exact version that installed in your
environment. This is useful to lock versions on production deployments.
`sourcePackageFilenames` : If the default `useInstalledVersions` option is set, then this is only used as a final
fallback for finding versions. This is useful for mono-repos and projects where your dependencies in your code are not
only defined from a single contextual project. If you share code between multiple projects or "workspaces" to be bundled
into a final distribution project, you might want to set this option.

### :mag: Things to take note of

You should remember to set the `"main": "./index.js"` to the correct filename (would probably
be the output bundle file from the same webpack task), and / or correctly set your starting script
which will be run on Node.js server deployments by `npm start`. You can set these values in
the `basePackageValues` object you pass into the plugin, example:
You should remember to set the `"main": "./index.js"` to the correct filename (would probably be the output bundle file
from the same webpack task), and / or correctly set your starting script which will be run on Node.js server deployments
by `npm start`. You can set these values in the `basePackage` object you pass into the plugin, example:

```
const basePackageValues = {
const basePackage = {
"name": "my-nodejs-module",
"version": "1.0.0",
"main": "./bundle.js",
Expand Down
5 changes: 4 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { Plugin } from 'webpack';
declare class GeneratePackageJsonPlugin extends Plugin {
constructor(
basePackageValues: Record<string, unknown>,
versionsPackageFilename: string,
extraOptions?: {
debug?: boolean;
/** @deprecated Use sourcePackageFilenames instead */
extraSourcePackageFilenames?: string[];
sourcePackageFilenames?: string[];
/** @deprecated Simply add these dependencies to your base package.json */
additionalDependencies?: Record<string, string>;
useInstalledVersions?: boolean;
resolveContextPaths?: string[];
},
);
}
Expand Down
Loading

0 comments on commit e072ddf

Please sign in to comment.