文件魔术数字

Before we begin: This article uses JavaScript / Node.js example code, but you can port these concepts to any language using the right tools.

开始之前:本文使用JavaScript / Node.js示例代码,但是您可以使用正确的工具将这些概念移植到任何语言。

精彩的介绍 (An exciting intro)

Do you ever find yourself creating the same files over and over again in your projects?

您是否发现自己在项目中一遍又一遍地创建相同的文件?

I do, too.

我也做。

我的手指受伤了! (My fingers hurt!)

I’m not surprised. You’re taking work from the robots.

我不惊讶。 您正在从机器人那里接管工作。

Creating the same files repeatedly is boring and unnecessary.

重复创建相同的文件很无聊,也没有必要。

TLDR? 我知道了-这是一个演示 (TLDR? I got you — Here’s a demo)

给我看代码 (Show me the code)

I respect your sense of urgency — I’ll cut to the chase.

我尊重您的紧迫感-我会追逐。

代码 (The Code)

We want to automate file creation — that’s why you all showed up today. First, we need to identify the files we want to create.

我们希望自动化文件创建-这就是今天所有人出现的原因。 首先,我们需要确定我们要创建的文件。

I’ve been creating a lot of React components lately, so my setup revolves around that — but you can tweak this for literally anything.

最近,我一直在创建很多React组件,因此我的设置围绕着这一点进行-但您实际上可以对其进行调整。

I’ve split this into four steps. Just telling you now so you can manage your expectations. If you can’t handle anything longer than three steps, then we’re in trouble...

我将其分为四个步骤。 现在就告诉您,以便您可以管理自己的期望。 如果您不能完成超过三步的操作,那么我们就麻烦了...

步骤1:模板 (Step 1: Templates)

Set them up once and profit.

设置一次即可获利。

We need templates. I used Template Literals, but do it in whatever way makes sense to you — be creative.

我们需要模板。 我使用了Template Literals ,但是以您认为有意义的任何方式进行-发挥创意。

These are the files I’m creating every time I make a React component:

这些是我每次制作React组件时要创建的文件:

  1. index.jsx

    index.jsx

  2. {Component}.test.js

    {Component} .test.js

  3. {Component}.sass

    {Component} .sass

Note: {Component} implies string interpolation.

注意: {Component}表示字符串插值 。

I’m testing with Jest, and using the create-react-app boilerplate. I know a lot of people prefer CSS-in-JS these days — but hey. Let me know in the comments what you’re into.

我正在使用Jest进行测试,并使用create-react-app样板。 我知道现在有很多人喜欢CSS-in-JS-但是,嘿。 在评论中让我知道您的兴趣。

Anyway — Here we go:

无论如何-我们开始:

const templates = {index: name => `// @flow
import React from 'react';
import './${name}.css';
// TODO: write rest of ${name} component
const ${name} = () => (<div className="${name.toLowerCase()}"><span>rest of component</span></div>
);
export default ${name};`,test: name => `// TODO: TDD
import { shallow, render } from 'enzyme';
import renderer from 'react-test-renderer';
import React from 'react';
import ${name} from '.';
const component = <${name} />;
describe('The ${name} component', () => {it('renders correctly', () => {const wrapper = render(component);expect(wrapper.hasClass('${name.toLowerCase()}')).toBeTruthy();const tree = renderer.create(component).toJSON();expect(tree).toMatchSnapshot();});
});`,sass: name => `.${name.toLowerCase()}background: initial`,
};

That’s the messiest piece of code you’ll see here — pinky promise.

这是您在这里看到的最乱的代码-小指承诺。

So, we have an object with three properties: index, test, and sass. Each hosts a function which takes a name and returns a template with that name interpolated. Seems legit.

因此,我们有一个具有三个属性的对象:索引,测试和sass。 每个托管一个函数,该函数采用一个名称,并返回一个插有该名称的模板。 似乎是合法的。

步骤2:让我们做一些功能! (Step 2: Let’s make some functions!)

We’re using the fs module packaged with Node. It’s fab. It does many things.

我们正在使用Node附带的fs模块 。 是晶圆厂。 它做很多事情。

We’re going to use some arrow functions and a little functional programming. Don’t be scared — just go with it.

我们将使用一些箭头功能和一些功能编程 。 不要害怕-随它去吧。

The double arrow function syntax is called currying. It’s okay if it looks weird. I was freaked out when I first saw it, but it allows for super cool stuff. In fact, here’s a quick demo:

双箭头函数的语法称为currying 。 看起来很奇怪也可以。 当我第一次看到它时,我感到非常震惊,但是它可以提供超酷的东西 。 实际上,这是一个快速演示:

