feat(preset-rollup): provide a preset for code bundling via rollup
This commit is contained in:
commit
dfebcbe9a5
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"preset": "presetter-preset",
|
||||||
|
"config": {
|
||||||
|
"npmignore": ["!/configs/**", "!/templates/**"]
|
||||||
|
},
|
||||||
|
"variable": {
|
||||||
|
"root": "../.."
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,192 @@
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
![Logo](https://github.com/alvis/presetter/raw/master/assets/logo.svg)
|
||||||
|
|
||||||
|
🏄🏻 _A collection of opinionated configurations for a building a code bundle via rollup for presetter_
|
||||||
|
|
||||||
|
• [Quick Start](#quick-start) • [Project Structure](#project-structure) • [Customisation](#customisation) • [Scripts](#script-template-summary) •
|
||||||
|
|
||||||
|
[![npm](https://img.shields.io/npm/v/presetter-preset-rollup?style=flat-square)](https://github.com/alvis/presetter/releases)
|
||||||
|
[![build](https://img.shields.io/github/workflow/status/alvis/presetter/code%20test?style=flat-square)](https://github.com/alvis/presetter/actions)
|
||||||
|
[![maintainability](https://img.shields.io/codeclimate/maintainability/alvis/presetter?style=flat-square)](https://codeclimate.com/github/alvis/presetter/maintainability)
|
||||||
|
[![coverage](https://img.shields.io/codeclimate/coverage/alvis/presetter?style=flat-square)](https://codeclimate.com/github/alvis/presetter/test_coverage)
|
||||||
|
[![security](https://img.shields.io/snyk/vulnerabilities/github/alvis/presetter/packages/preset-rollup/package.json.svg?style=flat-square)](https://snyk.io/test/github/alvis/presetter?targetFile=packages/preset-rollup/package.json&style=flat-square)
|
||||||
|
[![dependencies](https://img.shields.io/david/alvis/presetter?path=packages/preset-rollup&style=flat-square)](https://david-dm.org/alvis/presetter?path=packages/preset-rollup)
|
||||||
|
[![license](https://img.shields.io/github/license/alvis/presetter.svg?style=flat-square)](https://github.com/alvis/presetter/blob/master/LICENSE)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
**presetter-preset-rollup** is an opinionated preset for you to setup rollup in a fraction of time you usually take via [**presetter**](https://github.com/alvis/presetter).
|
||||||
|
|
||||||
|
- 🗞️ Rollup 2
|
||||||
|
- 2️⃣ Dual CJS and ESM modules export by default
|
||||||
|
- 🍄 Common rollup packages included as one single bundle
|
||||||
|
- `@rollup/plugin-commonjs`
|
||||||
|
- `@rollup/plugin-graphql`
|
||||||
|
- `@rollup/plugin-image`
|
||||||
|
- `@rollup/plugin-json`
|
||||||
|
- `@rollup/plugin-yaml`
|
||||||
|
- `rollup` <~ of course including rollup itself
|
||||||
|
- `rollup-plugin-postcss`
|
||||||
|
- `rollup-plugin-ts`
|
||||||
|
- `rollup-plugin-tsconfig-paths`
|
||||||
|
- `rollup-plugin-visualizer`
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
[**FULL DOCUMENTATION IS AVAILABLE HERE**](https://github.com/alvis/presetter/blob/master/README.md)
|
||||||
|
|
||||||
|
1. Bootstrap your project with `presetter-preset` & `presetter-preset-rollup`
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npx presetter use presetter-preset presetter-preset-rollup
|
||||||
|
```
|
||||||
|
|
||||||
|
That's. One command and you're set.
|
||||||
|
|
||||||
|
After bootstrapping, you would see a lot of configuration files generated, including a `rollup.config.ts` that has all plugins configured properly for you.
|
||||||
|
|
||||||
|
2. Develop and run life cycle scripts provided by the preset
|
||||||
|
|
||||||
|
At this point, all development packages specified in the preset are installed,
|
||||||
|
and now you can try to run some example life cycle scripts (e.g. run prepare).
|
||||||
|
|
||||||
|
![Demo](https://raw.githubusercontent.com/alvis/presetter/master/assets/demo.gif)
|
||||||
|
|
||||||
|
**IMPORTANT**
|
||||||
|
For NodeJS to import the correct export, remember to specify the following in your project's package.json too!
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"module": "lib/index.mjs",
|
||||||
|
"types": "lib/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
"require": "./lib/index.js",
|
||||||
|
"import": "./lib/index.mjs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
After installing `presetter-preset` & `presetter-preset-rollup`, your project file structure should look like the following or with more configuration file if you also installed `presetter-preset`.
|
||||||
|
|
||||||
|
Implement your business logic under `source` and prepare tests under `spec`.
|
||||||
|
|
||||||
|
**TIPS** You can always change the source directory to other (e.g. src) by setting the `source` variable in `.presetterrc.json`. See the [customisation](https://github.com/alvis/presetter/blob/master/packages/preset-rollup#customisation) section below for more details.
|
||||||
|
|
||||||
|
```
|
||||||
|
(root)
|
||||||
|
├─ .git
|
||||||
|
├─ .preseterrc.json
|
||||||
|
├─ node_modules
|
||||||
|
├─ source
|
||||||
|
│ ├─ <folders>
|
||||||
|
│ ├─ index.ts
|
||||||
|
│ ├─ (auxiliary).ts
|
||||||
|
├─ spec
|
||||||
|
│ ├─ *.spec.ts
|
||||||
|
├─ package.json
|
||||||
|
└─ rollup.config.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customisation
|
||||||
|
|
||||||
|
By default, this preset exports a handy configuration for rollup for a typescript project.
|
||||||
|
But you can further customise (either extending or replacing) the configuration by specifying the change in the config file (`.presetterrc` or `.presetterrc.json`).
|
||||||
|
|
||||||
|
These settings are available in the `config` field in the config file. For directories, the setting is specified in the `variable` field.
|
||||||
|
|
||||||
|
The structure of `.presetterrc` should follow the interface below:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface PresetterRC {
|
||||||
|
/** name(s) of the preset e.g. presetter-preset */
|
||||||
|
name: string | string[];
|
||||||
|
/** additional configuration passed to the preset for generating the configuration files */
|
||||||
|
config?: {
|
||||||
|
// ┌─ configuration for other tools via other presets (e.g. presetter-preset)
|
||||||
|
// ...
|
||||||
|
|
||||||
|
/** additional configuration for rollup */
|
||||||
|
rollup?: {
|
||||||
|
// ┌─ any configuration supported by rollup, see https://rollupjs.org/guide/en/#configuration-files
|
||||||
|
// ...
|
||||||
|
|
||||||
|
/** list of plugin and its options */
|
||||||
|
plugins?:
|
||||||
|
| NormalisedRollupConfig['plugins']
|
||||||
|
| Array<
|
||||||
|
| string
|
||||||
|
| [name: string]
|
||||||
|
| [
|
||||||
|
name: string,
|
||||||
|
options:
|
||||||
|
| Record<string, unknown>
|
||||||
|
| `@apply ${string}`
|
||||||
|
| `@import ${string}`
|
||||||
|
| null,
|
||||||
|
]
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** variables to be substituted in templates */
|
||||||
|
variable?: {
|
||||||
|
/** the directory containing all source code (default: source) */
|
||||||
|
source?: string;
|
||||||
|
/** the directory containing all output tile (default: source) */
|
||||||
|
output?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For generating `rollup.config.ts`, this preset also support the `@apply` and `@import` directives such that you can also import configuration from other packages or ts/js files.
|
||||||
|
|
||||||
|
The usage of the directives is simple. In any part of the configuration for rollup, you can simply put
|
||||||
|
`@apply package_name` or `@import package_name` and the preset will automatically replace the content with an imported variable. For example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"rollup": {
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"@apply rollup-plugin-postcss[default]",
|
||||||
|
{ "plugins": "@import ./postcss.config[default.plugins]" }
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
will create a `rollup.config.ts` file with the following content:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import * as import0 from 'rollup-plugin-postcss';
|
||||||
|
import * as import1 from './postcss.config';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
plugins: [import0.default(...[{ plugins: import1.default.plugins }])],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
The syntax for both the directives is quite similar.
|
||||||
|
Use `@apply` in a situation that you have to invoke a function from an imported package,
|
||||||
|
such as `rollup-plugin-postcss` in the above example.
|
||||||
|
You can also specify the arguments for the invoked function in the form of `["@apply package", options]`
|
||||||
|
|
||||||
|
For `@import`, use it if you want to import value from another package or ts/js file.
|
||||||
|
For example, `@import ./postcss.config[default.plugins]` would allow you to refer `default.plugins` from `./postcss.config` in the above example.
|
||||||
|
|
||||||
|
In addition to the directives, to specify the plugins for rollup, you can write it in three ways similar to babel.
|
||||||
|
|
||||||
|
1. A object with plugin name as the key and its options as its value e.g. `{'@apply @rollup/plugin-typescript[default]': {options}}`
|
||||||
|
2. Name of a plugin in an array e.g. `['@apply @rollup/plugin-typescript[default]']`
|
||||||
|
3. Doublet of `[plugin name, options]` in an array e.g. `[['@apply @rollup/plugin-typescript[default]', {options}]]`
|
||||||
|
|
||||||
|
## Script Template Summary
|
||||||
|
|
||||||
|
- **`run build`**: Bundle your code via rollup
|
||||||
|
- **`run develop`**: Continuous code build and watch
|
|
@ -0,0 +1,26 @@
|
||||||
|
input: '{source}/index.ts'
|
||||||
|
output:
|
||||||
|
- file: '{output}/index.js'
|
||||||
|
format: cjs
|
||||||
|
sourcemap: true
|
||||||
|
- file: '{output}/index.mjs'
|
||||||
|
format: es
|
||||||
|
sourcemap: true
|
||||||
|
plugins:
|
||||||
|
- '@apply rollup-plugin-ts[default]'
|
||||||
|
- '@apply rollup-plugin-tsconfig-paths[default]'
|
||||||
|
- '@apply @rollup/plugin-node-resolve[default]'
|
||||||
|
- - '@apply @rollup/plugin-commonjs[default]'
|
||||||
|
- extensions:
|
||||||
|
- .js
|
||||||
|
- .jsx
|
||||||
|
- .ts
|
||||||
|
- .tsx
|
||||||
|
- '@apply @rollup/plugin-json[default]'
|
||||||
|
- '@apply @rollup/plugin-graphql[default]'
|
||||||
|
- '@apply @rollup/plugin-image[default]'
|
||||||
|
- '@apply @rollup/plugin-yaml[default]'
|
||||||
|
- - '@apply rollup-plugin-postcss[default]'
|
||||||
|
- inject:
|
||||||
|
insertAt: top
|
||||||
|
- '@apply rollup-plugin-visualizer[default]'
|
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
"name": "presetter-preset-rollup",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "An opinionated presetter preset for using rollup as a bundler",
|
||||||
|
"keywords": [
|
||||||
|
"presetter",
|
||||||
|
"preset"
|
||||||
|
],
|
||||||
|
"homepage": "https://github.com/alvis/presetter#readme",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/alvis/presetter/issues"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"author": {
|
||||||
|
"name": "Alvis HT Tang",
|
||||||
|
"email": "alvis@hilbert.space"
|
||||||
|
},
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"types": "lib/index.d.ts",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/alvis/presetter.git"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"bootstrap": "presetter bootstrap && run prepare",
|
||||||
|
"build": "run build",
|
||||||
|
"coverage": "run coverage",
|
||||||
|
"lint": "run lint",
|
||||||
|
"prepublishOnly": "run prepare && run prepublishOnly",
|
||||||
|
"release": "run-s release:peer:*",
|
||||||
|
"release:peer:presetter": "npm pkg set peerDependencies.presetter=^$(npx -c 'echo $npm_package_version')",
|
||||||
|
"test": "run test",
|
||||||
|
"watch": "run watch"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@rollup/plugin-commonjs": "^20.0.0",
|
||||||
|
"@rollup/plugin-graphql": "^1.0.0",
|
||||||
|
"@rollup/plugin-image": "^2.0.0",
|
||||||
|
"@rollup/plugin-json": "^4.0.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||||
|
"@rollup/plugin-yaml": "^3.0.0",
|
||||||
|
"presetter": "^3.0.0",
|
||||||
|
"rollup": "^2.0.0",
|
||||||
|
"rollup-plugin-postcss": "^4.0.0",
|
||||||
|
"rollup-plugin-ts": "^1.0.0",
|
||||||
|
"rollup-plugin-tsconfig-paths": "^1.0.0",
|
||||||
|
"rollup-plugin-visualizer": "^5.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"presetter": "file:../presetter",
|
||||||
|
"presetter-preset": "file:../preset"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* *** MIT LICENSE ***
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* This code may be modified and distributed under the MIT license.
|
||||||
|
* See the LICENSE file for details.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* @summary Collection of preset assets for bundling a project with rollup
|
||||||
|
*
|
||||||
|
* @author Alvis HT Tang <alvis@hilbert.space>
|
||||||
|
* @license MIT
|
||||||
|
* @copyright Copyright (c) 2021 - All Rights Reserved.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { resolve } from 'path';
|
||||||
|
import { loadFile, template } from 'presetter';
|
||||||
|
|
||||||
|
import { getRollupParameter } from './rollup';
|
||||||
|
|
||||||
|
import type { PresetAsset } from 'presetter';
|
||||||
|
|
||||||
|
import type { RollupConfig } from './rollup';
|
||||||
|
|
||||||
|
// paths to the template directory
|
||||||
|
const TEMPLATES = resolve(__dirname, '..', 'templates');
|
||||||
|
const CONFIGS = resolve(__dirname, '..', 'configs');
|
||||||
|
|
||||||
|
/** config for this preset */
|
||||||
|
export type PresetConfig = {
|
||||||
|
rollup?: RollupConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** List of configurable variables */
|
||||||
|
export type Variable = {
|
||||||
|
/** the directory containing all source code (default: source) */
|
||||||
|
source: string;
|
||||||
|
/** the directory containing all the compiled files (default: lib) */
|
||||||
|
output: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DEFAULT_VARIABLE: Variable = {
|
||||||
|
source: 'source',
|
||||||
|
output: 'lib',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the list of templates provided by this preset
|
||||||
|
* @returns list of preset templates
|
||||||
|
*/
|
||||||
|
export default async function (): Promise<PresetAsset> {
|
||||||
|
return {
|
||||||
|
template: {
|
||||||
|
'rollup.config.ts': async (context) => {
|
||||||
|
const content = await loadFile(
|
||||||
|
resolve(TEMPLATES, 'rollup.config.ts'),
|
||||||
|
'text',
|
||||||
|
);
|
||||||
|
const variable = await getRollupParameter(context);
|
||||||
|
|
||||||
|
return template(content, variable);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scripts: resolve(TEMPLATES, 'scripts.yaml'),
|
||||||
|
noSymlinks: ['rollup.config.ts'],
|
||||||
|
supplementaryConfig: {
|
||||||
|
gitignore: ['/rollup.config.ts'],
|
||||||
|
rollup: resolve(CONFIGS, 'rollup.yaml'),
|
||||||
|
},
|
||||||
|
variable: DEFAULT_VARIABLE,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* *** MIT LICENSE ***
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* This code may be modified and distributed under the MIT license.
|
||||||
|
* See the LICENSE file for details.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* @summary Collection of plugin related helpers
|
||||||
|
*
|
||||||
|
* @author Alvis HT Tang <alvis@hilbert.space>
|
||||||
|
* @license MIT
|
||||||
|
* @copyright Copyright (c) 2021 - All Rights Reserved.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { isDirective } from 'presetter';
|
||||||
|
|
||||||
|
import type { ApplyDirective, ImportDirective } from 'presetter';
|
||||||
|
|
||||||
|
/** full configuration about a plugin */
|
||||||
|
export type PluginConfiguration =
|
||||||
|
| [name: PluginHeader]
|
||||||
|
| [name: PluginHeader, options: PluginOptions | null];
|
||||||
|
|
||||||
|
/** specification of a plugin name and its handling direction (e.g. by invoking the function or just simply specify the name) */
|
||||||
|
export type PluginHeader = string | ApplyDirective;
|
||||||
|
|
||||||
|
/** options for a plugin */
|
||||||
|
export type PluginOptions =
|
||||||
|
| Record<string, unknown>
|
||||||
|
| ApplyDirective
|
||||||
|
| ImportDirective;
|
||||||
|
|
||||||
|
/** plugin configuration as an object */
|
||||||
|
export type PluginObject = Record<PluginHeader, PluginOptions | null>;
|
||||||
|
|
||||||
|
/** plugin configuration as an array */
|
||||||
|
export type PluginList = PluginListItem[];
|
||||||
|
|
||||||
|
/** possible types for individual item in a PluginList */
|
||||||
|
type PluginListItem = PluginHeader | [name: PluginHeader] | PluginConfiguration;
|
||||||
|
|
||||||
|
/** all possible configuration form for a collection of plugins */
|
||||||
|
export type PluginManifest = PluginList | PluginObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ensure that the given value is a valid PluginManifest
|
||||||
|
* @param value value to be tested
|
||||||
|
* @returns nothing if it's a pass
|
||||||
|
*/
|
||||||
|
export function assertPluginManifest(
|
||||||
|
value: unknown,
|
||||||
|
): asserts value is PluginManifest {
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return assertPluginList(value);
|
||||||
|
} else if (value !== null) {
|
||||||
|
return assertPluginObject(value as Record<string, unknown>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new TypeError('plugin manifest is not in a supported format');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ensure that the given value is a valid PluginObject
|
||||||
|
* @param value value to be tested
|
||||||
|
*/
|
||||||
|
export function assertPluginObject(
|
||||||
|
value: Record<string, unknown>,
|
||||||
|
): asserts value is PluginObject {
|
||||||
|
// all values must be an object
|
||||||
|
if (
|
||||||
|
[...Object.values(value)].some(
|
||||||
|
(opt) => typeof opt !== 'object' && !isDirective(opt),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new TypeError('all plugin options must be a object');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ensure that the given value is a valid PluginList
|
||||||
|
* @param value value to be tested
|
||||||
|
*/
|
||||||
|
export function assertPluginList(
|
||||||
|
value: unknown[],
|
||||||
|
): asserts value is PluginList {
|
||||||
|
for (const plugin of value) {
|
||||||
|
assertPluginListItem(plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PLUGIN_LIST_MAX_ITEMS = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ensure that the given value is a valid PluginListItem
|
||||||
|
* @param value value to be tested
|
||||||
|
*/
|
||||||
|
export function assertPluginListItem(
|
||||||
|
value: unknown,
|
||||||
|
): asserts value is PluginListItem {
|
||||||
|
if (
|
||||||
|
typeof value !== 'string' &&
|
||||||
|
!(
|
||||||
|
Array.isArray(value) &&
|
||||||
|
value.length <= PLUGIN_LIST_MAX_ITEMS &&
|
||||||
|
typeof value[0] === 'string' &&
|
||||||
|
(isDirective(value[1]) ||
|
||||||
|
['undefined', 'object'].includes(typeof value[1]))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new TypeError(
|
||||||
|
'a plugin manifest in an array form must be in either one of the following forms: string, [string], [string, object]',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
* *** MIT LICENSE ***
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* This code may be modified and distributed under the MIT license.
|
||||||
|
* See the LICENSE file for details.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* @summary Collection of helpers for rollup
|
||||||
|
*
|
||||||
|
* @author Alvis HT Tang <alvis@hilbert.space>
|
||||||
|
* @license MIT
|
||||||
|
* @copyright Copyright (c) 2021 - All Rights Reserved.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
isDirective,
|
||||||
|
isJSON,
|
||||||
|
merge,
|
||||||
|
resolveDirective,
|
||||||
|
template,
|
||||||
|
} from 'presetter';
|
||||||
|
|
||||||
|
import { assertPluginManifest } from './plugin';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
PluginConfiguration,
|
||||||
|
PluginList,
|
||||||
|
PluginManifest,
|
||||||
|
PluginObject,
|
||||||
|
} from './plugin';
|
||||||
|
import type {
|
||||||
|
ApplyDirective,
|
||||||
|
ImportDirective,
|
||||||
|
ResolvedPresetContext,
|
||||||
|
} from 'presetter';
|
||||||
|
|
||||||
|
|
||||||
|
/** preset configuration for rollup */
|
||||||
|
export interface RollupConfig {
|
||||||
|
[index: string]: unknown | RollupConfig;
|
||||||
|
/** list of plugin and its options */
|
||||||
|
plugins?: PluginManifest | ApplyDirective | ImportDirective;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** genuine configuration that rollup would take, making sure all plugins are a list */
|
||||||
|
interface TrueRollupConfig {
|
||||||
|
[index: string]: unknown | TrueRollupConfig;
|
||||||
|
/** list of plugin and its options */
|
||||||
|
plugins?: PluginConfiguration[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** transformed configuration for rollup, with all plugins represented by an object */
|
||||||
|
interface IntermediateRollupConfig {
|
||||||
|
[index: string]: unknown | IntermediateRollupConfig;
|
||||||
|
/** list of plugin and its options */
|
||||||
|
plugins?: PluginObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get template parameters for rollup
|
||||||
|
* @param context context about the build environment
|
||||||
|
* @returns template parameter related to rollup
|
||||||
|
*/
|
||||||
|
export async function getRollupParameter(
|
||||||
|
context: ResolvedPresetContext,
|
||||||
|
): Promise<Record<'rollupImport' | 'rollupExport', string>> {
|
||||||
|
const { config, variable } = context.custom;
|
||||||
|
|
||||||
|
const normalisedConfig = template(
|
||||||
|
normaliseConfig(transformConfig({ ...config.rollup })),
|
||||||
|
variable,
|
||||||
|
);
|
||||||
|
|
||||||
|
return generateRollupParameter(normalisedConfig, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate template parameters for rollup
|
||||||
|
* @param config normalised rollup config
|
||||||
|
* @param context context about the build environment
|
||||||
|
* @returns template parameter related to rollup
|
||||||
|
*/
|
||||||
|
function generateRollupParameter(
|
||||||
|
config: TrueRollupConfig,
|
||||||
|
context: ResolvedPresetContext,
|
||||||
|
): Record<'rollupImport' | 'rollupExport', string> {
|
||||||
|
const { importMap, stringifiedConfig } = resolveDirective(config, context);
|
||||||
|
|
||||||
|
// generate import statements
|
||||||
|
const rollupImport = Object.entries(importMap)
|
||||||
|
.map(([name, resolved]) => `import * as ${resolved} from '${name}';`)
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
// generate export statements
|
||||||
|
const rollupExport = `export default ${stringifiedConfig}`;
|
||||||
|
|
||||||
|
return { rollupImport, rollupExport };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* normalise rollup config with all plugins represented as a list
|
||||||
|
* @param config transformed config
|
||||||
|
* @returns config that rollup would take
|
||||||
|
*/
|
||||||
|
function normaliseConfig(config: IntermediateRollupConfig): TrueRollupConfig {
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(config).map(([key, value]): [string, unknown] => {
|
||||||
|
return [
|
||||||
|
key,
|
||||||
|
isDirective(value) ? value : normaliseConfigValue(key, value),
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* try to normalise any nested configuration
|
||||||
|
* @param key field name
|
||||||
|
* @param value value of a field
|
||||||
|
* @returns normalised value
|
||||||
|
*/
|
||||||
|
function normaliseConfigValue(key: string, value: unknown): unknown {
|
||||||
|
switch (key) {
|
||||||
|
case 'plugins':
|
||||||
|
return [
|
||||||
|
...Object.entries(value as PluginObject)
|
||||||
|
.filter(([_, options]) => options !== null)
|
||||||
|
.map(([plugin, options]) =>
|
||||||
|
[plugin, normaliseConfigValue(plugin, options)].filter(
|
||||||
|
(element) => element !== undefined,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
default:
|
||||||
|
return isJSON(value)
|
||||||
|
? normaliseConfig(value as IntermediateRollupConfig)
|
||||||
|
: value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* transform rollup config with plugins represented by an object for better merging
|
||||||
|
* @param config rollup config in .presetterrc
|
||||||
|
* @returns transformed config
|
||||||
|
*/
|
||||||
|
function transformConfig(
|
||||||
|
config: Record<string, any>,
|
||||||
|
): IntermediateRollupConfig {
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(config).map(([key, value]): [string, unknown] => {
|
||||||
|
return [
|
||||||
|
key,
|
||||||
|
isDirective(value) ? value : transformConfigValue(key, value),
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* try to transform any nested configuration
|
||||||
|
* @param key field name
|
||||||
|
* @param value value of a field
|
||||||
|
* @returns transformed value
|
||||||
|
*/
|
||||||
|
function transformConfigValue(key: string, value: unknown): unknown {
|
||||||
|
switch (key) {
|
||||||
|
case 'plugins':
|
||||||
|
assertPluginManifest(value);
|
||||||
|
|
||||||
|
return objectifyPlugins(value);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return isJSON(value) ? transformConfig(value) : value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* objectify rollup plugins
|
||||||
|
* @param plugins rollup plugin config
|
||||||
|
* @returns normalised plugin config
|
||||||
|
*/
|
||||||
|
function objectifyPlugins(
|
||||||
|
plugins: PluginManifest,
|
||||||
|
): IntermediateRollupConfig['plugins'] {
|
||||||
|
const normalisedPlugin: PluginObject = {};
|
||||||
|
|
||||||
|
const pluginList: PluginConfiguration[] = Array.isArray(plugins)
|
||||||
|
? arrayToPluginConfiguration(plugins)
|
||||||
|
: objectToPluginConfiguration(plugins);
|
||||||
|
|
||||||
|
for (const [name, options] of pluginList) {
|
||||||
|
Object.assign(
|
||||||
|
normalisedPlugin,
|
||||||
|
merge(normalisedPlugin, { [name]: options }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalisedPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* normalise rollup plugin config in array form
|
||||||
|
* @param plugins rollup plugin config in array form
|
||||||
|
* @returns normalised plugin config
|
||||||
|
*/
|
||||||
|
function arrayToPluginConfiguration(
|
||||||
|
plugins: PluginList,
|
||||||
|
): PluginConfiguration[] {
|
||||||
|
return plugins.map((plugin) =>
|
||||||
|
typeof plugin === 'string' ? [plugin] : plugin,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* normalise rollup plugin config in object form
|
||||||
|
* @param plugins rollup plugin config in object form
|
||||||
|
* @returns normalised plugin config
|
||||||
|
*/
|
||||||
|
function objectToPluginConfiguration(
|
||||||
|
plugins: PluginObject,
|
||||||
|
): PluginConfiguration[] {
|
||||||
|
return [...Object.entries(plugins)];
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* *** MIT LICENSE ***
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* This code may be modified and distributed under the MIT license.
|
||||||
|
* See the LICENSE file for details.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* @summary Tests on config generation
|
||||||
|
*
|
||||||
|
* @author Alvis HT Tang <alvis@hilbert.space>
|
||||||
|
* @license MIT
|
||||||
|
* @copyright Copyright (c) 2020 - All Rights Reserved.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readdirSync } from 'fs';
|
||||||
|
import { resolve } from 'path';
|
||||||
|
import { resolveContext, resolveDynamicMap } from 'presetter';
|
||||||
|
|
||||||
|
import getPresetAsset from '#index';
|
||||||
|
|
||||||
|
jest.mock('path', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
...jest.requireActual('path'),
|
||||||
|
resolve: jest.fn(jest.requireActual('path').resolve),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('fn:getPresetAsset', () => {
|
||||||
|
it('use all templates', async () => {
|
||||||
|
const assets = [await getPresetAsset()];
|
||||||
|
const context = await resolveContext(assets, {
|
||||||
|
target: { name: 'preset', root: '/', package: {} },
|
||||||
|
custom: { preset: 'preset' },
|
||||||
|
});
|
||||||
|
|
||||||
|
// load all potential dynamic content
|
||||||
|
await resolveDynamicMap(assets, context, 'supplementaryConfig');
|
||||||
|
await resolveDynamicMap(assets, context, 'template');
|
||||||
|
|
||||||
|
const TEMPLATES = resolve(__dirname, '..', 'templates');
|
||||||
|
const allTemplates = await readdirSync(TEMPLATES);
|
||||||
|
const CONFIGS = resolve(__dirname, '..', 'configs');
|
||||||
|
const supplementaryConfig = await readdirSync(CONFIGS);
|
||||||
|
|
||||||
|
for (const path of allTemplates) {
|
||||||
|
expect(resolve).toBeCalledWith(TEMPLATES, path);
|
||||||
|
}
|
||||||
|
for (const path of supplementaryConfig) {
|
||||||
|
expect(resolve).toBeCalledWith(CONFIGS, path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* *** MIT LICENSE ***
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* This code may be modified and distributed under the MIT license.
|
||||||
|
* See the LICENSE file for details.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* @summary Tests on plugin related helpers
|
||||||
|
*
|
||||||
|
* @author Alvis HT Tang <alvis@hilbert.space>
|
||||||
|
* @license MIT
|
||||||
|
* @copyright Copyright (c) 2021 - All Rights Reserved.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
assertPluginList,
|
||||||
|
assertPluginListItem,
|
||||||
|
assertPluginObject,
|
||||||
|
assertPluginManifest,
|
||||||
|
} from '#plugin';
|
||||||
|
|
||||||
|
describe('fn:assertPluginListItem', () => {
|
||||||
|
it('pass with just a string', () => {
|
||||||
|
expect(() => assertPluginListItem('plugin')).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('pass with a string in an array', () => {
|
||||||
|
expect(() => assertPluginListItem(['plugin'])).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('pass with a string and its options in an array', () => {
|
||||||
|
expect(() =>
|
||||||
|
assertPluginListItem(['plugin', { options: true }]),
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails with a non-string header', () => {
|
||||||
|
expect(() => assertPluginListItem([0])).toThrow(TypeError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails with an array more than 2 items', () => {
|
||||||
|
expect(() =>
|
||||||
|
assertPluginListItem(['plugin', { options: true }, 'extra']),
|
||||||
|
).toThrow(TypeError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fn:assertPluginList', () => {
|
||||||
|
it('pass with a valid plugin configuration list', () => {
|
||||||
|
expect(() =>
|
||||||
|
assertPluginList(['plugin', ['plugin'], ['plugin', { options: true }]]),
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fail with any invalid plugin configurations', () => {
|
||||||
|
expect(() =>
|
||||||
|
assertPluginList([
|
||||||
|
'plugin',
|
||||||
|
['plugin'],
|
||||||
|
['plugin', { options: true }],
|
||||||
|
{ invalid: true },
|
||||||
|
]),
|
||||||
|
).toThrow(TypeError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fn:assertPluginObject', () => {
|
||||||
|
it('pass with a valid plugin configuration object', () => {
|
||||||
|
expect(() =>
|
||||||
|
assertPluginObject({ plugin: { options: true } }),
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fail with any invalid plugin options', () => {
|
||||||
|
expect(() => assertPluginObject({ plugin: true })).toThrow(TypeError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fn:assertPluginManifest', () => {
|
||||||
|
it('pass with a valid plugin configuration object', () => {
|
||||||
|
expect(() =>
|
||||||
|
assertPluginManifest({ plugin: { options: true } }),
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('pass with a valid plugin configuration list', () => {
|
||||||
|
expect(() =>
|
||||||
|
assertPluginManifest([
|
||||||
|
'plugin',
|
||||||
|
['plugin'],
|
||||||
|
['plugin', { options: true }],
|
||||||
|
]),
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fail with any invalid manifest', () => {
|
||||||
|
expect(() => assertPluginManifest(null)).toThrow(TypeError);
|
||||||
|
expect(() => assertPluginManifest('invalid')).toThrow(TypeError);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* *** MIT LICENSE ***
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* This code may be modified and distributed under the MIT license.
|
||||||
|
* See the LICENSE file for details.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* @summary Tests on the helpers for rollup
|
||||||
|
*
|
||||||
|
* @author Alvis HT Tang <alvis@hilbert.space>
|
||||||
|
* @license MIT
|
||||||
|
* @copyright Copyright (c) 2021 - All Rights Reserved.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getRollupParameter } from '#rollup';
|
||||||
|
|
||||||
|
import type { Config, ResolvedPresetContext } from 'presetter';
|
||||||
|
|
||||||
|
describe('fn:getRollupParameter', () => {
|
||||||
|
const generateContext = (config?: Config): ResolvedPresetContext => ({
|
||||||
|
target: { name: 'target', root: '/path/to/target', package: {} },
|
||||||
|
custom: {
|
||||||
|
preset: 'preset',
|
||||||
|
config: config ? { rollup: config } : {},
|
||||||
|
noSymlinks: [],
|
||||||
|
variable: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add plugins by importing from another config files', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: '@import config[plugins]',
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'config';`,
|
||||||
|
rollupExport: 'export default {"plugins": import0.plugins}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add a plugin by adding the plugin in the object form, using the supplied options', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: { '@apply newPlugin': { name: 'newPlugin' } },
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'newPlugin';`,
|
||||||
|
rollupExport:
|
||||||
|
'export default {"plugins": [import0(...[{"name": "newPlugin"}])]}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add a plugin by just the plugin name, using everything default', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: ['@apply newPlugin'],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'newPlugin';`,
|
||||||
|
rollupExport: 'export default {"plugins": [import0(...[])]}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add a plugin by adding the plugin in the array form, using everything default', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: [['@apply newPlugin']],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'newPlugin';`,
|
||||||
|
rollupExport: 'export default {"plugins": [import0(...[])]}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add a plugin by adding the plugin in the array form, using the supplied options', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: [['@apply newPlugin', { name: 'newPlugin' }]],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'newPlugin';`,
|
||||||
|
rollupExport:
|
||||||
|
'export default {"plugins": [import0(...[{"name": "newPlugin"}])]}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('remove a plugin by setting the plugin config as null', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: {
|
||||||
|
'@apply pluginWithOptions': null,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: ``,
|
||||||
|
rollupExport: 'export default {"plugins": []}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add a plugin from a named import', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: {
|
||||||
|
'@apply pluginWithOptions': null,
|
||||||
|
'@apply pluginWithoutOptions': null,
|
||||||
|
'@apply newPlugin[plugin]': { options: true },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'newPlugin';`,
|
||||||
|
rollupExport:
|
||||||
|
'export default {"plugins": [import0.plugin(...[{"options": true}])]}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generate default parameters if no further config is given', async () => {
|
||||||
|
expect(await getRollupParameter(generateContext())).toEqual({
|
||||||
|
rollupImport: ``,
|
||||||
|
rollupExport: 'export default {}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generate config with extra options other than plugins', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
cache: null,
|
||||||
|
extra: { options: true },
|
||||||
|
external: ['import1', 'import2'],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: ``,
|
||||||
|
rollupExport:
|
||||||
|
'export default {"cache": null, "extra": {"options": true}, "external": ["import1", "import2"]}',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generate extra import statements for imports within plugin options', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: {
|
||||||
|
'@apply pluginWithOptions': '@import another',
|
||||||
|
'@apply pluginWithoutOptions': '@import another',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'another';\nimport * as import1 from 'pluginWithOptions';\nimport * as import2 from 'pluginWithoutOptions';`,
|
||||||
|
rollupExport: `export default {"plugins": [import1(...[import0]), import2(...[import0])]}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: [
|
||||||
|
['@apply pluginWithOptions', '@import another'],
|
||||||
|
['@apply pluginWithoutOptions', '@import another'],
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'another';\nimport * as import1 from 'pluginWithOptions';\nimport * as import2 from 'pluginWithoutOptions';`,
|
||||||
|
rollupExport: `export default {"plugins": [import1(...[import0]), import2(...[import0])]}`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generate only one import statement per unique import', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: {
|
||||||
|
'@apply pluginWithOptions': null,
|
||||||
|
'@apply pluginWithoutOptions': null,
|
||||||
|
'@apply plugin0': '@import another[export0]',
|
||||||
|
'@apply plugin1': '@import another[export1]',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'another';\nimport * as import1 from 'plugin0';\nimport * as import2 from 'plugin1';`,
|
||||||
|
rollupExport: `export default {"plugins": [import1(...[import0.export0]), import2(...[import0.export1])]}`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('support nested plugin declaration', async () => {
|
||||||
|
expect(
|
||||||
|
await getRollupParameter(
|
||||||
|
generateContext({
|
||||||
|
plugins: {
|
||||||
|
'@apply pluginWithOptions': null,
|
||||||
|
'@apply pluginWithoutOptions': null,
|
||||||
|
'@apply plugin0': {
|
||||||
|
plugins: { another: '@import options[export0]' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
rollupImport: `import * as import0 from 'options';\nimport * as import1 from 'plugin0';`,
|
||||||
|
rollupExport: `export default {"plugins": [import1(...[{"plugins": [["another", import0.export0]]}])]}`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,3 @@
|
||||||
|
{rollupImport}
|
||||||
|
|
||||||
|
{rollupExport}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# replace the `prepare` template from presetter-preset
|
||||||
|
# so that the build procedure will not be triggered upon package installation
|
||||||
|
build: run-s clean build:rollup
|
||||||
|
build:rollup: cross-env NODE_ENV=production rollup --config rollup.config.ts --configPlugin rollup-plugin-ts
|
||||||
|
develop: run-s "build:rollup -- --watch {@}" --
|
Loading…
Reference in New Issue