-
Notifications
You must be signed in to change notification settings - Fork 0
Import and Export Gotchas
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:
I don't find the official Node documentation very helpful in explaining the various import/export flavors.
- ES6 Modules and How to Use Import and Export in JavaScript — good examples
- MDN JavaScript Modules — provides good background and more complex examples
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.
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: "dart-sass@1.25.0: 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.
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.
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.
@
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.
@import '@/plugins/vuetify/mixins/typography'
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'
Testing what this does?