const fs = require('fs');const fileExists = path => file => fs.existsSync(`${path}/${file}`);const fileExistsInSrc = fileExists('/src'); // file => fs.existsSync(`${path}/${file}`)fileExistsInSrc('index.js') // true || false

So that’s currying with partial application — it’s also a closure.

因此,使用部分应用程序很麻烦 -这也是一个闭包 。

Sidebar: Hopefully nobody calls me out here on some technicality, but please do harass me in the comments if you feel the need.

补充工具栏 :希望没人在这里给我一些技术性的要求,但是如果您有需要,请在评论中骚扰我。

Let’s carry on:

让我们继续:

const fs = require('fs');const fileExists = path => file => fs.existsSync(`${path}/${file}`);const writeToPath = path => (file, content) => {const filePath = `${path}/${file}`;fs.writeFile(filePath, content, err => {if (err) throw err;console.log("Created file: ", filePath);return true;});
};

First we require fs. We need it in our life.

首先,我们需要fs 。 我们一生中都需要它。

Then we declare fileExists as a function expression.

然后,我们将fileExists声明为函数表达式 。

Finally we have another function expression called writeToPath. It takes the path and returns another function which accepts a file string and the content of that file. It then writes the file or throws an error (worst case scenario).

最后,我们还有另一个函数表达式称为writeToPath。 它采用路径并返回另一个函数,该函数接受文件字符串和该文件内容 。 然后,它将写入文件或引发错误(最坏的情况)。

You get it right? We’re creating some files.

你说对了吗? 我们正在创建一些文件。

步骤3:认识Chokidar (Step 3: Meet Chokidar)

Fun fact: It’s a Hindi word.

有趣的事实:这是北印度语单词 。

Chowkidar — (India) watchman, caretaker, gatekeeper; one who inhabits a “chowki”, police station or guard house.

乔基达尔 -( 印度 )值班员,看守人,看门人; 居住在“ chowki”,警察局或警卫室的人。

We’re talking about the npm package though. It’s based on our new friend fs and you could use it for so many delightful things.

我们正在谈论npm软件包 。 它基于我们的新朋友fs ,您可以将其用于许多令人愉悦的事情。

It watches our files for us like a hawk.

它像鹰一样为我们监视文件。

Well not exactly like a hawk.

嗯,不完全像鹰。

It is not a bird.

它不是鸟。

Like at all.

一样。

Anyway, here’s the code…

无论如何,这是代码...

