Based on your query and provided code snippet, it seems like you are interested in converting only the portion of a vue
file that contains sass/scss
code. To achieve this task, I would create a custom script that follows these steps:
- Iterate through all the
.vue
files.
- Determine if there is a style tag with the language set to
sass
.
- Replace the content with the compiled
css
code.
In order to execute the above steps, three packages will be utilized:
- node-sass: Used for converting
sass/scss
code to css
.
- fs-extra: Employed for file-handling purposes and as an alternative to the native
fs
module. However, you can stick with the fs
module if desired.
- vue-template-compiler: Serves as a parser specifically designed for understanding Vue components. Although using regular expressions (
regex
) could have been a feasible option, parsing a language with regex is generally discouraged due to certain computational concepts. For further details, refer to this post.
The following code exemplifies the implementation:
// convert-sass.js
const fs = require('fs-extra');
const path = require('path');
const sass = require('node-sass');
const compiler = require('vue-template-compiler');
const vueDirectory = './src'; // Path to the directory containing .vue files.
function convertSASSinVueFiles(dir) {
// 1. Iterate over all files within the directory with a .vue extension.
fs.readdirSync(dir).forEach(file => {
const filePath = path.join(dir, file);
if (fs.lstatSync(filePath).isDirectory()) {
convertSASSinVueFiles(filePath);
} else if (path.extname(file) === '.vue') {
convertSASSinVueComponent(filePath);
}
});
}
function convertSASSinVueComponent(file) {
const content = fs.readFileSync(file, 'utf8');
// Parse the Vue file.
const parsedComponent = compiler.parseComponent(content);
/* 2. Check for a style tag with lang attribute set to sass.
Adjustments may be made based on requirements. */
if (parsedComponent.styles.length > 0 &&
(parsedComponent.styles[0].lang === 'sass' ||
parsedComponent.styles[0].lang === 'scss')) {
const sassCode = parsedComponent.styles[0].content;
// Convert sass code to css.
const cssCode = sass.renderSync(
{
data: sassCode,
includePaths: ['./path/to/your/partials']
}
).css.toString();
// Replace sass content with css code.
const updatedContent = content.
replace(/<style.*lang="s[ac]ss".*>([\s\S]*?)<\/style>/,
`<style>${cssCode}</style>`);
fs.writeFileSync(file, updatedContent);
}
}
convertSASSinVueFiles(vueDirectory);
NOTE 1: The current replace regex, i.e.,
/<style.*lang="s[ac]ss".*>([\s\S]*?)<\/style>/
, accommodates both scss and sass syntaxes. Modifications can be made according to specific needs.
NOTE 2: When utilizing partials, ensure inclusion of one of the properties offered by the scss-compiler, such as the includePaths option.
EDIT:
Initially, the provided code covered conversion from .scss to .css syntax. However, considering recent feedback highlighting usage of .sass syntax instead of .scss, adjustments need to be made. Refer to this post for insights on the differences between their syntaxes. Notably, one employs indentation while the other utilizes curly braces similar to CSS rules.
Fortunately, there exists a single compiler capable of handling both syntaxes, as initially utilized. Simply incorporate an additional option, indentedSyntax, to the renderSync()
function and set its value to true:
const isSass = parsedComponent.styles[0].lang === 'sass';
const cssCode = sass.renderSync(
{
data: sassCode,
includePaths: ['./path/to/your/partials'],
indentedSyntax: isSass // Enable for sass syntax
}
).css.toString();
NOTE 3: Consider adjusting the partials paths within the includePaths
option to align with project requirements. If specified, the compiler will search within the designated directory for partials, disregarding relative paths inside your @import
rule. To illustrate, providing ./src/sass
in the array of includePaths
and importing a partial as
@import './src/sass/someDir/typography';
might trigger a file not found error. In such cases, omitting the
includePaths
option from the script could be beneficial.
CODE DEMO