Skip to content

Commit

Permalink
refactor(remark-plugin-npm2yarn): migrate package to TS (#5931)
Browse files Browse the repository at this point in the history
* refactor(remark-plugin-npm2yarn): migrate package to TS

* fix(remark-plugin-npm2yarn): type as unified Plugin

* refactor(remark-plugin-npm2yarn): standardize code style with remark plugins in mdx-loader

* Use unist-util-visit

* Use export =

* Remove unneeded includes option

* Fix tests

* Migrate test to TS

* Make output look better

Co-authored-by: Josh-Cena <[email protected]>
  • Loading branch information
duanwilliam and Josh-Cena authored Nov 12, 2021
1 parent c914da3 commit 1e725a1
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 116 deletions.
10 changes: 8 additions & 2 deletions packages/docusaurus-remark-plugin-npm2yarn/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@
"name": "@docusaurus/remark-plugin-npm2yarn",
"version": "2.0.0-beta.9",
"description": "Remark plugin for converting npm commands to Yarn commands as tabs.",
"main": "src/index.js",
"main": "lib/index.js",
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "tsc",
"watch": "tsc --watch"
},
"repository": {
"type": "git",
"url": "https://github.com/facebook/docusaurus.git",
"directory": "packages/docusaurus-remark-plugin-npm2yarn"
},
"license": "MIT",
"dependencies": {
"npm-to-yarn": "^1.0.1"
"npm-to-yarn": "^1.0.1",
"unist-util-visit": "^2.0.2"
},
"devDependencies": {
"@types/mdast": "^3.0.10",
"remark": "^12.0.0",
"remark-mdx": "^1.6.21",
"to-vfile": "^6.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,15 @@ exports[`npm2yarn plugin test: already imported tabs components above are not re
import TabItem from '@theme/TabItem';
<Tabs defaultValue=\\"npm\\" values={[
{ label: 'npm', value: 'npm', },
{ label: 'Yarn', value: 'yarn', },
]}
>
<Tabs>
<TabItem value=\\"npm\\">
\`\`\`bash
$ npm install --global docusaurus
\`\`\`
</TabItem>
<TabItem value=\\"yarn\\">
<TabItem value=\\"yarn\\" label=\\"Yarn\\">
\`\`\`bash
$ yarn add --global docusaurus
Expand All @@ -29,19 +25,15 @@ import TabItem from '@theme/TabItem';
`;
exports[`npm2yarn plugin test: already imported tabs components below are not re-imported 1`] = `
"<Tabs defaultValue=\\"npm\\" values={[
{ label: 'npm', value: 'npm', },
{ label: 'Yarn', value: 'yarn', },
]}
>
"<Tabs>
<TabItem value=\\"npm\\">
\`\`\`bash
$ npm install --global docusaurus
\`\`\`
</TabItem>
<TabItem value=\\"yarn\\">
<TabItem value=\\"yarn\\" label=\\"Yarn\\">
\`\`\`bash
$ yarn add --global docusaurus
Expand All @@ -60,19 +52,15 @@ exports[`npm2yarn plugin test: installation file 1`] = `
"import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs defaultValue=\\"npm\\" values={[
{ label: 'npm', value: 'npm', },
{ label: 'Yarn', value: 'yarn', },
]}
>
<Tabs>
<TabItem value=\\"npm\\">
\`\`\`bash
$ npm install --global docusaurus
\`\`\`
</TabItem>
<TabItem value=\\"yarn\\">
<TabItem value=\\"yarn\\" label=\\"Yarn\\">
\`\`\`bash
$ yarn add --global docusaurus
Expand Down Expand Up @@ -106,19 +94,15 @@ import TabItem from '@theme/TabItem';
A plugin is usually a npm package, so you install them like other npm packages using npm.
<Tabs defaultValue=\\"npm\\" values={[
{ label: 'npm', value: 'npm', },
{ label: 'Yarn', value: 'yarn', },
]}
>
<Tabs>
<TabItem value=\\"npm\\">
\`\`\`bash
npm install --save docusaurus-plugin-name
\`\`\`
</TabItem>
<TabItem value=\\"yarn\\">
<TabItem value=\\"yarn\\" label=\\"Yarn\\">
\`\`\`bash
yarn add docusaurus-plugin-name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@
*/

import remark from 'remark';
import npm2yarn from '../index';
// import from the transpiled lib because Babel can't transpile `export =` syntax
// TODO change to `../index` after migrating to ESM
import npm2yarn from '../../lib/index';
import vfile from 'to-vfile';
import {join, relative} from 'path';
import mdx from 'remark-mdx';

const staticDir = `./${relative(process.cwd(), join(__dirname, 'fixtures'))}`;

const processFixture = async (name, options) => {
const processFixture = async (
name: string,
options: {sync?: boolean; staticDir: string},
) => {
const path = join(__dirname, 'fixtures', `${name}.md`);
const file = await vfile.read(path);
const result = await remark()
Expand Down
87 changes: 0 additions & 87 deletions packages/docusaurus-remark-plugin-npm2yarn/src/index.js

This file was deleted.

95 changes: 95 additions & 0 deletions packages/docusaurus-remark-plugin-npm2yarn/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import type {Code, Content, Literal} from 'mdast';
import type {Plugin, Transformer} from 'unified';
import type {Node, Parent} from 'unist';
import visit from 'unist-util-visit';
import npmToYarn from 'npm-to-yarn';

interface PluginOptions {
sync?: boolean;
}

// E.g. global install: 'npm i' -> 'yarn'
const convertNpmToYarn = (npmCode: string) => npmToYarn(npmCode, 'yarn');

const transformNode = (node: Code, isSync: boolean) => {
const groupIdProp = isSync ? ' groupId="npm2yarn"' : '';
const npmCode = node.value;
const yarnCode = convertNpmToYarn(node.value);
return [
{
type: 'jsx',
value: `<Tabs${groupIdProp}>\n<TabItem value="npm">`,
},
{
type: node.type,
lang: node.lang,
value: npmCode,
},
{
type: 'jsx',
value: '</TabItem>\n<TabItem value="yarn" label="Yarn">',
},
{
type: node.type,
lang: node.lang,
value: yarnCode,
},
{
type: 'jsx',
value: '</TabItem>\n</Tabs>',
},
] as Content[];
};

const isImport = (node: Node): node is Literal => node.type === 'import';
const isParent = (node: Node): node is Parent =>
Array.isArray((node as Parent).children);
const matchNode = (node: Node): node is Code =>
node.type === 'code' && (node as Code).meta === 'npm2yarn';
const nodeForImport: Literal = {
type: 'import',
value:
"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';",
};

const plugin: Plugin<[PluginOptions?]> = (options = {}) => {
const {sync = false} = options;
let transformed = false;
let alreadyImported = false;
const transformer: Transformer = (root) => {
visit(root, (node: Node) => {
if (isImport(node) && node.value.includes('@theme/Tabs')) {
alreadyImported = true;
}
if (isParent(node)) {
let index = 0;
while (index < node.children.length) {
const child = node.children[index];
if (matchNode(child)) {
const result = transformNode(child, sync);
node.children.splice(index, 1, ...result);
index += result.length;
transformed = true;
} else {
index += 1;
}
}
}
});
if (transformed && !alreadyImported) {
(root as Parent).children.unshift(nodeForImport);
}
};
return transformer;
};

// To continue supporting `require('npm2yarn')` without the `.default` ㄟ(▔,▔)ㄏ
// TODO change to export default after migrating to ESM
export = plugin;
9 changes: 9 additions & 0 deletions packages/docusaurus-remark-plugin-npm2yarn/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./lib/.tsbuildinfo",
"rootDir": "src",
"outDir": "lib"
}
}
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4262,7 +4262,7 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.174.tgz#b4b06b6eced9850eed6b6a8f1abdd0f5192803c1"
integrity sha512-KMBLT6+g9qrGXpDt7ohjWPUD34WA/jasrtjTEHStF0NPdEwJ1N9SZ+4GaMVDeuk/y0+X5j9xFm6mNiXS7UoaLQ==

"@types/mdast@^3.0.0", "@types/mdast@^3.0.7":
"@types/mdast@^3.0.0", "@types/mdast@^3.0.10", "@types/mdast@^3.0.7":
version "3.0.10"
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==
Expand Down

0 comments on commit 1e725a1

Please sign in to comment.