Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

refactor: bundling external fallbacks with webpack #637

Closed

Conversation

giulianok
Copy link
Member

@giulianok giulianok commented Apr 9, 2024

Provide a general summary of your changes in the Title above.

Bundling external fallbacks with webpack instead of esbuild

Description

Describe your changes in detail

External Fallbacks are currently being bundled with esbuild. There are certain externals that use libs such as crypto that require a fallback to a polyfill (e.g. crypto-browserify) in order to properly work on the browser. esbuild supports it via aliases but only for the code that's being transpiled and not for its dependencies. webpack solves by via the fallback flag which tries to resolve the dependency and defaults to a specified one in case it cannot, even for dependencies.

We could have created an esbuild plugin to implement the fallback feature from webpack, but we decided to instead use webpack to bundle it to be consistent with production and because we are unsure when esbuild will be used for production bundles.

This project only accepts pull requests related to open issues.

If suggesting a new feature or change, please discuss it in an issue first.

Motivation

Why is this change required? What issue does it resolve?

Test Conditions

Describe in detail how the changes are tested.

Include details of your testing environment, and the tests you ran to.

How does your change affect the rest of the code.

Types of changes

Check boxes that apply:

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation (adding or updating documentation)
  • Dependency update
  • Security update

Checklist

Check boxes that apply:

  • My code follows the code style of this project.
  • My change requires a change to the documentation and I have updated the documentation accordingly.
  • These changes should be applied to a maintenance branch.
  • I have added the Apache 2.0 license header to any new files created.

@giulianok giulianok marked this pull request as ready for review April 10, 2024 18:49
@giulianok giulianok requested review from a team as code owners April 10, 2024 18:49
bishnubista
bishnubista previously approved these changes Apr 11, 2024
.eslintignore Outdated Show resolved Hide resolved
jest.cjs.config.js Outdated Show resolved Hide resolved
@@ -15,9 +15,11 @@
import chalk from 'chalk';
import fs from 'node:fs';
import path from 'node:path';
import snakeCase from 'lodash.snakecase';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just implement this here instead of adding a dependency (esp lodash)

function toSnakeCase(str) {
  return str
    .replace(/[\s-]+/g, '_')    // Replace spaces and dashes with _
    .replace(/([A-Z])/g, '_$1') // Prefix uppercase letters with _
    .toLowerCase()              // Convert the whole string to lowercase
    .replace(/^_/, '');         // Remove leading underscore if present
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can't we just go with lodash? we used it before in the dev bundler and does not affect the output/bundle

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have all of lodash we don't need lodash.snakecase specifically as well right?

resolve: {
mainFields: MAIN_FIELDS,
modules: [packageRoot, 'node_modules'],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
extensions: ['.js', '.jsx', '.ts', '.tsx'],
extensions: ['.js', '.jsx', '.ts', '.tsx', '.cjs'],

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think this is needed since it's strange to have client side code using commonjs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@giulianok I had to fix this last week with the latest redux release, so it is needed
#633

module: {
rules: [
{
test: /[jt]sx?$/,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
test: /[jt]sx?$/,
test: /\.c?[jt]sx?$/,

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think this is needed since it's strange to have client side code using commonjs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Matthew Mallimo <matthew.c.mallimo@aexp.com>
fs.writeFileSync(configPath, JSON.stringify({
...config,
...newData,
}, null, 2));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we save some bytes by not pretty printing the json?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think it will make a huge diff but why not

dogpatch626
dogpatch626 previously approved these changes Apr 16, 2024
util: resolve('util'),
vm: resolve('vm-browserify'),
zlib: resolve('browserify-zlib'),
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are pollyfilling this ^ all of these modules in fallback: elsewhere, does it make sense to do it again here within the externalFallbacks?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/americanexpress/one-app-cli/blob/main/packages/one-app-bundler/webpack/module/webpack.client.js These are pollyfills that were provided by webpack 4 and no longer are so we manually pollyfill them here. probably should not provide it again? maybe my understanding of what actually is happening in the externalFallbacks version is off

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if I follow.

we aren't actually pollyfilling, we provide a fallback, which only uses the pollyfil if the actual lib cannot be used / isn't available. We do it for the modules and we need to do it for external fallbacks since they are separate bundles

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm okay I think im mainly just trying to figure out if this work is being duplicated. Because in module/webpack.client.js we pollyfill, and here we fallback the pollyfill it seems so if the pollyfill is found it should not duplicate such work

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@giulianok I think Danny's point is that this code is repeated. Maybe we can extract this out

@10xLaCroixDrinker 10xLaCroixDrinker deleted the refactor/external-fallbacks-bundle-with-webpack branch May 15, 2024 12:41
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants