𧩠Boilerplates in VSCode
Matt Kenefick
Posted on November 13, 2023
What is it?
A Visual Studio Code plugin streamlining the creation and management of reusable templates. It's an essential tool for developers looking to optimize their workflow in VSCode.
Why use it?
It's a versatile templating system designed for flexible application. Here are some practical use cases:
Project Boilerplates: Streamline the initial setup for complex projects, including web servers, prototypes, and standard templates.
Dynamic File Templates: Generate files with dynamic variables (docblocks, author info, dates, paths) for personalized, consistent documentation.
Dynamic Structures: Generate folders of files with dynamic variables like you might find in an Angular project.
File Distribution: Spread out files across existing directories / subdirectories of a project. (Some files in /etc
, some in /var
, some in /home
)
Quickstart: A basic template
First, we create a template folder we can use.
- Create a new template by pressing
Cmd+Shift+P
and> File Template: New template
- Select
$WORKSPACE/.vscode/templates
- Type "My First Extension" in the prompt
- Add some new file(s) in this newly opened project
You now have a working template. Here's how to use it:
Option 1: Generate into the root of project
Open your command panel with Cmd+Shift+P
and select > File Template: Generate here...
You should now see the "My First Extension" available in the dropdown. Select that and watch the files appear in the root of your open folder.
Option 2: Generate into a specific folder
Right click a folder in the file explorer and select File Template: Generate here...
.
You should now see the "My First Extension" available in the dropdown. Select that and watch the files appear in the selected folder.
Template Setup
The structure of a template could look like this:
your-project/
βββ manifest.json
βββ src/
βββ {filename}.ts
βββ {filename}.scss
βββ index.html
By default, the filename copied from your template directory are the same. If you need a dynamic filename(s), you can wrap a variable in brackets like so:
{filename}.vue
{filename}-123.vue
This will prompt the user to provide a value for filename
. If they input "Batman", you will get a directory like this:
Batman.vue
Batman-123.vue
We automatically include static variables from process.env
and the nearest package.json
, if one is available, but you can also define custom variables. There are a couple examples in the examples directory demonstrating a range of functionality for templates.
Note: We start looking for a package.json in the path you've selected and search upwards for the nearest one. This allows you to have multiple projects open in a workspace but still use the most accurate manifest.
For env vars, you can use them like this:
My Home: ${env.HOME}
My User: ${env.USER}
For package.json
vars, you can use them like this:
${package.name}
${package.version}
...
To access variables input by the user, like filename
if requested by VSCode:
${input.filename}
You can setup custom variables in settings like this:
"new-from-template.variables": {
"${lorem}": "Lorem ipsum sit amet dolor adipiscing elit et al.",
"${my-variable}": "Hello World."
}
Dynamic code can be executed via the eval()
function in JavaScript by using a double bracket syntax like this: ${{ Date.now() }}
There are several variables injected into the dynamic variables scope, including:
// Special path variables (interpreted)
${{ workspaceRoot }} = /Users/mattkenefick/Sites/Projects/vscode-file-template
${{ inputPathRelative }} = .vscode/templates/my-first-extension/index.js
${{ outputPathRelative }} = tmp/index.js
${{ inputDirectory }} = /Users/mattkenefick/Sites/Projects/vscode-file-template/.vscode/templates/my-first-extension
${{ outputDirectory }} = /Users/mattkenefick/Sites/Projects/vscode-file-template/tmp
${{ inputDirectoryRelative }} = .vscode/templates/my-first-extension
${{ outputDirectoryRelative }} = tmp
${{ inputFilename }} = index.js
${{ outputFilename }} = index.js
You can also access the static variables (env/package) through the dynamic scope by prefixing like this: ${{ variables.package_version }}
. You might do this to separate SEMVAR from your version, like this:
${{
const [major, minor, patch] = variables.package_version.split('.');
`Major: ${major}\nMinor: ${minor}\nPatch: ${patch}`
}}
You can also dynamically define variables on the fly within the template for later use. Let's say we wanted to define a custom "classname" to be used in multiple spots:
${--
variables.className = outputPathRelative.split('.').slice(0, -1).join('.').split('/').join('-').toLowerCase().split('src-')[1]
--}
// The above can be later accessed via ${{ variables.className }} in the same template
Note: If you're trying the above technique, but the code still appears in your template, you may have a syntax error.
You can include standard JavaScript logic like conditionals as well:
${{
if (variables.package_author.indexOf('Kenefick') > -1) {
`It's Matt.`
}
else {
`It's someone else.`
}
}}
An example docblock might look like:
/**
* @author ${package.author}
* @package ${{ outputDirectoryRelative.split('src/')[1] }}
* @project ${package.name}
*/
which may generate out as:
/**
* @author Matt Kenefick <matt.kenefick@buck.co>
* @package Page
* @project MyProject
*/
Configuration
There are two places where templates are stored:
- Your home directory, e.g.
$HOME/VsCodeTemplates
- Local vscode directory of your project, e.g.
project/.vscode/templates
This can be adjusted in your settings.
"new-from-template.templateDirectories": [
".vscode/templates",
"$HOME/VSCodeTemplates"
]
Posted on November 13, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.