Inappropriate coding practices - Wildcard export - Dart

Inappropriate coding practices - Wildcard export - Dart

Need

Enforce explicit export of functions in libraries

Context

  • Usage of Dart 2.0 for building high-performance, cross-platform applications
  • Usage of lib.dart for implementing Dart libraries and modules

Description

Non compliant code

        // lib.dart
library lib;

void function1() {
  print('Function 1');
}

void function2() {
  print('Function 2');
}

void function3() {
  print('Function 3');
}

// main.dart
import 'lib.dart' show *;

void main() {
  function1();
  function2();
  function3();
}
        
        

The lib.dart file defines a library named lib and it includes three functions: function1, function2, and function3.

In main.dart, the wildcard operator (*) is used to import all functions from lib.dart. This is a bad practice because it can lead to name clashes if there are functions with the same name in different libraries. It also makes it harder to track which functions are being used from the lib.dart file. It can lead to unnecessary imports if not all functions are used, which can increase the size of the final compiled code.

Moreover, the wildcard import makes it harder to understand which functions are coming from which libraries, especially in a large codebase with many libraries. This can make the code harder to read and maintain.

Therefore, it is better to explicitly import only the functions that are needed. This not only avoids potential name clashes and unnecessary imports, but also makes the code easier to understand and maintain.

Steps

  • Identify the specific functions that are needed from the library in your code.
  • Instead of using the wildcard operator (*), explicitly import only those functions that are required.
  • Remove the wildcard operator (*) from the import statement.
  • Replace it with the specific function names separated by commas.
  • Ensure that the rest of your code is updated to reflect these changes, if necessary.

Compliant code

        // lib.dart
library lib;

void function1() {
  print('Function 1');
}

void function2() {
  print('Function 2');
}

void function3() {
  print('Function 3');
}

// main.dart
import 'lib.dart' show function1, function2, function3;

void main() {
  function1();
  function2();
  function3();
}
        
        

The original code was vulnerable due to the use of the wildcard operator (*) in the import statement. This operator was used to import all functions from the 'lib.dart' library, which is a bad practice as it can lead to complications in the use and maintenance of the module.

The fixed code no longer uses the wildcard operator. Instead, it explicitly imports only the functions that are required, which in this case are function1, function2, and function3. This is done using the show keyword followed by the specific function names separated by commas.

This change makes the code safer and easier to maintain, as it's now clear which functions are being imported from the library. It also reduces the risk of naming conflicts and makes the code easier to read and understand.

Remember to update the rest of your code to reflect these changes if necessary. For example, if you were using a function from the library that you have now stopped importing, you will need to either start importing that function or remove the code that uses it.

References