Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NodeJs Script that compiles scss files fails because of postcss rule for undefined variables #101

Open
gquinteros93 opened this issue Mar 16, 2020 · 1 comment

Comments

@gquinteros93
Copy link

I am using scss-bundle to import an scss file and resolve all his @import statements to later save it again as scss file.

This works fine and below is an example to see how it works:

scss-bundle.ts

import { Bundler } from 'scss-bundle';
import { relative } from 'path';
import { writeFile } from 'fs-extra';

/** Bundles all SCSS files into a single file */
async function bundleScss(input, output) {
  const {found, bundledContent, imports} = await new Bundler()
    .Bundle(input, ['./src/styles/**/*.scss']);
  if (imports) {
    const cwd = process.cwd();

    const filesNotFound = imports
      .filter((x) => !x.found)
      .map((x) => relative(cwd, x.filePath));

    if (filesNotFound.length) {
      console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
      throw new Error('One or more SCSS imports failed');
    }
  }

  if (found) {
    await writeFile(output, bundledContent);
  }
}

bundleScss('./src/styles/file-to-import.scss', './src/styles/imported-file.scss');

Where file-to-import.scss is the following file:

@import './file-to-import-1';
@import './file-to-import-2';

And file-to-import-1.scss and file-to-import-2.scss are the following files:

file-to-import-1.scss

.price-range {
  background-color: $range-header-background-1;
}

file-to-import-2.scss

.qr-code {
  background-color: $range-header-background-2;
}

The result of executing the script is:

imported-file.scss:

.price-range {
  background-color: $range-header-background-1;
}

.qr-code {
  background-color: $range-header-background-2;
}

Until this everything is working well.

Now ... I want to use postcss-css-modules in order to hash the names of the classes, the result should be something like this:

imported-file.scss after being hashed

._3BQkZ {
  background-color: $range-header-background-1;
}

.Xb2EV {
  background-color: $range-header-background-2;
}

I have already achieved that but only if I define the variables $range-header-background-1 and $range-header-background-2.

However, I can not define the variables yet because I need to defined them on run time as query params of an Http request.

If I run the script without defining the variables the following error is display:

(node:1972) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): CssSyntaxError: <css input>:372:14: Unknown word
(node:1972) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Here is the scss-budle.ts with postcss-css-modules call:

import { Bundler } from 'scss-bundle';
import { relative } from 'path';
import * as path from 'path';
import { writeFile } from 'fs-extra';
import * as postcssModules from 'postcss-modules';
import * as postcss from 'postcss';
import * as fs from 'fs';

/** Bundles all SCSS files into a single file */
async function bundleScss(input, output) {
  const {found, bundledContent, imports} = await new Bundler()
    .Bundle(input, ['./src/styles/**/*.scss']);
  if (imports) {
    const cwd = process.cwd();

    const filesNotFound = imports
      .filter((x) => !x.found)
      .map((x) => relative(cwd, x.filePath));

    if (filesNotFound.length) {
      console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
      throw new Error('One or more SCSS imports failed');
    }
  }

  if (found) {
    await writeFile(output, bundledContent);

    const hashedResult = await postcss().use(postcssModules({
      generateScopedName: '[hash:base64:5]',
      getJSON(cssFileName: any, json: any, outputFileName: any) {
        let jsonFileName = path.resolve('./src/styles/imported-file.json');
        fs.writeFileSync(jsonFileName, JSON.stringify(json));
      }
    })).process(bundledContent);
    await writeFile(output.replace('.scss', '-hashed.scss'), hashedResult.css, 'utf8');
    return;
  }

}

bundleScss('./src/styles/file-to-import.scss', './src/styles/imported-file.scss');

Does anybody know how to continue executing postcss-css-modules without stopping because the scss variables are not defined?

Thanks in advance.

@gquinteros93
Copy link
Author

Hi, I was able to run the script successfully using postcss-scss as parser of postcss:

import * as postcssScss from 'postcss-scss';

...

const hashedResult = await postcss([
  postcssModules({
    generateScopedName: '[hash:base64:8]',
    getJSON(cssFileName: any, json: any, outputFileName: any) {
        let jsonFileName = path.resolve('./src/styles/imported-file.json');
        fs.writeFileSync(jsonFileName, JSON.stringify(json));
    }
  })
]).process(bundledContent, { parser: postcssScss});


I answered the question in stackoverflow also I leave the script complete here:

scss-bundle.ts

import { Bundler } from 'scss-bundle';
import { relative } from 'path';
import * as path from 'path';
import { writeFile } from 'fs-extra';
import * as postcssModules from 'postcss-modules';
import * as postcss from 'postcss';
import * as fs from 'fs';
import * as postcssScss from 'postcss-scss';

/** Bundles all SCSS files into a single file */
async function bundleScss(input, output) {
  const {found, bundledContent, imports} = await new Bundler()
    .Bundle(input, ['./src/styles/**/*.scss']);
  if (imports) {
    const cwd = process.cwd();

    const filesNotFound = imports
      .filter((x) => !x.found)
      .map((x) => relative(cwd, x.filePath));

    if (filesNotFound.length) {
      console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
      throw new Error('One or more SCSS imports failed');
    }
  }

  if (found) {
    await writeFile(output, bundledContent);

	const hashedResult = await postcss([
	  postcssModules({
	    generateScopedName: '[hash:base64:8]',
	    getJSON(cssFileName: any, json: any, outputFileName: any) {
	        let jsonFileName = path.resolve('./src/styles/imported-file.json');
	        fs.writeFileSync(jsonFileName, JSON.stringify(json));
	    }
	  })
	]).process(bundledContent, { parser: postcssScss});
    await writeFile(output.replace('.scss', '-hashed.scss'), hashedResult.css, 'utf8');
    return;
  }
}

bundleScss('./src/styles/file-to-import.scss', './src/styles/imported-file.scss');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant