Skip to content

Commit

Permalink
feat: add comments to banner using formatter option (#39)
Browse files Browse the repository at this point in the history
* test-cli with formatter option
* use banner in banner2 project ;)
* update tests, readme, changelog and .d.ts
* docBlockAndGap & docBlock formatter optiond
  • Loading branch information
stropho authored May 11, 2024
1 parent bc7c6d3 commit 0578505
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 12 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/bump-push-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ jobs:
registry-url: https://registry.npmjs.org/
node-version: '20'
- run: npm ci
- run: npm run build

- name: Git configuration
run: |
git config --global user.email "github-action@users.noreply.github.com"
git config --global user.name "GitHub Actions"
- run: npm version ${{ env.VERSION_BUMP_TYPE }}
# build after bump to reflect the version number
- run: npm run build
- name: Push bumped files
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- `formatter` option with value `docBlock` and `docBlockAndGap` to automatically wrap banner string in `/** */` along with prepending every line with `*`

## [1.2.3] - 2024-03-28

### Added
Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default {
- `banner2` supports adding different banner to different chunks based on `ChunkInfo` (for more info see https://rollupjs.org/ )
- `banner2` does not support file path option that loads a file content and uses that as a banner. It should be easy enough to call `fs.readFileSync` yourself
- `banner2` does not support injecting values from `package.json` to banner via `<%= pkg.author %>` etc.
- `banner2` does not add JS comments as a wrapper to every banner
- `banner2` does not add JS comments as a wrapper to every banner automatically. You can explicitly use the option `{formatter: 'docBlock}`.

The missing features could be added if someone actually needs them.

Expand All @@ -53,18 +53,27 @@ The missing features could be added if someone actually needs them.
banner2(resolveBanner, options)
```

See the [typescript definition](index.d.ts) for more info.

### resolveBanner

The `resolveBanner` function returns a banner as

- `string`
- stringifiable object, i.e. having `toString` method, such as `Buffer`
- any falsy value for an empty banner
- a `Promise` resolving any of the values mentioned above

For more details see the [typescript definition](index.d.ts)
### options

- **sourcemap** - enable/disable sourcemap. `true` by default
- **formatter** - transform banner. No transform by default. Possible options:
- `'docBlock'` - i.e. `/**` & `*/\n`
- `'docBlockAndGap'` - i.e. `/**` & `*/\n\n`

## Contributing

- new PRs accepted :-)
- always cover your changes by tests
- always mention your changes in the [CHANGELOG.md](CHANGELOG.md)
- always update [typescript definition](index.d.ts) file when relevant to your changes
- always update [typescript definition](index.d.ts) file when relevant to your changes, and possibly the docs.
16 changes: 16 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,24 @@ type ResolveBanner = (
options: rollup.OutputOptions,
) => string | Falsy | Stringifiable | Promise<string | Falsy | Stringifiable>

type FormatterOption = 'docBlock' | 'docBlockAndGap'
type Options = {
/**
* Set `false` to explicitly disable sourcemaps.
* `true` by default
*/
sourcemap?: boolean
/**
* Transform the resolved banner string
*
* @example
* banner2(() => 'banner', { formatter: 'docBlock' })
* // outputs multiline comment similar to:
* /**
* * banner
* * /
*/
formatter?: FormatterOption
}

declare function banner2(
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"test:unit": "jest",
"test:tdd": "npm run test:unit -- --no-cache --watch",
"test": "npm run test:lint && npm run test:unit && kacl lint",
"test-cli": "rollup -i test/fixture/input-multi-first.js --sourcemap inline -f es -p './test/cli/add-one-line-banner-plugin.cjs.js'",
"test-cli": "rollup -c=test/cli/rollup.config.js --sourcemap inline",
"prepare": "husky install && npm run build",
"preversion": "kacl prerelease",
"prettier": "prettier '**/*.{ts,tsx,js,jsx,cjs,mjs,json,md,html,yml,yaml}' --write",
Expand Down
7 changes: 5 additions & 2 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import pkg from './package.json'
import banner2 from './src/index'

export default [
{
input: 'src/index.js',
external: ['fs', 'path', ...Object.keys(pkg.dependencies || {})],
external: Object.keys(pkg.dependencies || {}),
output: [
{ file: pkg.main, format: 'cjs' },
{ file: pkg.module, format: 'esm' },
],
plugins: [],
plugins: [
banner2(() => `${pkg.name}@${pkg.version}`, { formatter: 'docBlock' }),
],
},
]
14 changes: 14 additions & 0 deletions src/formatters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const identity = (str) => str

export const docBlock = (str) => {
const lines = str.split('\n')
const wrapped = ['/**', ...lines.map((l) => ` * ${l}`), ' */\n'].join('\n')

return wrapped
}

export const docBlockAndGap = (str) => {
return `${docBlock(str)}\n`
}

export const formatters = { docBlock, docBlockAndGap, identity }
10 changes: 8 additions & 2 deletions src/plugin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import MagicString from 'magic-string'
import { formatters } from './formatters'

const defaultOptions = {
sourcemap: true,
formatter: 'identity',
}
export default function banner2(resolveBanner, userOptions) {
const opts = { ...defaultOptions, ...(userOptions || {}) }
Expand All @@ -11,10 +13,14 @@ export default function banner2(resolveBanner, userOptions) {
async renderChunk(code, chunk, options) {
const banner = await resolveBanner(chunk, options)
if (!banner) return { code, map: null }
if (!opts.sourcemap) return banner + code

const formatterByOption = formatters[opts.formatter]
const formattedBanner = formatterByOption(String(banner))

if (!opts.sourcemap) return formattedBanner + code

const magicString = new MagicString(code)
magicString.prepend(String(banner))
magicString.prepend(formattedBanner)

return {
code: magicString.toString(),
Expand Down
33 changes: 33 additions & 0 deletions test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,43 @@ export { second };
"
`;

exports[`output single entry point banner as Buffer with formatter and disabled sourcemap 1`] = `
"/**
* banner
*/
const foo = 'foo';
export { foo };
"
`;

exports[`output single entry point static banner 1`] = `
"// banner
const foo = 'foo';
export { foo };
"
`;

exports[`output single entry point static banner with formatter docBlock 1`] = `
"/**
* banner
*
*/
const foo = 'foo';
export { foo };
"
`;

exports[`output single entry point static banner with formatter docBlockAndGap 1`] = `
"/**
* banner
*
*/
const foo = 'foo';
export { foo };
"
`;
3 changes: 0 additions & 3 deletions test/cli/add-one-line-banner-plugin.cjs.js

This file was deleted.

13 changes: 13 additions & 0 deletions test/cli/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import banner2 from '../../dist/rollup-plugin-banner2.es'

const input = 'test/fixture/input-multi-first.js'
export default [
{
input,
plugins: [banner2(() => '// banner\n')],
},
{
input,
plugins: [banner2(() => 'banner', { formatter: 'docBlock' })],
},
]
65 changes: 65 additions & 0 deletions test/formatters.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { docBlock, docBlockAndGap } from '../src/formatters'

describe('formatters', () => {
describe('docBlock', () => {
it('wraps a single line', () => {
const input = 'this is a banner'

const actualResult = docBlock(input)

expect(`\n${actualResult}`).toMatchInlineSnapshot(`
"
/**
* this is a banner
*/
"
`)
})
it('wraps multiple lines', () => {
const input = 'this is a banner\nwith\nmore\nlines\n'

const actualResult = docBlock(input)

expect(`\n${actualResult}`).toMatchInlineSnapshot(`
"
/**
* this is a banner
* with
* more
* lines
*
*/
"
`)
})
it('does not correctly wrap comments', () => {
const input = '/* comments */'

const actualResult = docBlock(input)

expect(`\n${actualResult}`).toMatchInlineSnapshot(`
"
/**
* /* comments */
*/
"
`)
})
})
describe('docBlockAndGap', () => {
it('wraps a single line', () => {
const input = 'this is a banner'

const actualResult = docBlockAndGap(input)

expect(`\n${actualResult}`).toMatchInlineSnapshot(`
"
/**
* this is a banner
*/
"
`)
})
})
})
51 changes: 51 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('warnings', () => {

expect(output.length).toBe(1)
expect(onwarnSpy).toHaveBeenCalledTimes(1)
expect(output[0].map.mappings).toBeFalsy()
})

test('banner as stringifiable object', async () => {
Expand Down Expand Up @@ -82,6 +83,56 @@ describe('output', () => {
const bundle = await rollup(inputOptions)
const { output } = await bundle.generate(outputOptions)

expect(output.length).toBe(1)
expect(output[0].code).toMatchSnapshot()
})
test('static banner with formatter docBlock', async () => {
const inputOptions = {
input: path.resolve(__dirname, './fixture/input-single.js'),
plugins: [banner2(() => 'banner\n', { formatter: 'docBlock' })],
}
const outputOptions = {
...OUTPUT_OPTIONS,
}

const bundle = await rollup(inputOptions)
const { output } = await bundle.generate(outputOptions)

expect(output.length).toBe(1)
expect(output[0].code).toMatchSnapshot()
})
test('static banner with formatter docBlockAndGap', async () => {
const inputOptions = {
input: path.resolve(__dirname, './fixture/input-single.js'),
plugins: [banner2(() => 'banner\n', { formatter: 'docBlockAndGap' })],
}
const outputOptions = {
...OUTPUT_OPTIONS,
}

const bundle = await rollup(inputOptions)
const { output } = await bundle.generate(outputOptions)

expect(output.length).toBe(1)
expect(output[0].code).toMatchSnapshot()
})
test('banner as Buffer with formatter and disabled sourcemap', async () => {
const inputOptions = {
input: path.resolve(__dirname, './fixture/input-single.js'),
plugins: [
banner2(() => Buffer.from('banner'), {
formatter: 'docBlock',
sourcemap: false,
}),
],
}
const outputOptions = {
...OUTPUT_OPTIONS,
}

const bundle = await rollup(inputOptions)
const { output } = await bundle.generate(outputOptions)

expect(output.length).toBe(1)
expect(output[0].code).toMatchSnapshot()
})
Expand Down

0 comments on commit 0578505

Please sign in to comment.