manipulateOptions

Each plugin can change the options

In the package @babel/core, the manipulateOptions methods of all the plugins are used to manipulate the options. Inside the src/transformation/normalize-opts.js file of the @babel/corepackage we can see this hook code:

// @flow
 
import path from "path";
import type { ResolvedConfig } from "../config";
 
export default function normalizeOptions(config: ResolvedConfig): {} {
  const { ... } = config.options;
 
  const opts = config.options;
 
  const options = { ...opts, parserOpts: {  ... }, generatorOpts: { ... } };
 
  for (const plugins of config.passes) {
    for (const plugin of plugins) {
      if (plugin.manipulateOptions) { // give the plugin a chance to manipulate the options
        plugin.manipulateOptions(options, options.parserOpts);
      }
    }
  }
 
  return options;
}

The manipulateOptions method of plugins are called before the parser is initialized and can be used to modify the parser options.

References to manipulateOptions

  • manipulateOptions is mentioned in https://babeljs.io/docs/v7-migration-api

    export default function() {
     return {
       manipulateOptions(opts, parserOpts) {
         parserOpts.tokens = true;
       },
       ...
     };
    }
  • Tan Li Hau in his article Codemod with babel (2019) mentions the manipulateOptions method. He recommends this template to start a babel transformation:

    const babel = require('@babel/core');
    const { promisify } = require('util');
    const { writeFile } = promisify(require('fs').writeFile);
     
    (async function() {
      const { code } = await babel.transformFileAsync(filename, {
        plugins: [
          function() {
            return {
              manipulateOptions(opts, parserOpts) {
                /*
                add to parserOpts.plugins to enable the syntax
                eg: 
                  jsx, flow, typescript, objectRestSpread, pipelineOperator, 
                  throwExpressions, optionalChaining, nullishCoalescingOperator, 
                  exportDefaultFrom, dynamicImport, ...
                */
                parserOpts.plugins.push(
                  'classProperties',
                  'classPrivateProperties'
                );
              },
              visitor: {
                // fill in a transformer here
              },
            };
          },
        ],
      });
      await writeFile(filename, code, 'utf-8');
    })();
  • Transpile JSX using your own custom built babel plugin

    … When you try to parse this jsx using your local babel cli, you will get a syntax error. Because the parser does not know anything about the jsx syntax. Thats why we need to add a file which manipulates the parser, name it as jsx-syntax-parser.js

    module.exports = function () {
      return {
        manipulateOptions: function manipulateOptions(opts, parserOpts) {
          parserOpts.plugins.push("jsx");
        }
      };
    };