Yung Silva
Yung Silva

Reputation: 1500

Prevent file from generating new build - Webpack

I have an application with nuxt.js / Vue.

I created a Webpack Plugin so that with each file changed, generate an index.js in a certain directory.

The problem is that when index.js is generated, Webpack recognizes this as a new change and build again, so it stays in that infinite loop ...

To detect changes, I'm using webpack hooks

compiler.hooks.beforeCompile.tapAsync('MyPlugin', (params, callback) => {
  // script to generate an index.js in a given directory
});

how can I prevent index.js from triggering a new build?

Updating the question for better understanding

I'm working on an application made with vue.js | nuxt.js and this component structure

├── components
│   ├── quarks
│   │   └── ...
│   ├── bosons
│   │   └── GridLayout.vue
│   │   └── ...
│   ├── atoms
│   │   └── ButtonStyle.vue
│   │   └── InputStyle.vue
│   │   └── ...
│   ├── molecules
│   │   └── ...
│   ├── organisms
│   │   └── ...
│   ├── templates
│   │   └── ...
└─────

I need to do named and grouped imports, like this:

import { ButtonStyle, InputStyle } from '@/components/atoms/'

but for this to work out I would need to have an index.js inside each folder exporting component by component, example

├── components
│   ├── atoms
│   │   └── ButtonStyle.vue
│   │   └── InputStyle.vue
│   │   └── index.js
└─────

and in index.js

export { default as ButtonStyled } from './ButtonStyled.vue'
export { default as InputStyle } from './InputStyle.vue'

But doing this work manually can be a very tiresome task. Every time you create, delete, rename a component, you would have to update the index.js of your respective folder.

so I started to develop a solution

in nuxt.config.js

import NamedExports from './plugins/NamedExports.js'

export default {
  // ... other config here ...
  build: {
    plugins: [
      new NamedExports()
    ],
  }
}

in plugins/NamedExports.js

const pluginName = 'NamedExports'
const { exec } = require('child_process')

class NamedExports {
  apply(compiler) {
    compiler.hooks.beforeCompile.tap(pluginName, (params, callback) => {
      exec('sh plugins/shell.sh', (err, stdout, stderr) => {
        console.log(stdout)
        console.log(stderr)
      })
    })
  }
}

export default NamedExports

plugins/shell.sh

parameters=$(ls components)
for item in ${parameters[*]}
do
    ls components/$item/ | grep -v index.js | sed 's#^\([^.]*\).*$#export { default as \1 } from "./&"#' > components/$item/index.js
done

but whenever the plugin creates an index.js, a new build is triggered

Upvotes: 3

Views: 566

Answers (2)

Yung Silva
Yung Silva

Reputation: 1500

I use a hook that runs only once and I use chokidar to listen for changes in the components directory

compiler.hooks.entryOption.tap('MyPlugin', (context, entry) => {
  // generates index.js
  // Watch a directory with chokidar 
});

I turned this into a library, maybe it helps other people

Weback Plugin - named-exports

Upvotes: 0

iHazCode
iHazCode

Reputation: 771

Have you added the new file/directory to WebPacks exclude list? If not, the watchOptions.ignore property might be just what your looking for: https://webpack.js.org/configuration/watch/

Hope this helps

Upvotes: 2

Related Questions