const chokidar = require("chokidar");const watcher = chokidar.watch("src/components/**", { ignored: /node_modules/ }).on("addDir", (path, event) => {const name = path.replace(/.*\/components\//, "");const goodToGo = /^[^\/_]*$/.test(name);if (goodToGo) createFiles(path, name);});

First we require it.

首先,我们需要它。

Next we define what we want to watch. I’m watching the src/components directory, but you can watch any set of paths. You can even pass an array of paths. If you don’t recognize the ** part in src/components/** — it’s called a glob pattern.

接下来,我们定义我们要观看的内容。 我正在看src / components目录,但是您可以看任何一组路径。 您甚至可以传递一系列路径 。 如果您无法识别src / components / **中**部分,则称为glob模式 。

After that, we define what events we want to listen for. I’m only listening for adding a directory with .on(“addDir”) but you can listen for other events too.

在那之后,我们定义我们想听的事件。 我只是在监听添加带有.on(“ addDir”)的目录,但是您也可以监听其他事件 。

Next let’s extract the name of the component by replacing anything before the component name:

接下来,通过替换组件名称之前的任何内容来提取组件的名称:

src/components/Header/components/Title

becomes

变成

Title

Finally we will check that the component name passes this regex:

最后,我们将检查组件名称是否通过此正则表达式:

/^[^\/_]*$/

So as long as it doesn’t have a forward slash or underscore — it’s good to go. This avoids polluting __tests__ folders or nested/directories by mistake.

因此,只要它没有正斜杠或下划线-那就很好了。 这样可以避免错误地污染__tests__文件夹或嵌套/目录。

步骤4:是时候制作一些文件了! (Step 4: Time to make some files!)

You reached the last step. Congratulations! It’s been pretty great.

您已到达最后一步。 恭喜你! 真是太好了。

This next function is aptly named createFiles.

下一个函数恰当地命名为createFiles

It’s a bit messy — it could be refactored.

有点混乱-可以重构。

I apologize in advance if the code below offends you.

如果以下代码冒犯了您,我深表歉意。

Let’s dig in:

让我们深入探讨:

function createFiles(path, name) {const files = {index: "index.jsx",test: `${name}.test.js`,sass: `${name}.sass`};if (name !== "components") {const writeFile = writeToPath(path);const toFileMissingBool = file => !fileExists(path)(file);const checkAllMissing = (acc, cur) => acc && cur;const noneExist = Object.values(files).map(toFileMissingBool).reduce(checkAllMissing);if (noneExist) {console.log(`Detected new component: ${name}, ${path}`);Object.entries(files).forEach(([type, fileName]) => {writeFile(fileName, templates[type](name));});}}
}

So at the top, we declare the files object — it’s a list of file name strings which we’re injecting the name parameter into. You might have noticed that it has the same keys as the templates object. That’s important.

因此,在顶部,我们声明了files对象-这是文件名字符串的列表,我们将name参数注入其中。 您可能已经注意到,它具有与模板对象相同的键。 那很重要

The if statement is very specific to my setup. I don’t want to create my files if the new folder is called components. I am only creating components within a components sub-folder.

if语句非常特定于我的设置。 如果新文件夹称为components,我不想创建文件。 我仅组件子文件夹中创建组件。

  • writeFile is our function writeToPath partially applied. It’s a function that creates a file in the given path when called with a filename and some content.

    writeFile是部分应用的函数writeToPath 。 当使用文件名和某些内容调用该函数时,它将在给定路径中创建文件。

  • toFileMissingBool takes a file name and returns true if that file doesn’t exist in the given path. I know the function names are weird, but I promise it kind of makes more sense in a few lines.

    toFileMissingBool采用文件名,如果给定路径中不存在该文件,则返回true。 我知道函数名称很奇怪,但是我保证在几行中它会更有意义。

  • checkAllMissing is a function that we are going to pass to reduce. It takes two booleans and returns true if both are true. This is boolean algebra. We are also using the reduce method of Array. Don’t be afraid of reduce. It’s super cool and really useful in this kind of situation.

    checkAllMissing是我们将要减少的函数。 它需要两个布尔值,如果两个都为true,则返回true。 这是布尔代数 。 我们还使用Arrayreduce方法。 不要害怕减少。 在这种情况下,它非常酷,而且非常有用。

Let’s talk about the variable noneExist. If it’s true, then none of the files we want to create exist in the new folder. The idea is that you don’t mess with a folder just because it doesn’t have a test file or a sass file. Maybe that folder doesn’t need one.

让我们谈谈变量noneExist 。 如果为true,则新文件夹中不存在我们要创建的文件。 这个想法是,您不会因为没有测试文件或sass文件而惹恼它。 也许那个文件夹不需要一个。

const noneExist = Object.values(files).map(toFileMissingBool)      .reduce(checkAllMissing);

That’s why I created those strangely named functions above.

这就是为什么我在上面创建了那些名字奇怪的函数的原因。

We map the values in files to a boolean which represents if that file is missing or not. Then we take that array of booleans and reduce them to a single boolean value which represents whether all the files exist or not.

我们 文件中的值映射到一个布尔值,该布尔值表示该文件是否丢失。 然后,我们采用该布尔数组并将其减小为一个布尔值,该布尔值表示所有文件是否存在。

So if they’re all true, then noneExist is also true. But if even one is false, then noneExist will be false.

因此,如果它们全部为真,noneExist也为真。 但是,即使一个为假, noneExist也将为

I hope you got all that. It’s a bit of a mouthful.

我希望你能得到所有。 有点大嘴巴 。

Last bit of code:

最后一点代码:

Object.entries(files).forEach(([type, fileName]) => {writeFile(fileName, templates[type](name));
});

We take the key (type) and value (fileName) and write a file in the given path with the content from the relevant template.

我们使用键( 类型)和值(fileName),并使用相关模板中的内容在给定路径中写入文件。

鳍。 (Fin.)

That picture of a sea turtle represents how free you must be feeling now you have automated everything.

这张海龟的图片代表着现在您已经自动化了一切,您必须有多自由。

If you want the whole code for auto-creating react components, it’s here.

如果您需要用于自动创建React组件的全部代码,请在此处 。

Let me know what you thought — Keep in touch.

让我知道您的想法-保持联系。

Tell me if you find any errors.

告诉我您是否发现任何错误。

Follow me on Twitter, Medium or Github.

在Twitter , Medium或Github上关注我。

翻译自: https://www.freecodecamp.org/news/how-to-create-files-automatically-and-save-time-with-magic-scaffolding-8dcd1b31483/

文件魔术数字

文件魔术数字_如何使用魔术脚手架自动创建文件并节省时间相关推荐

  1. php 自动创建文件,php:自动创建多级文件夹

    /** * 函数说明 * is_dir:判断给定文件名是否是一个目录,如果是返回ture,如果不是返回false * dirname:返回路径中的目录部分,本函数返回去掉文件名后的目录名.比如$pat ...

  2. File类和各种io类会不会自动创建文件

    File类是不会自动为你生成文件的,它只是为你定位这么一个地方,倘若需要为这个位置上的这个Fiel类所指定的文件名新建一个文件就得用到File类的一个成员方法:public boolean creat ...

  3. 【Unity3D小功能】Unity3D中在创建完项目后自动创建文件夹列表

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦. 一.前言 ...

  4. u盘复制文件第二台计算机无文件夹,电脑上的文件不能复制到U盘,U盘不能创建文件夹及删除文件...

    电脑上的文件不能复制到U盘,U盘不能创建文件夹及删除文件 计算机基础知识    知识宝库    2013-8-3    6606    0评论 最好查一下电脑被设置的什么保护,该怎样解开 你确认一下, ...

  5. 魔术唤醒_用户友好的魔术链接

    魔术唤醒 For the past few years, I've been recommending passwordless login via magic links for most use ...

  6. html 文件上传_某平台存在多处任意文件上传

    文章来源: EDI安全 01 漏洞标题 某平台存在多处任意文件上传 02 漏洞类型 文件上传 03 漏洞等级 中危 04 漏洞地址 http://xxxx.xxxxx.com/er.app.xxxx/ ...

  7. 启动转换安装失败 拷贝windows安装文件时出错_系统小技巧:“徒手”创建可启动的VHD系统...

    本刊曾介绍过创建Windows 10 VHD虚拟系统的方法,创建这样的系统除了需要用到Windows 10的ISO安装文件外,还要用到相应的第三方工具.实际上,不用任何第三方工具,仅通过Windows ...

  8. axure文件如何加密_怎么样给PDF加密?PDF文件如何加密?

    PDF文件在日常办公中使用频率非常得高,PDF格式可以保护文档内容不被随意修改,以及固定内容的格式,使其不易出现变动.如果我们想要这个PDF文件更加的安全,例如不让他人轻易打开看到PDF文件里的内容, ...

  9. ubuntu 将某个目录下的文件复制到_命令行 将多个特定文件从一个文件夹复制到另一个文件夹...

    只需从命令行一次复制多个文件 有几种方法可以实现这个,我见过的最容易的是cp /home/usr/dir/{file1,file2,file3,file4} /home/usr/destination ...

最新文章

  1. MySQL 误操作恢复表
  2. 使用 pm2-web 监控 pm2 服务运行状态
  3. SQL Server 2012中的Contained Database尝试
  4. TL-410小路由静态路由问题
  5. anaconda与pip 清华镜像源
  6. Python中flatten( ),matrix.A用法
  7. [bootStrap]代码块出现横线滚动条
  8. linux/unix编程手册-16_20
  9. B站美股增长13.24% 收盘价26.34美元创历史最高价
  10. MYSQL主从同步(主库服务器为Linux,从库为Windows)
  11. JavaScript获取验证码,60秒倒计时方法
  12. 拓端tecdat|Stata中的治疗效果:RA:回归调整、 IPW:逆概率加权、 IPWRA、 AIPW
  13. java中example函数作用,MyBatis逆向工程中的Mapper接口以及Example的实例函数及详解...
  14. 看大神如何玩转微信小程序日历插件?
  15. pytorch个人学习笔记(2)—Normalize()参数详解及用法
  16. 电子计算机发展经历几个阶段,计算机的发展经历几个阶段?每个阶段的电子原件及特征主要概述...
  17. 快速web开发框架——learun framework
  18. 将开发板的usb配置为ncm网口(qnx系统)
  19. Kubernetes——service管理
  20. 北航计算机考研机考,11北航计算机复试上机

热门文章

  1. mysql 修改某字段的格式为 utf8mb4
  2. 样式集 - 自适应居中弹窗
  3. 弹性布局,自动按比例居中
  4. vue组件定义、组件的切换、组件的通信、渲染组件的几种方式(标签、路由、render)...
  5. 安装 ssh 的公开密匙到 iPhone 上
  6. #读书笔记 Android-Activity启动模式
  7. Oracle学习笔记十三 触发器
  8. Spring笔记——8.基于XML Schema的简化配置
  9. redis-3.0.2集群部署
  10. Python学习笔记--序列