Is Using @Import Declarations a Bad Practice

Is using @import declarations a bad practice?

I think you should use LINK for simplicity—you have to remember to put @import at the top of the style block or else it won’t work. It turns out that avoiding @import is better for performance.

link

  • Linking is the first method for including an external style sheet on your Web pages. It is intended to link together your Web page with your style sheet.

import

  • Importing allows you to import one style sheet into another. This is slightly different than the link scenario, because you can import style sheets inside a linked style sheet.

The most common reason given for using @import instead is because older browsers didn't recognize @import, so you could hide styles from them.

This link will solve your all queries

What's the Difference Between @import and link for CSS?

Why is using a wild card with a Java import statement bad?

The only problem with it is that it clutters your local namespace. For example, let's say that you're writing a Swing app, and so need java.awt.Event, and are also interfacing with the company's calendaring system, which has com.mycompany.calendar.Event. If you import both using the wildcard method, one of these three things happens:

  1. You have an outright naming conflict between java.awt.Event and com.mycompany.calendar.Event, and so you can't even compile.
  2. You actually manage only to import one (only one of your two imports does .*), but it's the wrong one, and you struggle to figure out why your code is claiming the type is wrong.
  3. When you compile your code, there is no com.mycompany.calendar.Event, but when they later add one, your previously valid code suddenly stops compiling.

The advantage of explicitly listing all imports is that I can tell at a glance which class you meant to use, which simply makes reading the code much easier. If you're just doing a quick one-off thing, there's nothing explicitly wrong, but future maintainers will thank you for your clarity otherwise.

Why is import * bad?

  • Because it puts a lot of stuff into your namespace (might shadow some other object from previous import and you won't know about it).

  • Because you don't know exactly what is imported and can't easily find from which module a certain thing was imported (readability).

  • Because you can't use cool tools like pyflakes to statically detect errors in your code.

Should import statements always be at the top of a module?

Module importing is quite fast, but not instant. This means that:

  • Putting the imports at the top of the module is fine, because it's a trivial cost that's only paid once.
  • Putting the imports within a function will cause calls to that function to take longer.

So if you care about efficiency, put the imports at the top. Only move them into a function if your profiling shows that would help (you did profile to see where best to improve performance, right??)


The best reasons I've seen to perform lazy imports are:

  • Optional library support. If your code has multiple paths that use different libraries, don't break if an optional library is not installed.
  • In the __init__.py of a plugin, which might be imported but not actually used. Examples are Bazaar plugins, which use bzrlib's lazy-loading framework.

Import package.* vs import package.SpecificType

There is not a performance or overhead cost to doing import .* vs importing specific types. However, I consider it to be a best practice to never use import .* My primary reason for this is I just like to keep things straightward, clean and with as little ambiguity as possible, and I think with a .* import you lose that.

Best way to include CSS? Why use @import?

From a page speed standpoint, @import from a CSS file should almost never be used, as it can prevent stylesheets from being downloaded concurrently. For instance, if stylesheet A contains the text:

@import url("stylesheetB.css");

then the download of the second stylesheet may not start until the first stylesheet has been downloaded. If, on the other hand, both stylesheets are referenced in <link> elements in the main HTML page, both can be downloaded at the same time. If both stylesheets are always loaded together, it can also be helpful to simply combine them into a single file.

There are occasionally situations where @import is appropriate, but they are generally the exception, not the rule.

Use 'import module' or 'from module import'?

The difference between import module and from module import foo is mainly subjective. Pick the one you like best and be consistent in your use of it. Here are some points to help you decide.

import module

  • Pros:
    • Less maintenance of your import statements. Don't need to add any additional imports to start using another item from the module
  • Cons:
    • Typing module.foo in your code can be tedious and redundant (tedium can be minimized by using import module as mo then typing mo.foo)

from module import foo

  • Pros:
    • Less typing to use foo
    • More control over which items of a module can be accessed
  • Cons:
    • To use a new item from the module you have to update your import statement
    • You lose context about foo. For example, it's less clear what ceil() does compared to math.ceil()

Either method is acceptable, but don't use from module import *.

For any reasonable large set of code, if you import * you will likely be cementing it into the module, unable to be removed. This is because it is difficult to determine what items used in the code are coming from 'module', making it easy to get to the point where you think you don't use the import any more but it's extremely difficult to be sure.

When to use import and when to use require in Node.JS

Summary

import is the future of the Javascript language in both nodejs and the browser and is used in ECMAScript modules (ESM modules) for loading other modules, either statically or dynamically.

require() is the original way that nodejs loaded modules and is used in CommonJS modules. require() is natively supported in nodejs, but not in browsers (though there are some 3rd party libraries that have require-like module loaders for the browser).

Pick One

You will generally want to pick one mechanism and use it for your whole project as it complicates things to mix/match. import had some growing pains for awhile in nodejs, but the implementation is fairly complete now. Either way, you will probably run into some modules that are not of the type you chose for your project and will have to learn how to deal with that.

If I was starting a new project that I expected to last awhile and be working on it for years, I would pick ESM modules with import as that is the present/future architecture for modules in Javascript.

If I was writing a quick "get it done" kind of script that relied on a bunch of scripts that are only available in CommonJS, I would probably use CommonJS require().

If I was writing modules I wanted to share between nodejs and browsers, I'd pick ESM because it is supported in both.

Your Questions

When I look at the documentation for Node.JS for the file system "fs" module it doesn't make any mention of doing the const fs = require('fs); instead it talks about using the import method import { mkdir } from 'fs'

