Search code examples
javascriptnode.jsbabeljsstrict

How to programmatically pass options to Babel transforms/plugins?


A tool I work on uses Babel programmatically. It requires few plugins and everything works fine.

Tho, I want to pass options to a Babel transform. I realized I didn't did that yet, and looks like what I'm trying just doesn't work.

Specifically, I want to include the babel-transform-strict-mode and pass strict:false to disable the global strict mode.

The docs explain how to use it when having a .babelrc file:

// with options
{
  "plugins": [
    ["transform-strict-mode", {
      "strict": true
    }]
  ]
}

In my code I have:

const babelify = require("babelify")
    , es2015 = require("babel-preset-es2015")
    , reactify = require("babel-preset-react")
    , strictMode = require("babel-plugin-transform-strict-mode")
    ;

...

this.browserify.transform(babelify, {
    global: true,
    babelrc: false,
    presets: [
        reactify
      , es2015
      , [
            strictMode
          , { strict: false }
        ]
    ] 
});

While es2015 and reactify work great in the presets array, adding strictMode with { strict: false } just doesn't work.

The error is:

ReferenceError: [BABEL] /home/.../index.js: Unknown option: foreign.visitor.
Check out http://babeljs.io/docs/usage/options/ for more
information about options.

A common cause of this error is the presence of a
configuration options object without the corresponding
preset name. Example:

Invalid:
  `{ presets: [{option: value}] }`
Valid:
  `{ presets: [['presetName', {option: value}]] }`

For more detailed information on preset configuration,
please see
http://babeljs.io/docs/plugins/#pluginpresets-options.

If I use instead of strictMode the transform name (["transform-strict-mode", { strict: false }]), it won't find the module, obviously, because this is part of a different module.

How can I pass options to the required modules (in this case the strictMode), programmatically (without babelrc)?


Solution

  • Generally the recommended approach here is to disable ES6 module support, since ES6 modules are auto-strict. e.g.

    this.browserify.transform(babelify, {
      sourceType: 'script',
      presets: [
        reactify,
        [es2015, {modules: false}],
      ],
    })
    

    In your specific case, since your issue is breaking things in node_modules, this is because of your usage of global: true.

    I'm assuming that you specifically are passing global: true because you have node_modules that container ES6? If so, you should whitelist the things you compile by specifying an ignore regex for babelify like:

    // ...
    global: true,
    ignore: /node_modules\/(?:some_es6_module|some_other_es6_module)/,
    // ...
    

    to ignore any file with node_modules in the path, except modules named some_es6_module and some_other_es6_module. That way things like underscore will not be affected.