fix(babel-plugin-extend-docs): support templates containing ${{
This commit is contained in:
parent
5d528fd795
commit
f2c63e858e
6 changed files with 36 additions and 236 deletions
|
|
@ -1,231 +1,3 @@
|
||||||
# babel-plugin-extend-docs
|
# Babel Plugin Extend Docs
|
||||||
|
|
||||||
A plugin which rewrites imports and templates according to a configuration.
|
[=> See Source <=](../../docs/docs/node-tools/babel-plugin-extend-docs/overview.md)
|
||||||
This enables the reuse of existing documentation from source packages while still using your extensions code.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm i -D babel-plugin-extend-docs
|
|
||||||
```
|
|
||||||
|
|
||||||
We want to only execute `babel-plugin-extend-docs` on the actual files we want to modify/extend.
|
|
||||||
We recommend using [babel overrides](https://babeljs.io/docs/en/options#overrides) for it.
|
|
||||||
|
|
||||||
👉 _babel.config.js_
|
|
||||||
|
|
||||||
```js
|
|
||||||
const extendDocsConfig = {
|
|
||||||
rootPath: process.cwd(), // or `path.resolve('./')` as plugin needs to know the rootPath of your project
|
|
||||||
changes: [
|
|
||||||
// possible changes as described below
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
// plugin will only be executed on files that match this pattern
|
|
||||||
test: ['./node_modules/source-library/demos/**/*.js'],
|
|
||||||
plugins: [['babel-plugin-extend-docs', extendDocsConfig]],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- Renames named imports and all it's usage
|
|
||||||
- Adjusts import paths
|
|
||||||
- Replace tags in template literals
|
|
||||||
|
|
||||||
## A Change
|
|
||||||
|
|
||||||
A change is what gets placed between in the extendDocsConfig within the `changes` array.
|
|
||||||
|
|
||||||
> automating the generation of changes is optional but encouraged
|
|
||||||
|
|
||||||
It has the following possibilities:
|
|
||||||
|
|
||||||
```js
|
|
||||||
changes: [
|
|
||||||
{
|
|
||||||
description: 'MyCounter', // not needed but can be added for easier reading of the config
|
|
||||||
variable: {
|
|
||||||
// see below
|
|
||||||
},
|
|
||||||
tag: {
|
|
||||||
// see below
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
### Paths
|
|
||||||
|
|
||||||
Both `variable` and `tag` are required to have a `paths` array which defines how to remap import paths.
|
|
||||||
As demos can use multiple ways to import all of them needs to be written down in the config.
|
|
||||||
|
|
||||||
```js
|
|
||||||
paths: [
|
|
||||||
{ from: './index.js', to: './my-extension/index.js' },
|
|
||||||
{ from: '../index.js', to: '../my-extension/index.js' },
|
|
||||||
{ from: './src/MyCounter.js', to: './my-extension/index.js' },
|
|
||||||
{ from: '../src/MyCounter.js', to: '../my-extension/index.js' },
|
|
||||||
],
|
|
||||||
```
|
|
||||||
|
|
||||||
## Replacement of tags
|
|
||||||
|
|
||||||
We have an existing demo code which we want to reuse.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { LitElement, html } from '@lion/core';
|
|
||||||
import './my-counter.js';
|
|
||||||
class MyApp extends LitElement {
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<h1>Example App</h1>
|
|
||||||
<my-counter></my-counter>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customElements.define('my-app', MyApp);
|
|
||||||
```
|
|
||||||
|
|
||||||
We created a "better" version of `<my-counter>` so we would like to use that in the demo.
|
|
||||||
Our extension is called `<my-extension>` and is available in `./my-extension/my-extension.js`.
|
|
||||||
|
|
||||||
Within `babel-plugin-extend-docs` we can define to replace the tag + it's import.
|
|
||||||
|
|
||||||
```js
|
|
||||||
tag: {
|
|
||||||
from: 'my-counter',
|
|
||||||
to: 'my-extension',
|
|
||||||
paths: [{ from: './my-counter.js', to: './my-extension/my-extension.js' }],
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Result of Replacement of tags
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { LitElement, html } from '@lion/core';
|
|
||||||
import './my-extension/my-extension.js';
|
|
||||||
class MyApp extends LitElement {
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<h1>Example App</h1>
|
|
||||||
<my-extension></my-extension>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customElements.define('my-app', MyApp);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Replacement of classes
|
|
||||||
|
|
||||||
We have an existing demo code which we want to reuse.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { LitElement, html } from '@lion/core';
|
|
||||||
import { MyCounter } from './src/MyCounter.js';
|
|
||||||
class TenCounter extends MyCounter {
|
|
||||||
inc() {
|
|
||||||
this.count += 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customElements.define('ten-counter', TenCounter);
|
|
||||||
class MyApp extends LitElement {
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<h1>Example App</h1>
|
|
||||||
<ten-counter></ten-counter>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customElements.define('my-app', MyApp);
|
|
||||||
```
|
|
||||||
|
|
||||||
We created a "better" version of `MyCounter` so we would like that `TenCounter` now extends it instead.
|
|
||||||
|
|
||||||
Within `babel-plugin-extend-docs` we can define to replace the class + it's import.
|
|
||||||
|
|
||||||
```js
|
|
||||||
variable: {
|
|
||||||
from: 'MyCounter',
|
|
||||||
to: 'MyExtension',
|
|
||||||
paths: [
|
|
||||||
{ from: './src/MyCounter.js', to: './my-extension/index.js' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
### Result of Replacement of classes
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { LitElement, html } from '@lion/core';
|
|
||||||
import { MyExtension } from './my-extension/index.js';
|
|
||||||
class TenCounter extends MyExtension {
|
|
||||||
inc() {
|
|
||||||
this.count += 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customElements.define('ten-counter', TenCounter);
|
|
||||||
class MyApp extends LitElement {
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<h1>Example App</h1>
|
|
||||||
<ten-counter></ten-counter>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customElements.define('my-app', MyApp);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Full Demo & Api Example
|
|
||||||
|
|
||||||
You can run the example locally via `npm run start` or look at its [source code](https://github.com/ing-bank/lion/tree/master/packages-node/babel-plugin-extend-docs/demo/).
|
|
||||||
_Note we are configuring babel via the [server.config.js](https://github.com/ing-bank/lion/tree/master/packages-node/babel-plugin-extend-docs/demo/server.config.js)_
|
|
||||||
|
|
||||||
👉 _babel.config.js_
|
|
||||||
|
|
||||||
```js
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const extendDocsConfig = {
|
|
||||||
rootPath: path.resolve('./demo'),
|
|
||||||
changes: [
|
|
||||||
{
|
|
||||||
name: 'MyCounter',
|
|
||||||
variable: {
|
|
||||||
from: 'MyCounter',
|
|
||||||
to: 'MyExtension',
|
|
||||||
paths: [
|
|
||||||
{ from: './index.js', to: './my-extension/index.js' },
|
|
||||||
{ from: './src/MyCounter.js', to: './my-extension/index.js' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
tag: {
|
|
||||||
from: 'my-counter',
|
|
||||||
to: 'my-extension',
|
|
||||||
paths: [{ from: './my-counter.js', to: './my-extension/my-extension.js' }],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
test: ['./node_modules/@lion/*/README.md', './node_modules/@lion/*/docs/**/*.md',
|
|
||||||
plugins: [['babel-plugin-docs-extend', extendDocsConfig]],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
```js script
|
|
||||||
export default {
|
|
||||||
title: 'Tools/BabelPluginExtendDocs',
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
|
||||||
3
packages-node/babel-plugin-extend-docs/docs/overview.md
Normal file
3
packages-node/babel-plugin-extend-docs/docs/overview.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Babel Plugin Extend Docs
|
||||||
|
|
||||||
|
[=> See Source <=](../../../docs/docs/node-tools/babel-plugin-extend-docs/overview.md)
|
||||||
|
|
@ -17,7 +17,8 @@
|
||||||
"test-node"
|
"test-node"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublishOnly": "../../scripts/npm-prepublish.js",
|
"publish-docs": "node ../../packages-node/publish-docs/src/cli.js --github-url https://github.com/ing-bank/lion/ --git-root-dir ../../",
|
||||||
|
"prepublishOnly": "npm run publish-docs",
|
||||||
"start": "es-dev-server -c demo/server.config.js --root-dir ../../",
|
"start": "es-dev-server -c demo/server.config.js --root-dir ../../",
|
||||||
"start:no-babel": "es-dev-server -c demo/server.no-babel.config.js --root-dir ../../",
|
"start:no-babel": "es-dev-server -c demo/server.no-babel.config.js --root-dir ../../",
|
||||||
"test": "npm run test:node",
|
"test": "npm run test:node",
|
||||||
|
|
@ -31,5 +32,8 @@
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"exports": "./index.js"
|
"exports": {
|
||||||
|
".": "./index.js",
|
||||||
|
"./docs/": "./docs/"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const { validateOptions } = require('./validateOptions.js');
|
||||||
function replaceTemplateElements({ path, opts }) {
|
function replaceTemplateElements({ path, opts }) {
|
||||||
const replaceTag = (value, from, to) =>
|
const replaceTag = (value, from, to) =>
|
||||||
value
|
value
|
||||||
.replace(new RegExp(`<${from}(?= |>)`, 'g'), `<${to}`) // positive lookahead for '>' or ' ' after the tagName
|
.replace(new RegExp(`<${from}(?=\\s|>)`, 'g'), `<${to}`) // positive lookahead for '>' or ' ' after the tagName
|
||||||
.replace(new RegExp(`/${from}>`, 'g'), `/${to}>`);
|
.replace(new RegExp(`/${from}>`, 'g'), `/${to}>`);
|
||||||
path.node.quasi.quasis.forEach(quasi => {
|
path.node.quasi.quasis.forEach(quasi => {
|
||||||
opts.changes.forEach(change => {
|
opts.changes.forEach(change => {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable no-template-curly-in-string */
|
||||||
const { expect } = require('chai');
|
const { expect } = require('chai');
|
||||||
const { executeBabel, baseConfig } = require('./helpers.js');
|
const { executeBabel, baseConfig } = require('./helpers.js');
|
||||||
|
|
||||||
|
|
@ -188,7 +189,7 @@ describe('babel-plugin-extend-docs', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('replaces `@lion` tag imports', () => {
|
it('replaces `@lion` tag imports', () => {
|
||||||
const code = `import '@lion/input/lion-input.js';`;
|
const code = `import '@lion/input/define';`;
|
||||||
const output = `import "../../../__element-definitions/wolf-input.js";`;
|
const output = `import "../../../__element-definitions/wolf-input.js";`;
|
||||||
expect(executeBabel(code, testConfig)).to.equal(output);
|
expect(executeBabel(code, testConfig)).to.equal(output);
|
||||||
});
|
});
|
||||||
|
|
@ -207,6 +208,26 @@ describe('babel-plugin-extend-docs', () => {
|
||||||
expect(executeBabel(code, testConfig)).to.equal(output);
|
expect(executeBabel(code, testConfig)).to.equal(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("replaces tags also if using ${{key: 'value'}}", () => {
|
||||||
|
const code = [
|
||||||
|
'export const forceLocale = () => html`',
|
||||||
|
' <lion-input',
|
||||||
|
" .formatOptions=${{ locale: 'nl-NL' }}",
|
||||||
|
' ></lion-input>',
|
||||||
|
'`;',
|
||||||
|
].join('\n');
|
||||||
|
const output = [
|
||||||
|
'export const forceLocale = () => html`',
|
||||||
|
' <wolf-input',
|
||||||
|
' .formatOptions=${{',
|
||||||
|
" locale: 'nl-NL'",
|
||||||
|
'}}',
|
||||||
|
' ></wolf-input>',
|
||||||
|
'`;',
|
||||||
|
].join('\n');
|
||||||
|
expect(executeBabel(code, testConfig)).to.equal(output);
|
||||||
|
});
|
||||||
|
|
||||||
it('will not touch content of tags', () => {
|
it('will not touch content of tags', () => {
|
||||||
const code = [
|
const code = [
|
||||||
'export const main = () => html`',
|
'export const main = () => html`',
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ const baseConfig = {
|
||||||
to: './__element-definitions/wolf-input.js',
|
to: './__element-definitions/wolf-input.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: '@lion/input/lion-input.js',
|
from: '@lion/input/define',
|
||||||
to: './__element-definitions/wolf-input.js',
|
to: './__element-definitions/wolf-input.js',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -75,7 +75,7 @@ const baseConfig = {
|
||||||
to: './__element-definitions/wolf-button.js',
|
to: './__element-definitions/wolf-button.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: '@lion/button/lion-button.js',
|
from: '@lion/button/define',
|
||||||
to: './__element-definitions/wolf-button.js',
|
to: './__element-definitions/wolf-button.js',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue