Fitbit / webpack-config

Helps to load, extend and merge webpack configs
https://fitbit.github.io/webpack-config
Apache License 2.0
252 stars 18 forks source link

[Help Needed] Override environment variables when multiple webpack files are derived. #91

Open aga5tya opened 7 years ago

aga5tya commented 7 years ago

I have an issue in way we reuse environment variables per config. Let me explain below

1) There is a base.webpack.js which holds my basic config

// base.webpack.js
...
context: '[appContext]',
...

2) I have an helper function, which sets the appContext based on if its server or client code, since they live in two separate packages.


// webpack.helper.js
import Config, { environment } from 'webpack-config'

/*  Basic helper that fetches respective config based on the path and configName.

     localWebpackPath -> e.g. /path/to/server/webpack,
     localContextPath -> e.g. /path/to/server/src
     localConfigName -> e.g. server.webpack.js
*/
export function fetchConfig(
    localWebpackPath,
    localContextPath,
    localConfigName = ''
) {

// based on who invoked set the environment variables.
environment.setAll({
        root: () => 'path/to/common/webpack/files',   // root has base.js, prod.js, dev.js
        appContext: localContextPath  // source of the target webpack to resolve modules
    })

const toExport = []

//based on the name and location fetch the config.
toExport.push(...load(localConfigName, localWebpackPath)

if (!toExport.length) {
        // if no config could be constructed throw error.
        console.error('Error: WEBPACK_CONFIG files not given')
        process.exit()
    }

return toExport

}

// Helper to require the webpack file and merge them to one incase they exported arrays.
function load(file, localpath = '') {
    try {
        wp = require(path.resolve(localpath, file)).default
    } catch (e) {
        console.error(`Error: ${file}.js not found or has errors:`) // eslint-disable-line no-console
        console.error(e) // eslint-disable-line no-console
        process.exit()
    }

    // If the config isn't already an array, add it to a new one, map over each
    // `webpack-config`, and create a 'regular' Webpack-compatible object
    return (Array.isArray(wp) ? wp : [wp]).map(config =>
        new Config().merge(config).toObject()
    )
}
...
  1. webpack.config.babel.js that invokes server.webpack.js
    
    // client/webpack.config.babel.j
    import { fetchConfig } from 'path/to/common/helpers/webpack.helper'
    import path from 'path'

const localWebpackPath = path.join(dirname, 'webpack') const localContextPath = path.join(dirname, 'src') let localConfigName = 'client.webpack.js'

// just feed the path, based on the environment, helper will pick the corresponding webpack file. export default fetchConfig(localWebpackPath, localContextPath, localConfigName)

// server/webpack.config.babel.j import { fetchConfig } from 'path/to/common/helpers/webpack.helper' import path from 'path'

const localWebpackPath = path.join(dirname, 'webpack') const localContextPath = path.join(dirname, 'src') let localConfigName = 'server.webpack.js'

// just feed the path, based on the environment, helper will pick the corresponding webpack file. export default fetchConfig(localWebpackPath, localContextPath, localConfigName)



Now i can invoke and get the files merged, but the context got from base.js to server/client webpack files always have the one injected when client webpack was invoked.

Not sure what i'm missing out here or if the recommended way to inject the environment/reusable variable is wrong. Please let me know if there is way to achieve this.