# Bud Vue - loader not applying to files outside of the @src

**URL:** https://discourse.roots.io/t/bud-vue-loader-not-applying-to-files-outside-of-the-src/24023
**Category:** bud
**Tags:** vue, sage10
**Created:** 2022-10-07T14:51:20Z
**Posts:** 9

## Post 1 by @drbroad — 2022-10-07T14:51:20Z

When I include vue files in my admin entry, from the sage resources path (@src) - and everything works fine:

```
admin: [
          "@src/vue/index.js",
        ]
```

The contents of this index:

```
import { createApp } from 'vue'
// import the root component App from a single-file component.
import App from './App.vue'

const app = createApp(App)
app.mount('#app')
```

When I try to include vue files from a different folder, things go sideways:

```
admin: [
          "./components/assets/vue/index.js",
        ]
```

```
├─ ✘ error
│ ModuleParseError: Module parse failed: Unexpected token (1:0)
│ You may need an appropriate loader to handle this file type, currently no loaders are configured to process this
file. See https://webpack.js.org/concepts#loaders
│ > <template>
│ | <h1>Gday!</h1>
│ | </template>
```

I encountered this with sass files, so I added this in for sass/js outside the @src path:  
(Hattip to @kellymears for enlightening me about this on the github issues:)

```
app.hooks.action(`config.after`, async (app) => {
    app.build.rules.js.setInclude([
      bud => bud.path('@src'),
      app => app.path('./components'),
    ])

    app.build.rules.sass.setInclude([
      app => app.path('@src'),
      app => app.path('./components'),
    ])
  })
```

I assumed that adding in another block like so would work, but it does not:

```
app.build.rules.vue.setInclude([
      app => app.path('@src'),
      app => app.path('./components'),
    ])
```

Can anyone see what I’m doing wrong here?

---

## Post 3 by @drbroad — 2022-10-07T16:10:24Z

After looking at the documentation, i tried the following: ‘To be maximally accepting of what you want to transpile, you can use the following snippet’:

```
app.hooks.action(`config.after`, async app => {
    Object.values(app.build.rules).map(rule =>
      rule.setInclude([
        app => app.path('@src'),
        app => app.path('./components'),
      ]),
    )
  })
```

But that still didn’t work.

> **[Adding transpiler sources | bud.js](https://bud.js.org/guides/general-use/transpiler-sources/)**
>
> Module resolution in bud.js

---

## Post 4 by @kellymears — 2022-10-07T20:00:36Z

Vue is a special case because it is not compatible with webpack’s `oneOf` style rules. I don’t remember what their rationale is (if any has been provided).

Rules are parsed in three groups, in the following order:

- `build.module.rules.before` - called for every module
- `build.module.rules.oneOf` - all rules _except_ vue are applied here
- `build.module.rules.after` - called for every module (this is unused by bud internally, but the hook is provided and called in case there is user need).

`build.module.rules.oneOf` is the preferred group because it doesn’t apply modules unnecessarily. Once it finds a match it exits:

> **[Module | webpack](https://webpack.js.org/configuration/module/#ruleoneof)**
>
> 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.

> oneOf: an array of [`Rules`](https://webpack.js.org/configuration/module/#rule) from which only the first matching Rule is used when the Rule matches.

`@roots/bud-vue` has to add `vue-loader` to the list of rules which are applied to all modules, and it does so by adding it to the rules in `build.module.rules.before`.

The easiest way to make modifications to the vue rule at the moment is to hook `build.module.rules.before`:

```
bud.hooks.on(`build.module.rules.before`, (ruleset) => {
  // make modifications to ruleset array here
  return ruleset
})
```

I’m not 100% certain but I believe there is one other rule in the array. This rule ensures that browser incompatible code isn’t included in the bundle. I believe that the `vue` rule should be the first of the two rules, but you can throw in a console log and find out for yourself:

```
bud.hooks.on(`build.module.rules.before`, (ruleset) => {
  // make modifications to ruleset array here
  console.log(ruleset)
  process.exit()

  return ruleset
})
```

If it were the first array item, the final code would probably be something like this:

```
bud.hooks.on(`build.module.rules.before`, (ruleset) => {
  // make modifications to ruleset array here
  ruleset[0].include = [bud.path('./components'), ...ruleset[0].include]
  return ruleset
})
```

We need to document this and also provide a way to configure it (`bud.vue.setInclude` or something). But, nobody has asked yet! I’ll try to prioritize that in the near future now that I see the need.

---

## Post 5 by @kellymears — 2022-10-07T20:10:52Z

if for whatever reason you have problems logging the `ruleset` in the hook you might want to try out the `bud repl` cli command:

 ![image](https://discourse.roots.io/uploads/default/original/2X/b/b514143c566e58fe8a7179e5f9b4314c2622246c.jpeg)

It can be handy for exploring the shape of the generated config (`bud.build.config`).

---

## Post 6 by @drbroad — 2022-10-07T20:43:38Z

> [@kellymears](#):
>
> `@roots/bud-vue` has to add `vue-loader` to the list of rules which are applied to all modules, and it does so by adding it to the rules in `build.module.rules.before`.
> 
> The easiest way to make modifications to the vue rule at the moment is to hook `build.module.rules.before`:
> 
> ```
> bud.hooks.on(`build.module.rules.before`, (ruleset) => {
> // make modifications to ruleset array here
> return ruleset
> })
> ```

This is phenomenal, I _ **really** _ appreciate this response.

* * *

**An aside** : My theme is an extension of Sage, where pages are composed of components rather than traditional page templates. Each Component is a self-contained folder with assets, schema, function, and js for customElements. _ **Needless to say, it has some unique requirements for my bud config and beyond.** _

The components are also responsible for enqueuing its own assets when included in. a page in production (vs a complete bundle with HMR in development) , so less of a monolithic bundle, and more versioned component js/css files.

It does some fun things with ACF composer, hooking into the View Composers config to load from other directories, as well as a rudimentary CLI for creating components and importing them from a github repo of base components.

It makes for portable components across projects and the ability to scaffold a project pretty quickly from some start components

If you or anyone else would be interested in seeing it, let me know. It has sped up the way I build projects for all of our clients.

---

## Post 7 by @Davide_Prevosto — 2022-10-07T20:57:19Z

I’d like to see it. Thank you

---

## Post 8 by @kellymears — 2022-10-07T21:42:38Z

Sounds neat; I’d also be interested in seeing it. I’m wondering if there might be a way to leverage multiple compilers for this, since each is self-contained.

---

## Post 9 by @G-Hex — 2022-10-08T21:29:42Z

I’ve just started something similar, would love to see your repo, if you’re willing to share. Thanks :slight_smile:
