Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enabled config overriding by publishConfig #834

Merged
merged 5 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/odd-pets-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'microbundle': patch
---

Add support for configuration overrides using the `publishConfig` package.json field.
99 changes: 64 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,18 @@

2️⃣ **Set up** your `package.json`:

```js
```jsonc
{
"name": "foo", // your package name
"source": "src/foo.js", // your source code
"main": "dist/foo.js", // where to generate the CommonJS/Node bundle
"exports": "./dist/foo.modern.js", // path to the modern output (see below)
"module": "dist/foo.module.js", // where to generate the ESM bundle
"unpkg": "dist/foo.umd.js", // where to generate the UMD bundle (also aliased as "umd:main")
"name": "foo", // your package name
"type": "module",
"source": "src/foo.js", // your source code
"exports": "./dist/foo.modern.js", // where to generate the modern bundle (see below)
"main": "./dist/foo.cjs", // where to generate the CommonJS bundle
"module": "./dist/foo.module.js", // where to generate the ESM bundle
"unpkg": "./dist/foo.umd.js", // where to generate the UMD bundle (also aliased as "umd:main")
"scripts": {
"build": "microbundle", // compiles "source" to "main"/"module"/"unpkg"
"dev": "microbundle watch" // re-build when source files change
"build": "microbundle", // compiles "source" to "main"/"module"/"unpkg"
"dev": "microbundle watch" // re-build when source files change
}
}
```
Expand All @@ -55,11 +56,18 @@

## 💽 Output Formats <a name="formats"></a>

Microbundle produces <code title="ECMAScript Modules (import / export)">esm</code>, <code title="CommonJS (Node-style module.exports)">cjs</code>, <code title="Universal Module Definition (works everywhere)">umd</code> bundles with your code compiled to syntax that works pretty much everywhere. While it's possible to customize the browser or Node versions you wish to support using a [browserslist configuration](https://github.com/browserslist/browserslist#browserslist-), the default setting is optimal and strongly recommended.
Microbundle produces <code title="ECMAScript Modules (import / export)">esm</code>, <code title="CommonJS (Node-style module.exports)">cjs</code>, <code title="Universal Module Definition (works everywhere)">umd</code> bundles with your code compiled to syntax that works pretty much everywhere.
While it's possible to customize the browser or Node versions you wish to support using a [browserslist configuration](https://github.com/browserslist/browserslist#browserslist-), the default setting is optimal and strongly recommended.

## 🤖 Modern Mode <a name="modern"></a>

In addition to the above formats, Microbundle also outputs a `modern` bundle specially designed to work in _all modern browsers_. This bundle preserves most modern JS features when compiling your code, but ensures the result runs in 95% of web browsers without needing to be transpiled. Specifically, it uses [preset-modules](https://github.com/babel/preset-modules) to target the set of browsers that support `<script type="module">` - that allows syntax like async/await, tagged templates, arrow functions, destructured and rest parameters, etc. The result is generally smaller and faster to execute than the `esm` bundle:
In addition to the above formats, Microbundle also outputs a `modern` bundle specially designed to work in _all modern browsers_.
This bundle preserves most modern JS features when compiling your code, but ensures the result runs in 95% of web browsers without needing to be transpiled.
Specifically, it uses Babel's ["bugfixes" mode](https://babeljs.io/blog/2020/03/16/7.9.0#babelpreset-envs-bugfixes-option-11083httpsgithubcombabelbabelpull11083)
(previously known as [preset-modules](https://github.com/babel/preset-modules)) to target the set of browsers that support `<script type="module">` - that allows syntax like async/await, tagged templates, arrow functions, destructured and rest parameters, etc.
The result is generally smaller and faster to execute than the plain `esm` bundle.

Take the following source code for example:

```js
// Our source, "src/make-dom.js":
Expand Down Expand Up @@ -135,38 +143,65 @@ The `"exports"` field can also be an object for packages with multiple entry mod

## 📦 Usage & Configuration <a name="usage"></a>

Microbundle includes two commands - `build` (the default) and `watch`. Neither require any options, but you can tailor things to suit your needs a bit if you like.
Microbundle includes two commands - `build` (the default) and `watch`.
Neither require any options, but you can tailor things to suit your needs a bit if you like.

- **`microbundle`** – bundles your code once and exits. (alias: `microbundle build`)
- **`microbundle watch`** – bundles your code, then re-bundles when files change.