The current version of the fs documentation lets you pick whether you want the code examples to show CJS or ESM module syntax. You were apparently looking at the doc when it was showing ESM syntax. You can switch it. Either will work.

When you see this image Sample Image in the documentation, that lets you toggle the sample code in the doc from CJS to ESM or back.

SyntaxError: Cannot use import statement outside a module

In nodejs, you have to tell nodejs in some way whether your top level module is CJS or ESM. By default, a .js file is treated as CJS and an .mjs file is treated as ESM. If nodejs thinks you have a CJS file, you cannot use import (that is only for ESM modules).

You can also modify the package.json file that controls your particular script (by adding "type": "module" and force your file to an ESM module if you want (which allows you to use .js files as ESM modules).

Using const fs = require('fs'); works just fine

Yes, if nodejs thinks you are using a CJS module.

I want to make sure my code is consistent/correct so which one do I use and why?

See my previous explanation for when I'd choose each module type. If you are just learning, I would suggest you learn how to tell nodejs you're using ESM modules and use import since that is the future direction of the language. require() isn't going to go away anytime soon, but I would not be surprised if we start to see new NPM packages (shareable modules) that only support the newer ESM syntax and can only be loaded from ESM modules. It is possible (with some careful work) to make a shareable module that can be loaded by either an ESM module or a CJS module.

Also, ESM modules are getting some features (such as top-level await) that CJS modules will never get.

More Details

For more details, I suggest reading this article:

Node Modules at War - Why CommonJS and ESM Modules Can't Get Along

Import statement inside class/function definition - is it a good idea?

It's the most common style to put every import at the top of the file. PEP 8 recommends it, which is a good reason to do it to start with. But that's not a whim, it has advantages (although not critical enough to make everything else a crime). It allows finding all imports at a glance, as opposed to looking through the whole file. It also ensures everything is imported before any other code (which may depend on some imports) is executed. NameErrors are usually easy to resolve, but they can be annoying.

There's no (significant) namespace pollution to be avoided by keeping the module in a smaller scope, since all you add is the actual module (no, import * doesn't count and probably shouldn't be used anyway). Inside functions, you'd import again on every call (not really harmful since everything is imported once, but uncalled for).

@import vs link

Not much if anything has changed in the past year or two, and we're still dealing with a lot of the same browsers from then, so you should not change your practice.

<link> is preferred in all cases over @import, because the latter blocks parallel downloads, meaning that the browser will wait for the imported file to finish downloading before it starts downloading the rest of the content.

You can see this in great detail here:

http://www.stevesouders.com/blog/2009/04/09/dont-use-import/

So, while @import may be convenient, that's all it offers. If you really want to take advantage of fast loading times, use the minimum number of stylesheets (probably one in most cases), write good CSS with efficient selectors (the usual stuff), minify it, and use a <link> tag.


This was going to be a comment but it got too long:

Instead of @import (I know it is very convenient), you should combine the files into one when your site goes live. You shouldn't be tweaking at that point anyways, and there are a number of tools to help minify it. Personally, using PHP, I have a config file where I define all the CSS files that are written to a separate CSS file (the one I will reference in the <link> tag), then if the cached version is old (either determined manually or automatically), it combines/minifies them and writes the content to the "cache" file, and returns a timestamp query string to append to the CSS file name to force a fresh download.

If you are using PHP as well, I highly recommend cssmin, it can parse stylesheets for @import and pull the content into one file, as well as handle all aspects of minification.



Related Topics



Leave a reply



Submit