Motivation
The amazing ast-grep tool does not support vue
and scss
by default but can be configured to do so.
ast-grep
is like a much more powerful version of ripgrep
or grep
when it comes to searching for patterns within code as it understands the structure of the code (via the library tree-sitter).
For example the following command:
ast-grep -p '<h2>$A</h2>'
Will show all <h2>
tags in your html
(and also vue
files after applying the config from this post). Then the following could change all <h2>
tags to <h3>
tags interactively (each change will be shown and then y
can be used to accept it or n
to reject it):
ast-grep -p '<h2>$A</h2>' -r '<h3>$A</h3>' -i
-U
can be used instead of -i
to apply the changes without asking or neither can be used to view all the changes as a patch.
Configuration
All of the following commands should be run from the root directory of your vue
project.
First create a "rules" directory and add it to git
. This rules directory must exist for the config to be accepted so for now just create an empty directory (later it's possible to create rules based on ast-grep
patterns within this directory to scan/fix things in the code based, think of it like writing an eslint
library but much easier).
mkdir ast-rules
touch ast-rules/.keep-dir
git add ast-rules/.keep-dir
Then create a file sgconfig.yml
:
ruleDirs:
- ast-rules
customLanguages:
vue:
libraryPath: .tree-sitter/vue.so
extensions: [vue]
expandoChar: $
scss:
libraryPath: .tree-sitter/scss.so
extensions: [scss]
expandoChar: $
languageInjections:
- hostLanguage: vue
rule:
pattern: <template>$CONTENT</template>
injected: html
- hostLanguage: vue
rule:
pattern: <script $$$ lang="ts" $$$>$CONTENT</script>
injected: typescript
- hostLanguage: vue
rule:
pattern: <style $$$ lang="scss" $$$>$CONTENT</style>
injected: scss
Now a script is needed to create the libraries that this ast-grep
configuration needs to understand vue
and scss
files. This could be created at scripts/init-ast-grep-config.sh
:
#!/usr/bin/env bash
outdir=$PWD/.tree-sitter/
mkdir $outdir
cd /tmp
git clone https://github.com/tree-sitter-grammars/tree-sitter-vue
cd tree-sitter-vue
pnpm dlx tree-sitter-cli build
cp vue.so $outdir/
cd ..
rm -rf tree-sitter-vue
git clone https://github.com/serenadeai/tree-sitter-scss
cd tree-sitter-scss
pnpm dlx tree-sitter-cli build
cp scss.so $outdir/
cd ..
rm -rf tree-sitter-scss
Then ensure this script is executable:
chmod a+x scripts/init-ast-grep-config.sh
This script stores files within a directory .tree-sitter
within the project, since these libraries are binaries they are unique to the platform on which they were compiled so it's probably desirable to add the .tree-sitter
directory to .gitignore
.
Next add a reference to this script to the scripts
section of package.json
:
{
"scripts": {
"init-ast-grep-config": "./scripts/init-ast-grep-config.sh"
}
}
Now document this in your readme.md
, commit everything to git
, and developers on the project can begin using ast-grep
on your vue
project after running pnpm run init-ast-grep-config
.
Top comments (1)
Thanks for sharing! This is very helpful and cool!