Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use babel's `useBuiltIns: 'usage'` option on the vendors bundle?

Tags:

Since I need to support also IE11, I need to transpile also node_modules.

This is the babel config I use on the node_modules:

presets: [   ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }], ], 

I use the useBuiltIns options because it was giving an error Symbol is not defined, the polyfill was needed.

However this configuration breaks at compile time, supposedly because it injects some imports in the code, here is the error:

TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

Basically it's not liking the module.exports. So how do I use useBuiltIns in the vendors bundle?

For now I solved by always requiring the babel polyfill in the index.html, however this is not ideal.

like image 909
Pontiacks Avatar asked Sep 19 '18 13:09

Pontiacks


People also ask

How do you use babel?

Simply add a "scripts" field to your package. json and put the babel command inside there as build . This will run Babel the same way as before and the output will be present in lib directory, only now we are using a local copy. Alternatively, you can reference the babel cli inside of node_modules .

What is babel preset ENV used for?

@babel/preset-env is a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s). This both makes your life easier and JavaScript bundles smaller!


1 Answers

Babel by default assumes that files it processes are ES modules (using import and export). If you are running Babel on things in node_modules (which are likely CommonJS modules), you'll need to either tell Babel to process all node_modules as scripts, or tell Babel to guess the type based on the presence of import and export. Guessing is easiest, so you can add

sourceType: "unambiguous" 

and also tell Babel not to run the usage transform on core-js itself with

  ignore: [     /\/core-js/,   ], 

because otherwise the usage transform will actually be inserting references to core-js into itself causing dependency cycles.

So in your top-level Babel configuration, you'd do e.g.

{   ignore: [     /\/core-js/,   ],   sourceType: "unambiguous",   presets: [     ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }],   ], } 

If you wanted to be extra specific about it, you could also do

{   ignore: [     /\/core-js/,   ],   presets: [     ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }],   ],   overrides: [{     test: "./node_modules",     sourceType: "unambiguous",   }], } 

to only set the flag for files inside node_modules, but there is likely not much to gain by doing that.

As for why this fixes that error, the issue is that, if Babel thinks something is an ES module, it will insert import statements. If you insert import statements into a file that also uses CommonJS things like module.exports, it means the file would now be using both module systems in the same file, which is a big issue and causes the errors you are seeing.

like image 173
loganfsmyth Avatar answered Oct 10 '22 05:10

loganfsmyth