Import and Export Gotchas - JessicaOPRD/docs GitHub Wiki

Front-end importing and exporting has been historically unkind to developers. Part of the reason for this is rapid turnover in module system specifications/syntax/conventions over the past 10 years, as well as framework turnover (both JavaScript and CSS pre-processing). It's been a lot. Below are some gotchas:

JavaScript

I don't find the official Node documentation very helpful in explaining the various import/export flavors.

ES6 Module Import and Export

Resources

CSS Preprocessors

Sass

Understand that sass and scss files can be imported together

Coming from a background with LESS, I was confused about why two popular Sass flavors and file extensions coexist in the same project. Here is a good Stack Overflow breakdown. Essentially .sass is older and space-sensitive, and .scss is newer and more like traditional CSS. However .sass is not deprecated and it is a matter of choice. I personally think Sass has made itself very confusing by supporting two flavors, but some might argue the varying syntaxes are helpful depending on use. The convention I have seen in some frameworks is to use scss files for variables and sass files for rules.

Know which package/library is building your Sass

There have been many command line libraries in this space. You might not know what's building it if you use Webpack with sass-loader. As I'm writing this you can use either dart-sass or node-sass to power sass-loader. node-sass has support for things like importers but appears to have fallen out of favor. This is most likely due to performance issues. The Dart VM is cited as being very fast in comparison (even replacing the Ruby Sass compiler). If you install dart-sass manually, you will get: "[email protected]: This package has been renamed to 'sass'." So maybe I have just come into this space at a very confusing time. But you will want to know which is building your files before you get too committed to the way you do imports/exports.

Aliases for bundlers like Webpack may not be interpretable by a Sass compiler alone

In some cases, there is legitimate need to build the styles separately or in addition to. I had not considered that my Node.js and Webpack aliases could break any attempt to build with a Sass compiler. If this could be a need (and it will be if you have need for a style sheet that does not correspond to a JavaScript entry point), try to test your standalone Sass build as you go.

~ alias for node_modules

If your Sass files will be loaded through Webpack's sass-loader, you can import like so:

@import '~vuetify/src/styles/styles.sass';

Which points to 'node_modules/vuetify/src/styles/styles.sass'.

However, if you need to build a stand-alone CSS file that is not present in your JavaScript, but still uses the same source files, it makes more sense to build directly with your Sass compiler. Unfortunately this is where the magic of Webpack might haunt you, as the ~ is not recognized by dart-sass/sass.

The solution I have found is to remove the tilde from the Sass files:

@import 'vuetify/src/styles/styles.sass';

Next compile by declaring a load path:

sass --load-path=node_modules path/to/src.sass path/to/dist.css"

This works with both sass (^1.25.0) and sass-loader (^8.0.2). I'm not sure when the ~ became "optional," but imagine there is a lot of historical context here.

Custom Webpack aliases

@ became a popular convention for simplifying import paths and reducing relative path complexity (./../../../MyComponent for instance). Such aliases can be declared like so:

const webpackConfig = {
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'path/to/src'),
    }
  }
}

However, as above, the Sass compiler alone will be unable to recognize this import alias outside of a Webpack context. If there is a way to map aliases, I have not found it yet.

To fix this, use the relative paths when importing in Sass files.

Wrong
@import '@/plugins/vuetify/mixins/typography'
Correct

It happens to be a simple relative path here, but with other use the path could become more obfuscated/difficult to determine origin.

@import 'typography'