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

refactor(remark-plugin-npm2yarn): migrate package to TS #5931

Merged
merged 9 commits into from
Nov 12, 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
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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's annoying me due to not working with Babel, isn't there a better way to handle that interop problem?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is:

// To trick Babel & tsc
export default plugin;
// To actual do the export
module.exports = plugin;

This will be transpiled as:

exports.default = plugin;
module.exports = plugin;

Because exports is an alias for module.exports, the last line decouples the exports reference from module.exports and makes the second last line useless. However this makes everyone happy

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