# Bud - Upgrading to 5.2.0 causing problems

**URL:** https://discourse.roots.io/t/bud-upgrading-to-5-2-0-causing-problems/22217
**Category:** bud
**Tags:** sage10, bud
**Created:** 2022-01-31T09:38:37Z
**Posts:** 10

## Post 1 by @erip2 — 2022-01-31T09:38:37Z

I updated the Bud version to 5.2.0 and it has caused some problems:

On the update notes, it is said that `setPublicPath` is deprecated and I removed it, but the URL of the assets is wrong now and they are not found and a lot `ChunkLoadError` errors appear.  
If I add the `setPublicPath`, then it shows: `TypeError: app.use() requires a middleware function`.

If I remove my `.use()` configuration, there are no terminal errors, but still the JS files are not found. I see on the folder structure that they are inside a `vendor` folder(?).

This is my bud config:

```
const path = require('path')
require('dotenv').config({ path: path.resolve(__dirname, '../../../.env') })

const SVGSpritemapPlugin = require('svg-spritemap-webpack-plugin')

/**
 * @typedef {import('@roots/bud').Bud} Bud
 *
 * @param {Bud} config
 */

module.exports = (app) =>
  app
    /**
     * Application entrypoints`
     *
     * Paths are relative to your resources directory
     */
    .entry({
      app: ['scripts/app.js', 'styles/app.scss']
    })

    /**
     * These files should be processed as part of the build
     * even if they are not explicitly imported in application assets.
     */
    .assets([app.path('src', 'images')])
    .assets([app.path('src', 'fonts')])

    /**
     * These files will trigger a full page reload
     * when modified.
     */
    .watch([
      'tailwind.config.js',
      'resources/views/**/*.blade.php',
      'app/View/**/*.php'
    ])

    /**
     * Target URL to be proxied by the dev server.
     *
     * This is your local dev server.
     */
    .proxy(process.env.WP_HOME)

    .use(
      new SVGSpritemapPlugin('resources/sprite/*.svg', {
        output: {
          filename: 'spritesheet.svg',
          chunk: { keep: true },
          svgo: false
        }
      })
    )
