babel-plugin-optimize-helpers

0.0.1-dev.1 • Public • Published

babel-plugin-optimize-helpers

A Babel plugin that replaces known Babel modular runtime helpers with require() calls to a single runtime library.

Why?

Many packages in NPM are vended as already transpiled code that either already contain these helper functions or require() them from different runtime libraries (e.g. @babel/{runtime|runtime-corejs2}/helpers/[esm/]). This plugin will transform all of these references to require() from @babel/runtime-corejs2/helpers/esm/ (the one that the default Next.js configuration for @babel/plugin-transform-runtime uses). That way, there should only be a one, canonical copy of these helper functions which can be included in your "common" bundle.

Setup with webpack

In your webpack config, add a module rule that loads your script with a babel-loader with this plugin.

module.exports = {
  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.(js|mjs|jsx)$/,
        exclude: /[\\/]node_modules[\\/]@babel[\\/]runtime-corejs2[\\/]/,
        use: {
          loader: 'babel-loader',
          options: {
            babelrc: false,
            plugins: [
              require.resolve('@babel/plugin-syntax-dynamic-import'),
              require.resolve('@babel/plugin-syntax-class-properties'),
              require.resolve('@babel/plugin-syntax-jsx'),
              // Add other syntax plugins here.

              require('./babel-plugin-optimize-helpers')
            ]
          }
        }
      }
    ]
  }
};

Important Exclude @babel/runtime-corejs2/ from this rule - this would rewrite references to helpers in this library to require() itself and result in circular references.

Next.js

If you're using Next.js, you can use the provided next-plugin:

const withOptimizeHelpers = require('babel-plugin-optimize-helpers/next-plugin');

module.exports = withOptimizeHelpers({
  /* ... */
});

Alternatively, modify the webpack config in next.config.json (e.g. if you need other Babel syntax plugins):

module.exports = {
  webpack(config, { dev, isServer }) {
    const optimize = !dev && !isServer;

    // Only optimize browser code.
    if (optimize && config.optimization.splitChunks) {

      // Include `@babel/runtime-corejs2/` in the commons bundle.
      config.optimization.splitChunks.cacheGroups['corejs'] = {
        name: 'commons',
        chunks: 'all',
        test: /[\\/]node_modules[\\/]@babel[\\/]runtime-corejs2[\\/]/
      };

      // Load script with the plugin.
      config.module.rules.push({
        test: /\.(js|mjs|jsx)$/,
        exclude: /[\\/]node_modules[\\/]@babel[\\/]runtime-corejs2[\\/]/,
        use: {
          loader: 'babel-loader',
          options: {
            babelrc: false,
            plugins: [
              require.resolve('@babel/plugin-syntax-dynamic-import'),
              require.resolve('@babel/plugin-syntax-class-properties'),
              require.resolve('@babel/plugin-syntax-jsx'),
              // Add other syntax plugins here.

              require('./babel-plugin-optimize-helpers')
            ]
          }
        }
      });
    }

    return config;
  }
};

Do I need this plugin?

In an ideal world, libraries will publish a copy of un-transpiled source code and leave transpiling to the app developer (who can decide what the transpile target should be and what helpers to bundle). Unfortunately this is not the case today. This plugin should be considered as short-term gap solution.

Versions

Current Tags

Version History

  • Version
    Downloads (Last 7 Days)
    • Published
  • 0.0.1-dev.1
    0

Package Sidebar

Install

npm i babel-plugin-optimize-helpers

Weekly Downloads

0

Version

0.0.1-dev.1

License

none

Unpacked Size

10.7 kB

Total Files

4

Last publish

Collaborators

  • keanulee