Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importing uuid in rollup ESM library creates an import statement for "crypto" in output file

Edit: Added plugins configuration for more clarity


I am using uuid package in a rollup project. At first I was getting a warning for external dependency crypto. So I added external and output.globals in my rollup configuration:

export default [{
  input: '/path/to/input.js',
  external: ['crypto'],
  output: {
    file: '/path/to/output.esm.js',
    format: 'esm',
    ...
    globals: {
      crypto: 'crypto'
    }
  },
  plugins: [
    resolve({
      customResolveOptions: {
        moduleDirectory: 'node_modules'
      },
      preferBuiltins: true
    }),
    commonjs({
      namedExports: {
        uuid: ['v4']
      }
    })
  ]
}];

The warning is gone, but now I have an import statement in my output file:

output.esm.js

import crypto from 'crypto';
...

My question is will this work if I include output.esm.js in browser?

<script type="module" src="/path/to/output.esm.js"></script>
like image 265
Sachin Singh Avatar asked Jan 27 '20 19:01

Sachin Singh


1 Answers

At first I was getting a warning for external dependency crypto

This is because Rollup doesn't know whether you want to use node's built-in crypto or an external package. @rollup/plugin-node-resolve's preferBuiltins is used to choose between one of these alternatives.

So I added external and output.globals in my rollup configuration

These options, together with preferBuiltins: true tell Rollup to use node's built-in crypto without bundling it (hence the import statement still present in the output file).

However if your target environment is the browser, you should use the browser alternative provided by uuid that relies on the Web Crypto API instead of node's crypto. To do this, the following Rollup config should be enough:

// rollup.config.js

export default [{
  input: ...,
  output: {
    file: ...,
    format: 'esm',
  },
  plugins: [
    resolve({
        browser: true, // This instructs the plugin to use
                       // the "browser" property in package.json
    }),
    commonjs(),
  ],
}];

Just out of curiosity:

My question is will this work if I include output.esm.js in browser?

<script type="module" src="/path/to/output.esm.js"></script>

No, it won't; mainly because browsers don't understand bare module specifiers (import crypto from 'crypto' instead of './path/to/crypto.js'). Also, as per your Rollup configuration crypto is treated as a nodejs built-in, which is not available in the browser unless bundled :)

like image 142
Umbo Avatar answered Nov 07 '22 14:11

Umbo