```

I have no idea what to do in this case.

---

## Post 2 by @ben — 2022-01-31T19:21:16Z

> [@erip2](#):
>
> but the URL of the assets is wrong now

How **exactly** are they wrong?

1. What is the URL of the asset now?
2. What is the expected URL of the asset?

> [@erip2](#):
>
> and a lot `ChunkLoadError` errors appear.

What are the **exact errors?**

> [@erip2](#):
>
> If I add the `setPublicPath`,

:stop_sign: you already noticed this was deprecated — don’t re-add it :sweat_smile:

> [@erip2](#):
>
> I have no idea what to do in this case.

How did you update to Bud v5.2.0 in the first place? Did you wipe your node modules directory in the process?

Have you confirmed that your problems **still exist on a clean installation?**

---

## Post 3 by @ben — 2022-01-31T19:21:19Z



---

## Post 4 by @erip2 — 2022-02-02T13:24:31Z

Ok, I believe I can say that this is not a problem related to Bud 5.2.0.

When I run `yarn build` I get these problems too even in 5.1.0.

> [@ben](#):
>
> What are the **exact errors?**

```
ChunkLoadError: Loading chunk 783 failed.
(error: https://my-site.test/e-boutique/bridal/shoes/jasmine-2/component-Header.152e59.js)
    at Object.i.f.j ((index):562:4487)
    at (index):562:2966
    at Array.reduce (<anonymous>)
    at i.e ((index):562:2931)
    at Array.map (<anonymous>)
    at o (app.e20c45.js:1:4016)
    at Object.importComponents (app.e20c45.js:1:3452)
    at Object.instanceComponent (app.e20c45.js:1:3285)
    at app.e20c45.js:1:3016
    at Array.forEach (<anonymous>) 'ChunkLoadError: Loading chunk 783 failed.\n(error: https://my-site.test/e-boutique/bridal/shoes/jasmine-2/component-Header.152e59.js)\n at Object.i.f.j (https://my-site.test/e-boutique/bridal/shoes/jasmine-2/:562:4487)\n at https://my-site.test/e-boutique/bridal/shoes/jasmine-2/:562:2966\n at Array.reduce (<anonymous>)\n at i.e (https://my-site.test/e-boutique/bridal/shoes/jasmine-2/:562:2931)\n at Array.map (<anonymous>)\n at o (https://my-site.test/app/themes/my-site/public/app.e20c45.js:1:4016)\n at Object.importComponents (https://my-site.test/app/themes/my-site/public/app.e20c45.js:1:3452)\n at Object.instanceComponent (https://my-site.test/app/themes/my-site/public/app.e20c45.js:1:3285)\n at https://my-site.test/app/themes/my-site/public/app.e20c45.js:1:3016\n at Array.forEach (<anonymous>)'
```

I guess this happens because it doesn’t find the component’s files.

I use the `regenerator-runtime` to load my components dynamically. So, I got a function like this:

```
async importComponents(componentName) {
    return await import(
      /* webpackChunkName:`component-[request]` */ /* webpackMode: "lazy" */ `./components/${componentName}`
    )
  }
```

On the DevTools → Sources, I see that for some reason there are two app JS files: One in the public folder, the other in the public/vendor folder. I don’t get this.

This is the entrypoints.json:

```
{
  "app": {
    "js": [
      "runtime.7743d4.js",
      "vendor/app.d5ad86.js",
      "app.e20c45.js"
    ],
    "css": [
      "app.d2fc14.css"
    ],
    "dependencies": []
  }
}
```

And a screenshot of the public folder:

 ![Screenshot at Feb 02 14-23-56](https://discourse.roots.io/uploads/default/original/2X/d/dd1a3f58d724d041dd1936ab4b9b200dc1f96598.png)

---

## Post 5 by @kellymears — 2022-02-02T21:31:30Z

## why we split your application into two files

> On the DevTools → Sources, I see that for some reason there are two app JS files: One in the public folder, the other in the public/vendor folder. I don’t get this.

if you don’t want to vendor your scripts you can disable `splitChunks` with:

```
bud.splitChunks(false)
```

I don’t recommend this:

- the browser caches files based on name
- you probably release versions of your sage theme more than your production dependencies change
- if you have a single `app.[hash].js` it means that every time you change your application code you are requiring users to download the entire app, including all the dependencies, again.
- instead, there is a separate `vendor/app.[hash].js` file emitted to hold your dependencies. this file will not change unless you update your dependencies.
- by separating them the user only has to download the application code and can use the dependencies from their cache.

you can read more here:

> **[SplitChunksPlugin | webpack](https://webpack.js.org/plugins/split-chunks-plugin/)**
>
> webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

## Your build failure

I can reproduce it. But, I can also fix it very easily. This is not a problem with `bud`.

> I guess this happens because it doesn’t find the component’s files.

it is. Because your public path isn’t set. Because there is no `dotenv`.

You are relying on the package `dotenv` to just be present in your `node_modules` and it isn’t. You should not just be relying on common dependencies like `dotenv` or `lodash` to be present in your environment, although it is common to do that. In general, if you `require` or `import` a module directly, you should install it or have a dependable way to resolve it otherwise.

two choices. you can, as normal, install `dotenv`:

```
npm install dotenv --dev
```

Or, you can use the one that comes bundled in `@roots/bud-support`:

```
const {env} = require('@roots/bud-support')
```

We bundle this dependency (and many others) into a single package to keep your `node_modules` lightweight. This is an (unpublicized) feature and should be considered an internal API. But, you can probably rely on it for stuff like `lodash` & `dotenv`.

`bud` should give you better error messaging (and crash) when you make errors like this. it will do so in 5.3.0.

## Dynamic imports

I don’t think you need to do anything with `regenerator-runtime`. You probably don’t need any of those legacy webpack magic comments.

[https://webpack.js.org/guides/code-splitting#dynamic-imports](https://webpack.js.org/guides/code-splitting#dynamic-imports)

If you want to use lazy mode you can remove the magic comment and enable it like so:

```
.experiments('lazyCompilation', {
      // disable lazy compilation for dynamic imports
      imports: false,

      // disable lazy compilation for entries
      entries: false,
      
      // do not lazily compile moduleB
      test: (module) => !/moduleB/.test(module.nameForCondition()),
    })
```

[https://webpack.js.org/configuration/experiments/#experimentslazycompilation](https://webpack.js.org/configuration/experiments/#experimentslazycompilation)

---

## Post 6 by @erip2 — 2022-02-03T13:47:10Z

Thank you for your detailed answer, but I’m afraid it didn’t help me :confused:

> [@kellymears](#):
>
> why we split your application into two files

Yeap, I don’t want to disable `splitChunks`

> [@kellymears](#):
>
> You are relying on the package `dotenv` to just be present in your `node_modules` and it isn’t.

But it actually is. I do have installed the `dotenv` package Nevertheless, I don’t understand your intention in this paragraph regarding the problem.

> [@kellymears](#):
>
> Dynamic imports

I have added the `.experiments('lazyCompilation)` and removed the comments, but I still get the same result. I even tried it in a new Sage 10 installation and it still occurs. The chunks loading is failing. The URL is wrong. I’m lost.

Edit: Here’s a repo: [https://github.com/erip2/module-lazyload](https://github.com/erip2/module-lazyload) with the minimal setup on a new theme.

---

## Post 7 by @kellymears — 2022-02-04T06:18:49Z

I opened a PR on your repro that fixes the issue.

> <https://github.com/erip2/module-lazyload/pull/1>
>
> nothing wrong with babel config. you don't need to do anything unless you need a… polyfill for your target browsers.
> 
> `@scripts/editor.js` is trying to import a component that doesn't exist.

You removed the boilerplate from `@scripts/components` but you didn’t remove the code that imports it.

---

## Post 8 by @erip2 — 2022-02-04T08:27:48Z

Thank you again for your answer. I appreciate you taking your time for this.

This is not a solution, unfortunately :sweat:

I don’t think `editor.js` has anything to do with my problem. My problem is that the files inside the `components` folder don’t get loaded. I’m not using and I have no intention to use `editor.js`.

The whole logic of my structure lies in `app.js`.

---

## Post 9 by @kellymears — 2022-02-04T11:31:44Z

@erip2, it seems there are two separate issues in the app code you provided.

The first was that it wouldn’t compile because of a bad import in `editor.js`. The bad import was the cause of the compilation failure and with my fix (removing the import) it compiles again in CI and locally.

I looked back into it when you said you were still having problems and ultimately could reproduce your browser error.

The issue in the application code is that you are dynamically loading modules and so you need to dynamically set the public path.

I merged an addition to my earlier PR that includes an application level fix for this. The code works in the browser now.

> <https://github.com/kellymears/module-lazyload/pull/1>
>
> I did this with the bud api for accessing local .env values. You don't have to d…o that. You could just pass a string. You could also hardcode it into the app, although that's less portable.
> 
> References:
> 
> - bud.define docs: https://budjs.netlify.app/docs/bud.define
> - webpack docs: https://webpack.js.org/guides/public-path/

Ultimately, you need to do two things:

1. This is kind of optional but recommended. Define the publicPath in your `bud.config.js` file. Make sure to escape the value. I did it with `bud.env` but you can use `env` or just add it as a string. Whatever works.

```
/**
      * Define the public path for dynamically imported assets.
      *
      * I am defining it an .env file and accessing it with `bud.env`.
      */
     .define({
       ASSET_PATH: JSON.stringify(app.env.get('ASSET_PATH')),
     })
```

1. Set ` __webpack_public_path__ `:

```
// eslint-disable-next-line no-undef
__webpack_public_path__ = ASSET_PATH;
```

I did this in a separate module which was imported to the top of `app.js` intentionally since it works for literally all setups (newer esmodule imports will break if you just add it at the top of the entrypoint).

see bud documentation on `bud.define`:

> **[bud.define | bud.js](https://budjs.netlify.app/docs/bud.define/)**
>
> Replace variables in your application code and templates at compile time.

and the documentation from webpack on `publicPath`:

> **[Public Path | webpack](https://webpack.js.org/guides/public-path/)**
>
> webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

---

## Post 10 by @erip2 — 2022-02-04T12:00:35Z

Thanks so much. Can confirm that this works on dev & build.

Also, updated to 5.2.0 on my current project and it’s going fine :smiley:
