如何从终端生成React组件
react 循环生成组件
如何从终端生成React组件 (How to Generate React Components from your Terminal)
And speed up your workflow
并加快您的工作流程
Photo by Bernard Hermant on Unsplash 照片由Bernard Hermant在Unsplash上拍摄Adding a new component can be a cumbersome task, especially if you’re writing tests and using something like storybook. A file structure for a single component could potentially look like this:
添加新组件可能是一项繁琐的任务,尤其是在编写测试并使用故事书之类的东西时。 单个组件的文件结构可能看起来像这样:
You can save a lot of time by writing a node script that will take whatever component templates you need and generate these files, rather than writing them all by hand every time.
您可以编写节点脚本来节省大量时间,该脚本将采用所需的任何组件模板并生成这些文件,而不是每次都手动编写它们。
There are currently npm packages available that you can download and try out, but the added benefit of this approach is that you can tweak the component templates to fit you and your teams needs on a project by project basis.
当前可以下载并试用npm软件包,但是这种方法的另一个好处是,您可以根据项目的不同来调整组件模板以适合您和团队的需求。
你需要什么 (What You’ll Need)
- File template functions 文件模板功能
- A node script to create the files and populates the files 用于创建文件并填充文件的节点脚本
Logic in the script to update the
components/index.ts
file (optional)脚本中的逻辑更新
components/index.ts
文件(可选)- An npm script to run the node script (optional) 一个npm脚本来运行节点脚本(可选)
Let’s start by creating a directory in the root folder of our project to house the template functions and the logic.
让我们从在项目的根文件夹中创建一个目录开始,以容纳模板函数和逻辑。
take .generate_component
touch component_templates.js
touch index.js
组件模板 (Component Templates)
An example of the structure of a basic component that my team uses looks like this:
我的团队使用的基本组件的结构示例如下所示:
import React from 'react'; import './Navbar.scss'; export interface INavbarProps {} const Navbar = ({}: INavbarProps) => { return <div>Hello 👋, I am a Navbar component.</div>; }; export default Navbar;
In our
component_templates.jsfile, we can add a function to generate the component template like so.
在我们的
component_templates.js文件中,我们可以像这样添加一个函数来生成组件模板。
exports.component = name => `import React from 'react'; import './${name}.scss'; export interface I${name}Props {} const ${name} = ({}: ${name}Props) => { return <div>Hello 👋, I am a ${name} component.</div>; }; export default ${name}; `;
The function will receive the
nameargument when running the node script.
该函数将收到
name运行节点脚本时的参数。
Depending on what files you want to include your folder structure, you can add additional component templates. In my case, I want to add the following template functions:
根据要包括文件夹结构的文件,可以添加其他组件模板。 就我而言,我想添加以下模板函数:
component
零件
story
故事
test
测试
barrel
桶
The complete file for that folder structure would look like this:
该文件夹结构的完整文件如下所示:
// component.tsx exports.component = name => `import React from 'react'; import './${name}.scss'; export interface I${name}Props {} const ${name} = ({}: ${name}Props) => { return <div>Hello 👋, I am a ${name} component.</div>; }; export default ${name}; `; // component.stories.jsx exports.story = name => `import React from 'react'; import ${name} from './${name}.tsx'; export default { title: '${name}', component: ${name}, }; export const Default = () => <${name} />; `; // component.test.tsx exports.test = name => `import React from 'react'; import { render } from '@testing-library/react'; import ${name} from './${name}'; describe('${name} Component', () => { test('it should match the snapshot', () => { const { asFragment } = render(<${name} />); expect(asFragment()).toMatchSnapshot(); }); }); `; // index.ts exports.barrel = name => `import ${name} from './${name}'; export default ${name}; `;
节点脚本 (Node Script)
The tasks completed by the node script will be:
节点脚本完成的任务将是:
- Accept an argument (for the component name) from the terminal when running the script 运行脚本时从终端接受一个参数(用于组件名称)
- Create a Folder for the new component 为新组件创建一个文件夹
- Add desired files to the folder 将所需文件添加到文件夹
Read from the
components/index.ts
file and insert new component into it (optional)*从
components/index.ts
文件并将新组件插入其中(可选)*
* This is assuming that you use a barrel file to export all the components in your components folder . Here is an example of the barrel file that we use for reference:
*这是假设您使用桶文件导出Components文件夹中的所有组件。 这是我们用于参考的桶文件的示例:
import Carousel from './Carousel'; import GenreCard from './GenreCard'; import HeroBanner from './HeroBanner'; import Layout from './Layout'; import Navbar from './Navbar'; import NetworkCard from './NetworkCard'; import Poster from './Poster'; import Swimlane from './Swimlane'; export { Carousel, GenreCard, HeroBanner, Layout, Navbar, NetworkCard, Poster, Swimlane, };
If you don’t follow the pattern of including the newly generated component in
components/index.ts, then I would suggest removing that block of code in the below example following the comment that says “Optional”.
如果您不遵循在
components/index.ts中包括新生成的组件的模式,那么我建议在下面的示例中,在标有“ Optional”的注释之后删除该代码块。
const fs = require('fs'); const { component, story, test, barrel } = require('./component_templates.js'); // grab component name from terminal argument const [name] = process.argv.slice(2); if (!name) throw new Error('You must include a component name.'); const dir = `./src/components/${name}/`; // throw an error if the file already exists if (fs.existsSync(dir)) throw new Error('A component with that name already exists.'); // create the folder fs.mkdirSync(dir); function writeFileErrorHandler(err) { if (err) throw err; } // component.tsx fs.writeFile(`${dir}/${name}.tsx`, component(name), writeFileErrorHandler); // component.scss fs.writeFile(`${dir}/${name}.scss`, '', writeFileErrorHandler); // storybook.jsx fs.writeFile(`${dir}/${name}.stories.jsx`, story(name), writeFileErrorHandler); // test.tsx fs.writeFile(`${dir}/${name}.test.tsx`, test(name), writeFileErrorHandler); // index.tsx fs.writeFile(`${dir}/index.ts`, barrel(name), writeFileErrorHandler); /// Optional /// // insert new component into 'components/index.ts file fs.readFile('./src/components/index.ts', 'utf8', function(err, data) { if (err) throw err; // grab all components and combine them with new component const currentComponents = data.match(/(?<=import )(.*?)(?= from)/g); const newComponents = [name, ...currentComponents].sort(); // create the import and export statements const importStatements = newComponents .map(importName => `import ${importName} from './${importName}';\n`) .join(''); const exportStatements = `export {\n${newComponents .map(component => ` ${component},\n`) .join('')}};\n`; const fileContent = `${importStatements}\n${exportStatements}`; fs.writeFile(`./src/components/index.ts`, fileContent, callback); });
Now that the script and template functions in place, you can run the script by entering the following command in your terminal:
现在脚本和模板功能已经到位,您可以通过在终端中输入以下命令来运行脚本:
node ./generate_component ComponentName
Alternatively, if you don’t want to run the node script directly, you can write an npm script to run the command for you in your
package.jsonfile.
另外,如果您不想直接运行节点脚本,则可以在
package.json编写一个npm脚本来为您运行命令 文件。
Here’s an example of what that could look like:
这是一个看起来像的例子:
"scripts": {
"generate-component": "node .generate_component $1"
}
The
$1in the above script will be whatever component name you pass into the npm script when running it.
$1在上面的脚本中,将是您在运行npm脚本时传递给它的任何组件名称。
Now that you’ve written your npm script, you can run the following command in your terminal:
现在,您已经编写了npm脚本,您可以在终端中运行以下命令:
npm run generate-component ComponentName
If you executed everything correctly, a new folder should appear in the components folder and added to your
components/index.tsfile.
如果正确执行了所有操作,则新文件夹应该出现在components文件夹中,并将其添加到
components/index.ts文件中。
I hope that you can incorporate this pattern into your workflow and save yourself a ton of time!
希望您可以将此模式整合到您的工作流程中,并节省大量时间!
翻译自: https://levelup.gitconnected.com/how-to-generate-react-components-from-your-terminal-a27741a5b862
react 循环生成组件
- react---react router4.0路由中如何异步动态加载组件,webpack使用require.ensure()生成异步chunk
- Android中使用react-native框架中的View组件如何使其中的文本换行
- react dva如何获取被form包裹的子组件函数
- react 兄弟组件如何调用对方的方法示例
- react组件之间如何交流
- 关于React组件之间如何优雅地传值的探讨
- react组件如何通信
- 在react中如何使用tab组件-小白系列 es6
- 如何写出漂亮的 React 组件
- react开发中如何使用require.ensure加载es6风格的组件
- 如何简单实现一个react组件
- 如何让.Net控件在设计时InitializeComponent()中不生成相关代码(C#组件开发)
- Macbook 终端Terminal下如何查看文件生成日期和修改日期
- vue 和react中子组件分别如何向父组件传值
- React简单解释如何封装组件的demo
- React如何将组件渲染到指定DOM节点详解
- GStreamer使用playbin,如何给动态生成的source组件设置属性?
- 如何创建一个依赖Android AAR文件的React Native组件
- 详解如何在React组件“外”使用父组件的Props
- React 组件之间如何交流