0.0.4 • Published 6 years ago

nej-global-dependency-fixer v0.0.4

Weekly downloads
-
License
MIT
Repository
-
Last release
6 years ago

NEJ Global Dependency Accessor Fixer

This is a tool used for fixing NEJ global namespace dependency accessor NEJ.P usage.

Introduction

Undefined errors occur when you use NEJ.P without explicitly declaring the dependency files. For examples:

  NEJ.define([], function () {
    var someDep = NEJ.P('some-namespace');

    // Using the module without declaring it
    console.log(someDep.name);
  });

Most of the time, people use NEJ module system with NEJ's build tool and if the CORE_FREQUENCY_JS configuration variable is not set, its default value is 2. With that value, almost all js files will be bundled into any pages. Therefore problems are temporarily avoided with the cost of serving a bloated js file with over 50% unused js code. However, once we try to increase the CORE_FREQUENCY_JS variable so that we could reduce unused code, problems will occur.

Fortunately, most of the usage of NEJ.P are pretty much the same with some possible exceptions, so it could theoretically be solved with an automatic script.

What this tool does is that it automatically resolves all undeclared dependency files and add them to the dependency list. After running the tool on a project, the code snippet above will become:

  NEJ.define(['some/resolved/path'], function () {
    var someDep = NEJ.P('some-namespace');

    // Using the module without declaring it
    console.log(someDep.name);
  });

Problems solved, without breaking a sweat.

Features

  1. Automatically resolves undeclared dependencies.
  2. Supports custom resolution strategies or simple pattern resolution strategies.
  3. Supports several different ways of using NEJ.P except for dynamic runtime usage with non-deterministic namespace and exports.

Usgae

Step 1: Installation

$ npm i nej-global-dependency-fixer -g

or

$ yarn add nej-global-dependency-fixer -g

Step 2: Add a configuration file

A configuration file is a must-have before running the tool. To create one, the simplest way is create a ngdf.conf.js under your CWD.

For all available configuration options, see options.

Step 3: Run with CLI or Node APIs

  • To run with CLI

    Make sure you are under a correct CWD, since all configuration paths are resolved relative to it.

    To run the tool, simple type

    $ nej-global-dependency-fixer
  • To run with Node APIs

    const nejGlobalDependencyFixer = require('nej-global-dependency-fixer');
    
    nejGlobalDependencyFixer.run({
      // Config
    }, () => {
      // Done
    });

Configuration Options

  • projectDir

    Type: String

    Required: Yes

    Description: A directory of the entry project

    Example:

    {
      projectDir: './'
    }
  • nejPathAliases

    Type: Object

    Required: Yes

    Description: A map of NEJ path aliases.

    Example:

    {
      nejPathAliases: {
        pro: 'src/',
      }
    }
  • noWrite

    Type: RegExp

    Required: No

    Description: A pattern for matching paths of files that should not be changed. Defaults to undefined.

    Example:

    {
      noWrite: /lib/
    }
  • outDir

    Type: String

    Required: No

    Description: A directory of where the resolved files should be written to. Defaults ot projectDir.

    Example:

    {
      outDir: './dist/'
    }
  • logFilename

    Type: String

    Required: No

    Description: A filename of which the log will be write to. Defaults to undefined and no log files will be created.

    Example:

    {
      logFilename: './logs/ngdf.log'
    }
  • logLevels

    Type: Array

    Required: No

    Description: Determines what kinds of logs will be printed. All available values are 'info', 'warning', 'debug' and 'error'. Defaults to 'info', 'warning' and 'error'.

    Example:

    {
      logLevels: [
        'info'
      ]
    }
  • conflictResolutionMap

    Type: Object

    Required: No

    Description: A map to check for resolution when conflicts occur. Keys and values are both regular expression pattern strings.

    Example:

    {
      conflictResolutionMap: {
        '_\\$addEvent|_\\$clearEvent|_\\$dispatchEvent|_\\$delEvent': 'nej/src/base/event\\.js',
      }
    }
  • customConflictResolutionStrategy

    Type: Function

    Required: No

    Description: A function used to provide custom resolution strategy. It must return undefined, false or a file object. For more information, see How to Write a Custom Conflict Resolution Strategy Function;

    Example:

    {
      customConflictResolutionStrategy: function (currentFile, conflictFileList, symbol, projectInfo) {
        // return undefined;
        // return false;
        // return conflictFileList[i];
      }
    }
  • promptConflict

    Type: Boolean

    Required: No

    Description: Whether to prompt for users to manually select the file to resolve when encountering conflicts.

    Example:

    {
      promptConflict: true
    }

How to Write a Custom Conflict Resolution Strategy Function

If you have a more sophisticated resolution strategy to use, you can use the configuration variable customConflictResolutionStrategy to provide a function to do it.

The only thing to keep in mind is that, it needs to return undefined, false or a file object. A file object must be one of the files in the conflict file list.

  1. Returning undefined

It means that this resolution strategy does not work for this file and this symbol. It will proceed and if no files are resolved, it will throw an error.

  1. Returning false

It means that this symbol in this file does not need to be resolved, and this symbol will be skipped.

  1. Returning a file object

It will resolve this symbol in this file to the file you return.

For arguments passed to this function, it has:

```js
{
  /**
   * @interface IFile
   * 
   * @property {ISymbol[]} symbols The symbols using NEJ.P in this file
   * @property {string} filePath An absolute file path
   */
  
  /**
   * @interface ISymbol
   * 
   * @property {string} propertyName The name of the symbol
   * @property {string} nejNamespace The namespace it is in
   * @property {SYMBOL_ASSIGNMENT_TYPE} assignmentType Three types: NOT_ASSIGNMENT = 0, ASSIGNMENT_TO_ITSELF = 1, ASSIGNMENT_NOT_TO_ITSELF = 2
   */

  /**
   * @param {IFile} currentFile The file object that the symbol is in
   * @param {IFile[]} conflictFileList A list of files where the symbol is defined in
   * @param {ISymbol} symbol The symbol to resolve
   */
  customConflictResolutionStrategy: function (currentFile, conflictFileList, symbol) {
    // return undefined;
    // return false;
    // return conflictFileList[i];
  }
}
```