> ℹ️ Microbundle automatically determines which dependencies to inline into bundles based on your `package.json`.
>
> Read more about [How Microbundle decides which dependencies to bundle](https://github.com/developit/microbundle/wiki/How-Microbundle-decides-which-dependencies-to-bundle), including some example configurations.

### `microbundle` / `microbundle build`
### Configuration

Unless overridden via the command line, microbundle uses the `source` property in your `package.json` to locate the input file, and the `main`, `umd:main`, `module` and `exports` properties to figure out where it should place each generated bundle:
Unless overridden via the command line, microbundle uses the `source` property in your `package.json` to determine which of your JavaScript files to start bundling from (your "entry module").
The filenames and paths for generated bundles in each format are defined by the `main`, `umd:main`, `module` and `exports` properties in your `package.json`.


```
```jsonc
{
"source": "src/index.js", // input
"main": "dist/foo.js", // CommonJS output bundle
"umd:main": "dist/foo.umd.js", // UMD output bundle
"module": "dist/foo.m.js", // ES Modules output bundle
"source": "src/index.js", // input
"main": "dist/foo.js", // CommonJS output bundle
"umd:main": "dist/foo.umd.js", // UMD output bundle
"module": "dist/foo.m.js", // ES Modules output bundle
"exports": {
"require": "./dist/foo.js", // CommonJS output bundle
"require": "./dist/foo.js", // CommonJS output bundle
"default": "./dist/foo.modern.js", // Modern ES Modules output bundle
}
"types": "dist/foo.d.ts" // TypeScript typings directory
"types": "dist/foo.d.ts" // TypeScript typings directory
}
```

When deciding which bundle to use, Node.js 12+ and webpack 5+ will prefer the `exports` property, while older Node.js releases use the `main` property, and other bundlers prefer the `module` field. For more information about the meaning of the different properties, refer to the [Node.js documentation](https://nodejs.org/api/packages.html#packages_package_entry_points).
When deciding which bundle to use, Node.js 12+ and webpack 5+ will prefer the `exports` property, while older Node.js releases use the `main` property, and other bundlers prefer the `module` field.
For more information about the meaning of the different properties, refer to the [Node.js documentation](https://nodejs.org/api/packages.html#packages_package_entry_points).

For UMD builds, microbundle will use a camelCase version of the `name` field in your `package.json` as export name.
Alternatively, this can be explicitly by adding an `"amdName"` key in your `package.json`, or passing the `--name` command line argument.

For UMD builds, microbundle will use a camelCase version of the `name` field in your `package.json` as export name. This can be customized using an `"amdName"` key in your `package.json` or the `--name` command line argument.
### Additional Configuration Options

### `microbundle watch`
Config also can be overridded by the [`publishConfig`](https://docs.npmjs.com/cli/v7/configuring-npm/package-json#publishconfig) property in your `package.json`.

Acts just like `microbundle build`, but watches your source files and rebuilds on any change.
```jsonc
{
"main": "src/index.ts", // this would be used in the dev environment (e.g. Jest)
"publishConfig": {
"source": "src/index.js", // input
"main": "dist/my-library.js", // output
},
"scripts": {
"build": "microbundle"
}
}
```

### Building a single bundle with fixed output name

By default Microbundle outputs multiple bundles, one bundle per format. A single bundle with a fixed output name can be built like this:

```bash
microbundle -i lib/main.js -o dist/bundle.js --no-pkg-main -f umd
```

### Using with TypeScript

Expand Down Expand Up @@ -204,19 +239,11 @@ This can be customized by passing the command line argument `--css-modules "[nam
| true | import './my-file.css'; | :white_check_mark: |
| true | import './my-file.module.css'; | :white_check_mark: |

### Building a single bundle with a fixed output name

By default Microbundle outputs multiple bundles, one bundle per format. A single bundle with a fixed output name can be built like this:

```bash
microbundle -i lib/main.js -o dist/bundle.js --no-pkg-main -f umd
```

### Mangling Properties

To achieve the smallest possible bundle size, libraries often wish to rename internal object properties or class members to smaller names - transforming `this._internalIdValue` to `this._i`. Microbundle doesn't do this by default, however it can be enabled by creating a `mangle.json` file (or a `"mangle"` property in your package.json). Within that file, you can specify a regular expression pattern to control which properties should be mangled. For example: to mangle all property names beginning an underscore:

```json
```jsonc
{
"mangle": {
"regex": "^_"
Expand All @@ -236,6 +263,8 @@ The `--define` option can be used to inject or replace build-time constants when
| `microbundle --define API_KEY='abc123'` | `console.log(API_KEY)` | `console.log("abc123")` |
| `microbundle --define @assign=Object.assign` | `assign(a, b)` | `Object.assign(a, b)` |



### All CLI Options <a name="options"></a>

```
Expand Down
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ export default async function microbundle(inputOptions) {
const cwd = options.cwd;

const { hasPackageJson, pkg } = await getConfigFromPkgJson(cwd);
options.pkg = pkg;
options.pkg = {
...pkg,
...pkg.publishConfig,
};

const { finalName, pkgName } = getName({
name: options.name,
Expand Down
34 changes: 34 additions & 0 deletions test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2441,6 +2441,40 @@ exports[`fixtures build pretty with microbundle 5`] = `
"
`;

exports[`fixtures build publish-config with microbundle 1`] = `
"Used script: microbundle -f cjs

Directory tree:

publish-config
dist
bar.js
bar.js.map
foo.d.ts
node_modules
package.json
src
foo.ts


Build \\"publishConfig\\" to dist:
55 B: bar.js.gz
33 B: bar.js.br"
`;

exports[`fixtures build publish-config with microbundle 2`] = `3`;

exports[`fixtures build publish-config with microbundle 3`] = `
"exports.foo=function(){return 42};
//# sourceMappingURL=bar.js.map
"
`;

exports[`fixtures build publish-config with microbundle 4`] = `
"export declare function foo(): number;
"
`;

exports[`fixtures build pure with microbundle 1`] = `
"Used script: microbundle

Expand Down
11 changes: 11 additions & 0 deletions test/fixtures/publish-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "publish-config",
"main": "src/foo.ts",
"publishConfig": {
"source": "src/foo.ts",
"main": "dist/bar.js"
},
"scripts": {
"build": "microbundle -f cjs"
}
}
3 changes: 3 additions & 0 deletions test/fixtures/publish-config/src/foo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function foo() {
return 42;
}