Skip to content

Commit

Permalink
feat: support passing config to generateWebpackConfig for merging
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Sep 4, 2023
1 parent 54d3bcc commit df0f406
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 21 deletions.
31 changes: 12 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,25 +466,23 @@ First, you don't _need_ to use Shakapacker's webpack configuration. However, the
1. Your output files go to the right directory
2. Your output includes a manifest, via package [`webpack-assets-manifest`](https://github.com/webdeveric/webpack-assets-manifest) that maps output names (your 'packs') to the fingerprinted versions, including bundle-splitting dependencies. That's the main secret sauce of Shakapacker!

The most practical webpack configuration is to take the default from Shakapacker and then use [webpack-merge](https://github.com/survivejs/webpack-merge) to merge your customizations with the default. For example, suppose you want to add some `resolve.extensions`:
The easiest way to customize your webpack config beyond whats available in `config/shakapacker.yml` is to pass your desired customizations to `generateWebpackConfig` which will return a new config resulting from merging those customizations into the default config using [webpack-merge](https://github.com/survivejs/webpack-merge) to merge your customizations with the default.

For example, suppose you want to add some `resolve.extensions`:

```js
// use the new NPM package name, `shakapacker`.
// merge is webpack-merge from https://github.com/survivejs/webpack-merge
const { generateWebpackConfig, merge } = require('shakapacker')

const baseWebpackConfig = generateWebpackConfig()
const { generateWebpackConfig } = require('shakapacker')

const options = {
resolve: {
extensions: ['.css', '.ts', '.tsx']
}
}

// Copy the object using merge b/c the baseClientWebpackConfig is a mutable global
// If you want to use this object for client and server rendering configurations,
// having a new object is essential.
module.exports = merge({}, baseWebpackConfig, options)
// This results in a new object copied from the mutable global
module.exports = generateWebpackConfig(options)
```

This example is based on [an example project](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/webpack.config.js)
Expand Down Expand Up @@ -513,12 +511,11 @@ Then `require` this file in your `config/webpack/webpack.config.js`:
```js
// config/webpack/webpack.config.js
// use the new NPM package name, `shakapacker`.
const { generateWebpackConfig, merge } = require('shakapacker')
const { generateWebpackConfig } = require('shakapacker')

const webpackConfig = generateWebpackConfig()
const customConfig = require('./custom')

module.exports = merge(webpackConfig, customConfig)
module.exports = generateWebpackConfig(customConfig)
```

If you need access to configs within Shakapacker's configuration, you can import them like so:
Expand Down Expand Up @@ -616,12 +613,10 @@ Then modify the webpack config to use it as a plugin:

```js
// config/webpack/webpack.config.js
const { generateWebpackConfig, merge } = require("shakapacker");

const webpackConfig = generateWebpackConfig()
const { generateWebpackConfig } = require("shakapacker");
const ForkTSCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");

module.exports = merge(webpackConfig, {
module.exports = generateWebpackConfig({
plugins: [new ForkTSCheckerWebpackPlugin()],
});
```
Expand All @@ -638,17 +633,15 @@ Optionally, add the `CSS` extension to webpack config for easy resolution.

```js
// config/webpack/webpack.config.js
const { generateWebpackConfig, merge } = require('shakapacker')

const webpackConfig = generateWebpackConfig()
const { generateWebpackConfig } = require('shakapacker')

const customConfig = {
resolve: {
extensions: ['.css']
}
}

module.exports = merge(webpackConfig, customConfig)
module.exports = generateWebpackConfig(customConfig)
```

To enable `PostCSS`, `Sass` or `Less` support, add `CSS` support first and
Expand Down
15 changes: 15 additions & 0 deletions package/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,19 @@ describe('index', () => {
expect(webpackConfig2).not.toHaveProperty('newKey')
expect(webpackConfig2.output.path).not.toEqual('new value')
})

test('webpackConfig merges extra config', () => {
const { generateWebpackConfig } = require('../index')

const webpackConfig = generateWebpackConfig({
newKey: 'new value',
output: {
path: 'new path'
}
})

expect(webpackConfig).toHaveProperty('newKey', 'new value')
expect(webpackConfig).toHaveProperty('output.path', 'new path')
expect(webpackConfig).toHaveProperty('output.publicPath', '/packs/')
})
})
4 changes: 2 additions & 2 deletions package/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ const globalMutableWebpackConfig = () => {
return environmentConfig
}

const generateWebpackConfig = () => {
const generateWebpackConfig = (extraConfig = {}) => {
const environmentConfig = globalMutableWebpackConfig()
const immutable = webpackMerge.merge({}, environmentConfig)
const immutable = webpackMerge.merge({}, environmentConfig, extraConfig)
return immutable
}

Expand Down

0 comments on commit df0f406

Please sign in to comment.