If you can watch this dialogue patiently,
Maybe you want to configure a code generator,
In this way, your masquerade life may change and become more relaxed from then on.
Speaking from a scaffold
Daniel: Recently I want to build a code generator that can quickly generate project code. What recommendation does Brother Egg have?
Mr. Egg: Yeoman has always been used in the past, and it is an open source project that is faster than 10k star. However, what I want to recommend to you today is not yeoman, but a new generation of fresh meat ncgen
, it may seem more approachable.
Daniel: I like the simple one the most. How does it work?
Mr. Egg: Old rules, you say your needs, I will try to answer them one by one
First, you need a project template
Daniel: I have a project template (for example: vue3-ncgen-demo ), I hope all new projects come from this project template, so I only need to concentrate on maintaining this project template.
Mr. Egg: OK, this is the function of the project scaffolding. Let's take a look at ncgen
is handled.
The first step is to install ncgen
$ npm i ncgen -g # yarn global add ncgen
The second step is to generate a configuration file ncgen-config.js
, which describes the logic of the code generator
$ ncgen genConf
The third step is to modify ncgen-config.js
in main.tmplSource
as the address of the project template.
export default {
main: {
tmplSource: "https://github.com/daniel-dx/vue3-ncgen-demo.git",
},
};
Try it out:
ncgen ncgen-config.js
Simple copying is not enough, minor revisions are the norm
Daniel: Whoops is good. However, the currently generated project is exactly the same as the project template, but it will always have its own information that is different from the project template, such as the name of the project, the name of the author, etc. I don’t want to modify these manually every time the project is generated.
Mr. Egg: OK, the request is very reasonable. Since this information can only be provided by the person who created the project, we need to collect this information through some questions, and then we can make some modifications to the generated project based on this information. We modifications ncgen-config.js
in main.prompt
and main.updateFiles
Example description:package.json
file in the generated project, and the rules are as follows:vue3-ncgen-demo
string 0609b51aee5a4c with the project name entered by the userDaniel.xiao
string 0609b51aee5a60 with the author name entered by the user
export default {
main: {
prompt: [
{
type: "input",
name: "author",
message: "What is the author's name",
},
],
...
updateFiles: {
"package.json": function (content, options) {
const answers = this.$answers
return api.replace(content, {
"vue3-ncgen-demo": answers.projectNameObj.kebabCase,
"Daniel.xiao": answers.author,
});
},
},
}
};
Daniel: Hey, I noticed that the template engine is not used here, but the string replacement is used directly
Mr. Egg: Yes, this design has a lot of meaning. Using a template engine to replace files may cause the project template itself to fail to run normally, because the template engine requires placeholders, and placeholders may cause code parsing errors
Daniel: Yes, in this way the project template is just an ordinary project, and there is no need to make some template placeholder transformations.
The extra files were done yesterday? please delete
Daniel: Then I will continue. There are some template directories and files (such as module template directories, component template files) in my project template, but I don't want to see these templates in the generated project.
Mr. Egg: OK, no problem, just delete the specified files and directories. We modify ncgen-config.js
in main.removeFiles
.
Example description:ncgen-config.js
andsrc/components/base/Template.vue
files in the generated project
export default {
main: {
removeFiles: ["ncgen-config.js", "src/components/base/Template.vue"],
},
};
One-stop service: automatic installation of dependencies
Daniel: I just noticed that the above example will automatically install dependencies when it runs. It should be installed with npm
. Can this support yarn
? If I am a non-NodeJS project, such as Python, Go, etc., can I do it?
Mr. Egg: Yes, yes, the generated ncgen-config.js
uses npm i
to install dependencies by default. See the example below. If you want to change to yarn
, just change command
to yarn install
. And if it is Python, Go and other languages, you only need to change command
to the corresponding dependency installation command.
export default {
main: {
installDependencies: {
skip: false,
tips: "Dependencies are being installed, it may take a few minutes",
command: "npm i",
},
},
};
Finally, give some friendly tips
Daniel: That’s great. The project scaffolding is completed in just a few clicks. I think we need a friendly welcome and beautiful ending in the end.
Mr. Egg: As you wish, simply modify main.welcome
and main.complete
export default {
main: {
welcome: "Welcome to use (Vue 3 + TypeScript + Vite) project generator",
...
complete: "Congratulations, the operation is successful",
},
};
High-frequency use is not scaffolding
Daniel: The scaffolding is done, but it is only used when building a new project. High-frequency operations are still part of the code increase, such as adding a functional module, adding a component, adding an API, etc.
Mr. Egg: I understand what you mean. Old rules, you ask me to answer
The code template exists in the project template
Daniel: I want to add a new component to a project. I don't want to copy an existing component and then perform various operations to modify and delete the code. In fact, there are code templates for components in the project template
Mr. Egg: OK. We first ncgen-config.js
increase in a call add-component
sub-command.
Example description (assuming that the values of category and name are'busi' and'demo' respectively):description
used to describe the function of the subcommand.api.listDirs
This API is very useful when allowing users to choose where to insert the code.addFilesTo
will insert the src/components/base/Template.vue in the project template into the src/components/busi/Demo.vue file in the project.
export default {
sub: {
"add-component": {
description: "Add vue component",
prompt: [
{
type: "list",
choices: function () {
return api.listDirs("src/components/");
},
name: "category",
message: "Please select the category",
},
{
type: "input",
name: "name",
message: "What is the component name",
validate(input) {
if (!input) return "The component name is required";
return true;
},
},
],
tmplSource: "https://github.com/daniel-dx/vue3-ncgen-demo.git",
addFilesTo: function () {
const answers = this.$answers;
return {
"src/components/base/Template.vue": `src/components/${answers.category}/${answers.nameObj.upperFirstCamelCase}.vue`,
};
},
},
},
};
The code template does not exist in the project template
Daniel: Pretty. But for the existing projects, these projects are not from the project template, and I also want to add some subcommands to generate part of the code for the project, yesterday?
Mr. Egg: The subcommand supports two ways to add files, one is the code template from the project template mentioned above, and the other is dynamically created by you. Both can be used at the same time. The following example demonstrates how to dynamically create a code file
Example description (assuming that the values of category and name are'busi' and'demo' respectively):addFiles
will create the src/components/busi/Demo.md file in the project. The content of this file is# Demo
export default {
sub: {
"add-component": {
addFiles: function () {
const answers = this.$answers;
return {
[`src/components/${answers.category}/${answers.nameObj.upperFirstCamelCase}.md`]: function () {
return `# ${answers.nameObj.upperFirstCamelCase}`;
},
};
},
},
},
};
Recommended replacement techniques for cracked walls
Daniel: Next, some file content changes (such as adding a page, the routing rules file will be automatically modified to register routes for the page), right? The operation is the same as the main command.
Mr. Egg: Well savvy. A little trick recommended here is to add some identification comments where you need to insert the fragment code, as shown in the src/App.vue code:
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
<!-- Don't touch me - place component -->
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import HelloWorld from './components/busi/HelloWorld.vue'
// <!-- Don't touch me - import component -->
export default defineComponent({
name: 'App',
components: {
HelloWorld,
// <!-- Don't touch me - register component -->
}
})
</script>
api.insertBefore
with the 0609b51af079a0 API to insert the specified content before the specified matching position of the file
export default {
sub: {
updateFiles: function () {
const answers = this.$answers;
return {
"src/App.vue": function (content, options) {
return api.insertBefore(content, {
"// <!-- Don't touch me - import component -->": `import ${answers.nameObj.upperFirstCamelCase} from './components/${answers.category}/${answers.nameObj.upperFirstCamelCase}.vue'`,
"// <!-- Don't touch me - register component -->": `${answers.nameObj.upperFirstCamelCase},`,
"<!-- Don't touch me - place component -->": `<${answers.nameObj.upperFirstCamelCase}/>`,
});
},
[`src/components/${answers.category}/${answers.nameObj.upperFirstCamelCase}.vue`]: function (
content,
options
) {
return api.replace(content, {
Template: `${answers.nameObj.upperFirstCamelCase}`,
});
},
};
},
},
};
Daniel: Perfect. Thanks to the egg brother, I feel that I have already started the second line of duty, and I am eager to try my first code generator
Mr. Egg: No thanks, looking forward to your feedback
Write at the end
Above-complete configuration
ncgen-config.js
the complete configuration of 0609b51af07a3f in the example, https://github.com/daniel-dx/vue3-ncgen-demo/blob/master/ncgen-config.js
Below-ncgen official website
Keywords: ncgen, scaffolding, generator, code generator, scaffolding
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。