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

Compatible with Webpack multi builds? #55

Closed
joshhunt opened this issue Jun 23, 2016 · 5 comments
Closed

Compatible with Webpack multi builds? #55

joshhunt opened this issue Jun 23, 2016 · 5 comments

Comments

@joshhunt
Copy link

We're using Webpack in it's multi-build setup, where the config is an array of webpack configs:

module.exports = [
 { output, resolve },
 { output2, resolve2 },
]

When we configure both the configs to use Happypack, only one configuration starts and runs.

Any ideas on what's happening? Is this a tested/support configuration?

@amireh
Copy link
Owner

amireh commented Jun 23, 2016

Is this a tested/support configuration?

First time I've heard about this feature, no I haven't really tested this.

Any ideas on what's happening?

It could be that if webpack is creating only 1 compiler for those builds then HappyPack will run only on the first build, because right now it's coded to stop after the initial build unless we're in watch mode (and in this case, we're not in watch mode, but there are two "initial" builds.)

That's just a wild guess though. We can take a look at this.

@gnz00
Copy link

gnz00 commented Jul 9, 2016

I'm not too familiar with the multi-compiler mode in Webpack, but if it helps at all, here is how I'm running concurrent builds (with HappyPack) for 12 different environments:

gulp.task('compile:all', function(done) {
  const promises = configs.map(
    config => new Promise((resolve, reject) => {
      webpack(config, (err, stats) => {
        if (err) reject(err);
        else resolve(stats)
      })
    })
  )

  Promise.all(promises)
  .then(stats => done(null))
  .catch(error => done(error))
})

There are some issues with process file limits on OS X. Might be worth looking into spawning child processes or some other workaround.

@amireh
Copy link
Owner

amireh commented Aug 8, 2016

I've just tried this in a simple example and it seems to work fine for me. Make sure you're not using shared thread pools between the builds since each provides a different compiler and that won't work.

var path = require('path');
var HappyPack = require('../../');
var HAPPY_LOADER = path.resolve(__dirname, '../../loader.js');
var IDENTITY_LOADER = path.resolve(__dirname, './identity-loader.js');

module.exports = [
  {
    entry: path.resolve(__dirname, 'lib/a.js'),

    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: '[name].js'
    },

    plugins: [
      new HappyPack({
        id: 'happy-build-1',
        loaders: [ IDENTITY_LOADER ],
        threads: 2
      })
    ],

    module: {
      loaders: [
        {
          test: /\.js$/,
          loader: HAPPY_LOADER + '?id=happy-build-1',
        }
      ]
    },
  },

  {
    entry: path.resolve(__dirname, 'lib/a.js'),

    output: {
      path: path.resolve(__dirname, 'dist-2'),
      filename: '[name].js'
    },

    plugins: [
      new HappyPack({
        id: 'happy-build-2',
        loaders: [ IDENTITY_LOADER ],
        threads: 2
      })
    ],

    module: {
      loaders: [
        {
          test: /\.js$/,
          loader: HAPPY_LOADER + '?id=happy-build-2',
        }
      ]
    },
  }
];

Closing this since I can't reproduce and no context was provided.

@jmmendivil
Copy link

jmmendivil commented Aug 16, 2016

Here:

webpack.config.js

'use strict'
const path = require('path')
const webpack = require('webpack')
const commonConfig = require('./config.js')

let configs = []

const common = commonConfig()

const config1 = Object.assign(
  {},
  common,
  {
    entry: './app.coffee',
    output: {
      path: path.join(__dirname, 'dest'),
      filename: 'mobile.js' 
    },
    plugins: common.plugins.concat(
      new webpack.DefinePlugin({
        ENV: JSON.stringify('mobile')
      })
    )
  }
)

configs.push(config1)

const config2 = Object.assign(
  {},
  common,
  {
    entry: './app.coffee',
    output: {
      path: path.join(__dirname, 'dest'),
      filename: 'desktop.js' 
    },
    plugins: common.plugins.concat(
      new webpack.DefinePlugin({
        ENV: JSON.stringify('desktop')
      })
    )
  }
)
configs.push(config2)

module.exports = configs

config.js

'use strict'
const HappyPackPlugin = require('happypack')

module.exports = () => {
  return {
    module: {
      loaders: [
        { test: /\.coffee$/, loader: 'happypack/loader?id=coffeescript'  },
      ]
    },
    plugins: [
      new HappyPackPlugin({
        id: 'coffeescript',
        threads: 4,
        loaders: ['coffee-loader'],
        verbose: false
      })
    ]
  }
}

app.coffee

console.log 'ENV: ', ENV

expected: dist/mobile.js and dist/desktop.js

@amireh
Copy link
Owner

amireh commented Aug 20, 2016

Try to avoid reusing the common config instance.. just create the common config twice since it's a factory anyway, a la:

const config1 = Object.assign({}, common(), { ... });
const config2 = Object.assign({}, common(), { ... });

Then you end up with 2 actually unique HappyPlugin instances as opposed to sharing one.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants